diff --git a/spa/include/spa/utils/json.h b/spa/include/spa/utils/json.h index 5a5601e05..6976235bd 100644 --- a/spa/include/spa/utils/json.h +++ b/spa/include/spa/utils/json.h @@ -324,7 +324,18 @@ static inline int spa_json_parse_string(const char *val, int len, char *result) *result++ = '\t'; else if (*p == 'f') *result++ = '\f'; - else + else if (*p == 'u') { + char *end; + uint16_t v = strtol(p+1, &end, 16); + if (p+1 == end) { + *result++ = *p; + } else { + p = end-1; + if (v > 0xff) + *result++ = (v >> 8) & 0xff; + *result++ = v & 0xff; + } + } else *result++ = *p; } else if (*p == '\"') { break; @@ -348,6 +359,7 @@ static inline int spa_json_get_string(struct spa_json *iter, char *res, int maxl static inline int spa_json_encode_string(char *str, int size, const char *val) { int len = 0; + static const char hex[] = { "0123456789abcdef" }; #define __PUT(c) { if (len < size) *str++ = c; len++; } __PUT('"'); while (*val) { @@ -371,7 +383,13 @@ static inline int spa_json_encode_string(char *str, int size, const char *val) __PUT('\\'); __PUT('"'); break; default: - __PUT(*val); + if (*val > 0 && *val < 0x20) { + __PUT('\\'); __PUT('u'); + __PUT('0'); __PUT('0'); + __PUT(hex[((*val)>>4)&0xf]); __PUT(hex[(*val)&0xf]); + } else { + __PUT(*val); + } break; } val++; diff --git a/spa/tests/test-json.c b/spa/tests/test-json.c index c2bb5f815..47f343cdf 100644 --- a/spa/tests/test-json.c +++ b/spa/tests/test-json.c @@ -154,6 +154,7 @@ static void test_encode(void) char dst[1024]; char dst4[4]; char dst6[6]; + char result[1024]; spa_assert(spa_json_encode_string(dst, sizeof(dst), "test") == 6); spa_assert(strcmp(dst, "\"test\"") == 0); spa_assert(spa_json_encode_string(dst4, sizeof(dst4), "test") == 6); @@ -162,6 +163,10 @@ static void test_encode(void) spa_assert(strncmp(dst6, "\"test\"", 6) == 0); spa_assert(spa_json_encode_string(dst, sizeof(dst), "test\"\n\r \t\b\f\'") == 20); spa_assert(strcmp(dst, "\"test\\\"\\n\\r \\t\\b\\f'\"") == 0); + spa_assert(spa_json_encode_string(dst, sizeof(dst), "\x04\x05\x1f\x20\x01\x7f\x90") == 29); + spa_assert(strcmp(dst, "\"\\u0004\\u0005\\u001f \\u0001\x7f\x90\"") == 0); + spa_assert(spa_json_parse_string(dst, sizeof(dst), result) == 1); + spa_assert(strcmp(result, "\x04\x05\x1f\x20\x01\x7f\x90") == 0); } int main(int argc, char *argv[])