summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean Boussier <jean.boussier@gmail.com>2025-09-18 10:45:44 +0200
committerHiroshi SHIBATA <hsbt@ruby-lang.org>2025-09-19 19:30:10 +0900
commit3faf2a31fb49ed56bd550ff4c10d538b9882c099 (patch)
tree3c8d877bcb03ff7b7d199ba577ffdd3279c5ad63
parenta4c277733b10ff1ad484689c1a256032c39cea87 (diff)
[ruby/json] parser: Reject invalid surogate pairs more consistently.
https://github.com/ruby/json/commit/5855f4f603
-rw-r--r--ext/json/parser/parser.c7
-rw-r--r--test/json/json_parser_test.rb6
2 files changed, 12 insertions, 1 deletions
diff --git a/ext/json/parser/parser.c b/ext/json/parser/parser.c
index e34f1999d5..297031dcf1 100644
--- a/ext/json/parser/parser.c
+++ b/ext/json/parser/parser.c
@@ -713,11 +713,16 @@ static VALUE json_string_unescape(JSON_ParserState *state, const char *string, c
}
if (pe[0] == '\\' && pe[1] == 'u') {
uint32_t sur = unescape_unicode(state, (unsigned char *) pe + 2);
+
+ if ((sur & 0xFC00) != 0xDC00) {
+ raise_parse_error_at("invalid surrogate pair at %s", state, p);
+ }
+
ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
| (sur & 0x3FF));
pe += 5;
} else {
- unescape = (char *) "?";
+ raise_parse_error_at("incomplete surrogate pair at %s", state, p);
break;
}
}
diff --git a/test/json/json_parser_test.rb b/test/json/json_parser_test.rb
index a9b0624f6b..9d387cb808 100644
--- a/test/json/json_parser_test.rb
+++ b/test/json/json_parser_test.rb
@@ -319,6 +319,12 @@ class JSONParserTest < Test::Unit::TestCase
assert_raise(JSON::ParserError) { parse('"\u111___"') }
end
+ def test_invalid_surogates
+ assert_raise(JSON::ParserError) { parse('"\\uD800"') }
+ assert_raise(JSON::ParserError) { parse('"\\uD800_________________"') }
+ assert_raise(JSON::ParserError) { parse('"\\uD800\\u0041"') }
+ end
+
def test_parse_big_integers
json1 = JSON(orig = (1 << 31) - 1)
assert_equal orig, parse(json1)