Skip to content

Commit 3faf2a3

Browse files
byroothsbt
authored andcommitted
[ruby/json] parser: Reject invalid surogate pairs more consistently.
ruby/json@5855f4f603
1 parent a4c2777 commit 3faf2a3

File tree

2 files changed

+12
-1
lines changed

2 files changed

+12
-1
lines changed

ext/json/parser/parser.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -713,11 +713,16 @@ static VALUE json_string_unescape(JSON_ParserState *state, const char *string, c
713713
}
714714
if (pe[0] == '\\' && pe[1] == 'u') {
715715
uint32_t sur = unescape_unicode(state, (unsigned char *) pe + 2);
716+
717+
if ((sur & 0xFC00) != 0xDC00) {
718+
raise_parse_error_at("invalid surrogate pair at %s", state, p);
719+
}
720+
716721
ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
717722
| (sur & 0x3FF));
718723
pe += 5;
719724
} else {
720-
unescape = (char *) "?";
725+
raise_parse_error_at("incomplete surrogate pair at %s", state, p);
721726
break;
722727
}
723728
}

test/json/json_parser_test.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,12 @@ def test_invalid_unicode_escape
319319
assert_raise(JSON::ParserError) { parse('"\u111___"') }
320320
end
321321

322+
def test_invalid_surogates
323+
assert_raise(JSON::ParserError) { parse('"\\uD800"') }
324+
assert_raise(JSON::ParserError) { parse('"\\uD800_________________"') }
325+
assert_raise(JSON::ParserError) { parse('"\\uD800\\u0041"') }
326+
end
327+
322328
def test_parse_big_integers
323329
json1 = JSON(orig = (1 << 31) - 1)
324330
assert_equal orig, parse(json1)

0 commit comments

Comments
 (0)