[PATCH] lib: fwts_json: fix output so that it is machine parsable (LP: #1902249)
Colin King
colin.king at canonical.com
Fri Oct 30 17:49:13 UTC 2020
From: Colin Ian King <colin.king at canonical.com>
Currenty the json output is incorrectly places a trailing comma at
the end of collections. Fix this by re-working the output to
not emit commas where they are not required. Also escape the
output strings so they can be read by json parsers.
Fixes: 1a663dd3b37 ("Replace json-c library with minimal replacement")
Signed-off-by: Colin Ian King <colin.king at canonical.com>
---
src/lib/src/fwts_json.c | 104 ++++++++++++++++++++++++++++++++++------
1 file changed, 89 insertions(+), 15 deletions(-)
diff --git a/src/lib/src/fwts_json.c b/src/lib/src/fwts_json.c
index 8f2c396d..130e5ccb 100644
--- a/src/lib/src/fwts_json.c
+++ b/src/lib/src/fwts_json.c
@@ -755,6 +755,44 @@ static char *str_indent(char *str, int indent)
return str_append(str, buf);
}
+static bool char_escape(const int ch)
+{
+ switch (ch) {
+ case '"':
+ case '\b':
+ case '\f':
+ case '\n':
+ case '\r':
+ case '\t':
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
+static char *str_escape(char *oldstr)
+{
+ char *oldptr, *newstr, *newptr;
+ ssize_t n;
+
+ for (n = 0, oldptr = oldstr; *oldptr; oldptr++, n++)
+ if (char_escape(*oldptr))
+ n++;
+
+ newstr = malloc(n + 1);
+ if (!newstr)
+ return NULL;
+
+ for (oldptr = oldstr, newptr = newstr; *oldptr; oldptr++, newptr++) {
+ if (char_escape(*oldptr))
+ *(newptr++) = '\\';
+ *newptr = *oldptr;
+ }
+ *newptr = '\0';
+ return newstr;
+}
+
/*
* json_object_to_json_string_indent()
* turn a simplified fwts json object into a C string, returns
@@ -766,6 +804,7 @@ static char *json_object_to_json_string_indent(json_object *obj, int indent)
int i;
json_object **obj_ptr;
char *str = NULL;
+ char *tmp;
char buf[64];
if (!obj)
@@ -775,9 +814,6 @@ static char *json_object_to_json_string_indent(json_object *obj, int indent)
str = str_indent(str, indent);
if (!str)
return NULL;
- str = str_append(str, "{\n");
- if (!str)
- return NULL;
}
if (obj->key) {
@@ -797,15 +833,33 @@ static char *json_object_to_json_string_indent(json_object *obj, int indent)
switch (obj->type) {
case type_array:
- str = str_append(str, "[\n");
+ str = str_append(str, "\n");
+ if (!str)
+ return NULL;
+ str = str_indent(str, indent);
+ if (!str)
+ return NULL;
+ str = str_append(str, "[");
if (!str)
return NULL;
obj_ptr = (json_object **)obj->u.ptr;
if (obj_ptr) {
for (i = 0; i < obj->length; i++) {
- char *obj_str = json_object_to_json_string_indent(obj_ptr[i], indent + 1);
-
+ char *obj_str;
+
+ if (i) {
+ str = str_append(str, "\n");
+ if (!str)
+ return NULL;
+ str = str_indent(str, indent + 1);
+ if (!str)
+ return NULL;
+ str = str_append(str, ",");
+ if (!str)
+ return NULL;
+ }
+ obj_str = json_object_to_json_string_indent(obj_ptr[i], indent + 1);
if (!obj_str) {
free(str);
return NULL;
@@ -821,17 +875,30 @@ static char *json_object_to_json_string_indent(json_object *obj, int indent)
str = str_indent(str, indent);
if (!str)
return NULL;
- str = str_append(str, "]\n");
+ str = str_append(str, "]");
if (!str)
return NULL;
break;
case type_object:
+ str = str_append(str, "\n");
+ if (!str)
+ return NULL;
+ str = str_indent(str, indent);
+ if (!str)
+ return NULL;
+ str = str_append(str, "{");
+ if (!str)
+ return NULL;
obj_ptr = (json_object **)obj->u.ptr;
if (obj_ptr) {
for (i = 0; i < obj->length; i++) {
- char *obj_str = json_object_to_json_string_indent(obj_ptr[i], indent + 1);
+ char *obj_str;
+ str = str_append(str, (i == 0) ? "\n" : ",\n");
+ if (!str)
+ return NULL;
+ obj_str = json_object_to_json_string_indent(obj_ptr[i], indent + 1);
if (!obj_str) {
free(str);
return NULL;
@@ -841,6 +908,13 @@ static char *json_object_to_json_string_indent(json_object *obj, int indent)
return NULL;
}
}
+ str = str_append(str, "\n");
+ if (!str)
+ return NULL;
+ str = str_indent(str, indent);
+ if (!str)
+ return NULL;
+ str = str_append(str, "}");
if (!str)
return NULL;
break;
@@ -849,22 +923,25 @@ static char *json_object_to_json_string_indent(json_object *obj, int indent)
str = str_append(str, "\"");
if (!str)
return NULL;
- str = str_append(str, (char *)obj->u.ptr);
+ tmp = str_escape((char *)obj->u.ptr);
+ if (!tmp)
+ return NULL;
+ str = str_append(str, tmp);
if (!str)
return NULL;
- str = str_append(str, "\",\n");
+ str = str_append(str, "\"");
if (!str)
return NULL;
break;
case type_null:
- str = str_append(str, "(null)\n");
+ str = str_append(str, "(null)");
if (!str)
return NULL;
break;
case type_int:
- snprintf(buf, sizeof(buf), "%d,\n", obj->u.intval);
+ snprintf(buf, sizeof(buf), "%d", obj->u.intval);
str = str_append(str, buf);
if (!str)
return NULL;
@@ -877,9 +954,6 @@ static char *json_object_to_json_string_indent(json_object *obj, int indent)
str = str_indent(str, indent);
if (!str)
return NULL;
- str = str_append(str, "},\n");
- if (!str)
- return NULL;
}
return str;
}
--
2.27.0
More information about the fwts-devel
mailing list