|
Packit Service |
b23acc |
// SPDX-License-Identifier: LGPL-2.1+
|
|
Packit Service |
b23acc |
/*
|
|
Packit Service |
b23acc |
* Copyright (C) 2019 Red Hat, Inc.
|
|
Packit Service |
b23acc |
*/
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
#include "nm-default.h"
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
#include "nm-json-aux.h"
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/*****************************************************************************/
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
_gstr_append_string_len (GString *gstr,
|
|
Packit Service |
b23acc |
const char *str,
|
|
Packit Service |
b23acc |
gsize len)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
g_string_append_c (gstr, '\"');
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
while (len > 0) {
|
|
Packit Service |
b23acc |
gsize n;
|
|
Packit Service |
b23acc |
const char *end;
|
|
Packit Service |
b23acc |
gboolean valid;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_assert (len > 0);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
valid = g_utf8_validate (str, len, &end;;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_assert ( end
|
|
Packit Service |
b23acc |
&& end >= str
|
|
Packit Service |
b23acc |
&& end <= &str[len]);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (end > str) {
|
|
Packit Service |
b23acc |
const char *s;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
for (s = str; s < end; s++) {
|
|
Packit Service |
b23acc |
nm_assert (s[0] != '\0');
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (s[0] < 0x20) {
|
|
Packit Service |
b23acc |
const char *text;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
switch (s[0]) {
|
|
Packit Service |
b23acc |
case '\\': text = "\\\\"; break;
|
|
Packit Service |
b23acc |
case '\"': text = "\\\""; break;
|
|
Packit Service |
b23acc |
case '\b': text = "\\b"; break;
|
|
Packit Service |
b23acc |
case '\f': text = "\\f"; break;
|
|
Packit Service |
b23acc |
case '\n': text = "\\n"; break;
|
|
Packit Service |
b23acc |
case '\r': text = "\\r"; break;
|
|
Packit Service |
b23acc |
case '\t': text = "\\t"; break;
|
|
Packit Service |
b23acc |
default:
|
|
Packit Service |
b23acc |
g_string_append_printf (gstr, "\\u%04X", (guint) s[0]);
|
|
Packit Service |
b23acc |
continue;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
g_string_append (gstr, text);
|
|
Packit Service |
b23acc |
continue;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (NM_IN_SET (s[0], '\\', '\"'))
|
|
Packit Service |
b23acc |
g_string_append_c (gstr, '\\');
|
|
Packit Service |
b23acc |
g_string_append_c (gstr, s[0]);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
} else
|
|
Packit Service |
b23acc |
nm_assert (!valid);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (valid) {
|
|
Packit Service |
b23acc |
nm_assert (end == &str[len]);
|
|
Packit Service |
b23acc |
break;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_assert (end < &str[len]);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (end[0] == '\0') {
|
|
Packit Service |
b23acc |
/* there is a NUL byte in the string. Technically this is valid UTF-8, so we
|
|
Packit Service |
b23acc |
* encode it there. However, this will likely result in a truncated string when
|
|
Packit Service |
b23acc |
* parsing. */
|
|
Packit Service |
b23acc |
g_string_append (gstr, "\\u0000");
|
|
Packit Service |
b23acc |
} else {
|
|
Packit Service |
b23acc |
/* the character is not valid UTF-8. There is nothing we can do about it, because
|
|
Packit Service |
b23acc |
* JSON can only contain UTF-8 and even the escape sequences can only escape Unicode
|
|
Packit Service |
b23acc |
* codepoints (but not binary).
|
|
Packit Service |
b23acc |
*
|
|
Packit Service |
b23acc |
* The argument is not a a string (in any known encoding), hence we cannot represent
|
|
Packit Service |
b23acc |
* it as a JSON string (which are unicode strings).
|
|
Packit Service |
b23acc |
*
|
|
Packit Service |
b23acc |
* Print an underscore instead of the invalid char :) */
|
|
Packit Service |
b23acc |
g_string_append_c (gstr, '_');
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
n = str - end;
|
|
Packit Service |
b23acc |
nm_assert (n < len);
|
|
Packit Service |
b23acc |
n++;
|
|
Packit Service |
b23acc |
str += n;
|
|
Packit Service |
b23acc |
len -= n;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_string_append_c (gstr, '\"');
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
void
|
|
Packit Service |
b23acc |
nm_json_aux_gstr_append_string_len (GString *gstr,
|
|
Packit Service |
b23acc |
const char *str,
|
|
Packit Service |
b23acc |
gsize n)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
g_return_if_fail (gstr);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
_gstr_append_string_len (gstr, str, n);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
void
|
|
Packit Service |
b23acc |
nm_json_aux_gstr_append_string (GString *gstr,
|
|
Packit Service |
b23acc |
const char *str)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
g_return_if_fail (gstr);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (!str)
|
|
Packit Service |
b23acc |
g_string_append (gstr, "null");
|
|
Packit Service |
b23acc |
else
|
|
Packit Service |
b23acc |
_gstr_append_string_len (gstr, str, strlen (str));
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
void
|
|
Packit Service |
b23acc |
nm_json_aux_gstr_append_obj_name (GString *gstr,
|
|
Packit Service |
b23acc |
const char *key,
|
|
Packit Service |
b23acc |
char start_container)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
g_return_if_fail (gstr);
|
|
Packit Service |
b23acc |
g_return_if_fail (key);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_json_aux_gstr_append_string (gstr, key);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (start_container != '\0') {
|
|
Packit Service |
b23acc |
nm_assert (NM_IN_SET (start_container, '[', '{'));
|
|
Packit Service |
b23acc |
g_string_append_printf (gstr, ": %c ", start_container);
|
|
Packit Service |
b23acc |
} else
|
|
Packit Service |
b23acc |
g_string_append (gstr, ": ");
|
|
Packit Service |
b23acc |
}
|