diff options
author | Emmanuele Bassi <ebassi@gmail.com> | 2020-11-30 23:25:59 +0000 |
---|---|---|
committer | Emmanuele Bassi <ebassi@gmail.com> | 2020-11-30 23:25:59 +0000 |
commit | 1bd60e1a07f4c978ed16ddb6d1876b55be87e200 (patch) | |
tree | 8b44a3ad4e7058b3447d04cf475ca17373f6e734 | |
parent | 733ee90734d8a9a4e331d73696e6e5b7676a8315 (diff) | |
parent | cea6cb888065a89493d37a2d9b6805c00d592057 (diff) | |
download | json-glib-1bd60e1a07f4c978ed16ddb6d1876b55be87e200.tar.gz |
Merge branch 'fix-26' into 'master'
scanner: Fix crash on malformed surrogate pairs
Closes #26
See merge request GNOME/json-glib!34
-rw-r--r-- | json-glib/json-scanner.c | 28 | ||||
-rw-r--r-- | json-glib/tests/invalid.c | 3 |
2 files changed, 27 insertions, 4 deletions
diff --git a/json-glib/json-scanner.c b/json-glib/json-scanner.c index 59dd29c..e9a58be 100644 --- a/json-glib/json-scanner.c +++ b/json-glib/json-scanner.c @@ -40,6 +40,10 @@ #include <io.h> /* For _read() */ #endif +enum { + JSON_ERR_MALFORMED_SURROGATE_PAIR = G_TOKEN_LAST + 1, +}; + struct _JsonScannerConfig { /* Character sets @@ -681,7 +685,11 @@ json_scanner_unexp_token (JsonScanner *scanner, case G_ERR_DIGIT_RADIX: g_snprintf (token_string, token_string_len, "scanner: digit is beyond radix"); break; - + + case JSON_ERR_MALFORMED_SURROGATE_PAIR: + g_snprintf (token_string, token_string_len, "scanner: malformed surrogate pair"); + break; + case G_ERR_UNKNOWN: default: g_snprintf (token_string, token_string_len, "scanner: unknown error"); @@ -1066,7 +1074,7 @@ json_scanner_get_token_ll (JsonScanner *scanner, gstring = g_string_new (NULL); while ((ch = json_scanner_get_char (scanner, line_p, position_p)) != 0) { - if (ch == '"') + if (ch == '"' || token == G_TOKEN_ERROR) { in_string_dq = FALSE; break; @@ -1130,8 +1138,20 @@ json_scanner_get_token_ll (JsonScanner *scanner, units[0] = ucs; units[1] = json_scanner_get_unichar (scanner, line_p, position_p); - ucs = decode_utf16_surrogate_pair (units); - g_assert (g_unichar_validate (ucs)); + if (0xdc00 <= units[1] && units[1] <= 0xdfff && + 0xd800 <= units[0] && units[0] <= 0xdbff) + { + ucs = decode_utf16_surrogate_pair (units); + g_assert (g_unichar_validate (ucs)); + } + else + { + token = G_TOKEN_ERROR; + value.v_error = JSON_ERR_MALFORMED_SURROGATE_PAIR; + gstring = NULL; + break; + } + } } diff --git a/json-glib/tests/invalid.c b/json-glib/tests/invalid.c index 0ab2d30..cb5f818 100644 --- a/json-glib/tests/invalid.c +++ b/json-glib/tests/invalid.c @@ -212,6 +212,9 @@ static const struct /* values */ { "values-1", "[ -false ]", test_invalid_value }, + { "values-2", "[\"\\uD800\\uD800\"]", test_invalid_value }, + { "values-3", "[\"\\uDB00\\uD800\"]", test_invalid_value }, + { "values-4", "[\"\\uDB00\"]", test_invalid_value }, /* assignment */ { "assignment-1", "var foo", test_invalid_assignment }, |