Implement JsonFree(), make string handling UTF-8 aware.

This commit is contained in:
Jordan Bancino 2022-07-27 17:27:34 -04:00
parent ee1909e534
commit c143136097
2 changed files with 79 additions and 3 deletions

View file

@ -243,15 +243,35 @@ JsonValueNull(void)
void void
JsonValueFree(JsonValue * value) JsonValueFree(JsonValue * value)
{ {
size_t i;
Array *arr;
if (!value) if (!value)
{ {
return; return;
} }
switch (value->type)
{
case JSON_OBJECT:
JsonFree(value->as.object);
break;
case JSON_ARRAY:
arr = value->as.array;
for (i = 0; i < ArraySize(arr); i++)
{
JsonValueFree((JsonValue *) ArrayGet(arr, i));
}
ArrayFree(arr);
break;
default:
break;
}
free(value); free(value);
} }
static void void
JsonEncodeString(const char *str, FILE * out) JsonEncodeString(const char *str, FILE * out)
{ {
size_t i; size_t i;
@ -286,7 +306,25 @@ JsonEncodeString(const char *str, FILE * out)
fputs("\\r", out); fputs("\\r", out);
break; break;
default: /* Assume UTF-8 input */ default: /* Assume UTF-8 input */
/*
* RFC 4627: "All Unicode characters may be placed
* within the quotation marks except for the characters
* that must be escaped: quotation mark, reverse solidus,
* and the control characters (U+0000 through U+001F)."
*
* This technically covers the above cases for backspace,
* tab, newline, feed, and carriage return characters,
* but we can save bytes if we encode those as their
* more human-readable representation.
*/
if (c <= 0x001F)
{
printf("\\u%04x", c);
}
else
{
fputc(c, out); fputc(c, out);
}
break; break;
} }
@ -367,6 +405,24 @@ JsonDecodeString(FILE * in)
return NULL; return NULL;
} }
if (utf8 == 0)
{
/*
* We read in a \u0000, null. There is no
* circumstance in which putting a null
* character into our buffer will end well.
*
* There's also really no legitimate use
* for the null character in our JSON anyway;
* it's likely an attempted exploit.
*
* So lets just strip it out. Don't even
* include it in the string. There should be
* no harm in ignoring it.
*/
continue;
}
/* Encode the 4-byte UTF-8 buffer into a series /* Encode the 4-byte UTF-8 buffer into a series
* of 1-byte characters */ * of 1-byte characters */
utf8Ptr = UtilUtf8Encode(utf8); utf8Ptr = UtilUtf8Encode(utf8);
@ -423,7 +479,7 @@ JsonDecodeString(FILE * in)
return NULL; return NULL;
} }
static void void
JsonEncodeValue(JsonValue * value, FILE * out) JsonEncodeValue(JsonValue * value, FILE * out)
{ {
size_t i; size_t i;
@ -519,3 +575,17 @@ JsonEncode(HashMap * object, FILE * out)
return 1; return 1;
} }
void
JsonFree(HashMap * object)
{
char *key;
JsonValue *value;
while (HashMapIterate(object, &key, (void **) &value))
{
JsonValueFree(value);
}
HashMapFree(object);
}

View file

@ -56,6 +56,12 @@ extern void
extern void extern void
JsonFree(HashMap * object); JsonFree(HashMap * object);
extern void
JsonEncodeString(const char *str, FILE * out);
extern void
JsonEncodeValue(JsonValue * value, FILE * out);
extern int extern int
JsonEncode(HashMap * object, FILE * out); JsonEncode(HashMap * object, FILE * out);