mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
json: improve unicode parsing
Make sure don't overread the strings. Don't use sscanf but use a custom hex read function. Fixes #2340
This commit is contained in:
parent
f641e4ecb3
commit
92e2b7dd0d
2 changed files with 31 additions and 9 deletions
|
|
@ -331,6 +331,25 @@ static inline bool spa_json_is_string(const char *val, int len)
|
||||||
return len > 1 && *val == '"';
|
return len > 1 && *val == '"';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int spa_json_parse_hex(const char *p, int num, uint32_t *res)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
*res = 0;
|
||||||
|
for (i = 0; i < num; i++) {
|
||||||
|
char v = p[i];
|
||||||
|
if (v >= '0' && v <= '9')
|
||||||
|
v = v - '0';
|
||||||
|
else if (v >= 'a' && v <= 'f')
|
||||||
|
v = v - 'a' + 10;
|
||||||
|
else if (v >= 'A' && v <= 'F')
|
||||||
|
v = v - 'A' + 10;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
*res = (*res << 4) | v;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int spa_json_parse_stringn(const char *val, int len, char *result, int maxlen)
|
static inline int spa_json_parse_stringn(const char *val, int len, char *result, int maxlen)
|
||||||
{
|
{
|
||||||
const char *p;
|
const char *p;
|
||||||
|
|
@ -355,23 +374,23 @@ static inline int spa_json_parse_stringn(const char *val, int len, char *result,
|
||||||
else if (*p == 'f')
|
else if (*p == 'f')
|
||||||
*result++ = '\f';
|
*result++ = '\f';
|
||||||
else if (*p == 'u') {
|
else if (*p == 'u') {
|
||||||
uint8_t v[2], prefix[] = { 0, 0xc0, 0xe0, 0xf0 };
|
uint8_t prefix[] = { 0, 0xc0, 0xe0, 0xf0 };
|
||||||
uint32_t idx, n, cp, enc[] = { 0x80, 0x800, 0x10000 };
|
uint32_t idx, n, v, cp, enc[] = { 0x80, 0x800, 0x10000 };
|
||||||
if (p + 5 > val + len ||
|
if (val + len - p < 5 ||
|
||||||
sscanf(p+1, "%02hhx%02hhx", &v[0], &v[1]) != 2) {
|
spa_json_parse_hex(p+1, 4, &cp) < 0) {
|
||||||
*result++ = *p;
|
*result++ = *p;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
cp = v[0] << 8 | v[1];
|
|
||||||
p += 4;
|
p += 4;
|
||||||
|
|
||||||
if (cp >= 0xd800 && cp <= 0xdbff) {
|
if (cp >= 0xd800 && cp <= 0xdbff) {
|
||||||
if (p + 7 > val + len ||
|
if (val + len - p < 7 ||
|
||||||
sscanf(p+1, "\\u%02hhx%02hhx", &v[0], &v[1]) != 2 ||
|
p[1] != '\\' || p[2] != 'u' ||
|
||||||
v[0] <= 0xdb || v[0] >= 0xe0)
|
spa_json_parse_hex(p+3, 4, &v) < 0 ||
|
||||||
|
v < 0xdc00 || v > 0xdfff)
|
||||||
continue;
|
continue;
|
||||||
p += 6;
|
p += 6;
|
||||||
cp = 0x010000 | ((cp & 0x3ff) << 10) | (((v[0] << 8 | v[1])) & 0x3ff);
|
cp = 0x010000 | ((cp & 0x3ff) << 10) | (v & 0x3ff);
|
||||||
} else if (cp >= 0xdc00 && cp <= 0xdfff)
|
} else if (cp >= 0xdc00 && cp <= 0xdfff)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -179,6 +179,9 @@ PWTEST(json_encode)
|
||||||
strcpy(dst, "\"\\u03b2a\"");
|
strcpy(dst, "\"\\u03b2a\"");
|
||||||
pwtest_int_eq(spa_json_parse_stringn(dst, sizeof(dst), result, sizeof(result)), 1);
|
pwtest_int_eq(spa_json_parse_stringn(dst, sizeof(dst), result, sizeof(result)), 1);
|
||||||
pwtest_str_eq(result, "\316\262a");
|
pwtest_str_eq(result, "\316\262a");
|
||||||
|
strcpy(dst, "\"\\u 03b2a \"");
|
||||||
|
pwtest_int_eq(spa_json_parse_stringn(dst, sizeof(dst), result, sizeof(result)), 1);
|
||||||
|
pwtest_str_eq(result, "u 03b2a ");
|
||||||
|
|
||||||
return PWTEST_PASS;
|
return PWTEST_PASS;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue