Skip to content

Commit 0fce370

Browse files
committed
Fix a regression in parsing of unicode surogate pairs
Fix: #912 In the case of surogate pairs we consume two backslashes, so `json_next_backslash` need to ensure it's not sending us back in the stream.
1 parent 4bdb2d1 commit 0fce370

File tree

3 files changed

+12
-1
lines changed

3 files changed

+12
-1
lines changed

CHANGES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
### Unreleased
44

5+
* Fix a regression in parsing of unicode surogate pairs (`\uXX\uXX`) that could cause an invalid string to be returned.
6+
57
### 2025-12-03 (2.17.0)
68

79
* Improve `JSON.load` and `JSON.unsafe_load` to allow passing options as second argument.

ext/json/ext/parser/parser.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -651,7 +651,9 @@ static inline const char *json_next_backslash(const char *pe, const char *string
651651
positions->size--;
652652
const char *next_position = positions->positions[0];
653653
positions->positions++;
654-
return next_position;
654+
if (next_position >= pe) {
655+
return next_position;
656+
}
655657
}
656658

657659
if (positions->has_more) {

test/json/json_parser_test.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,13 @@ def test_invalid_unicode_escape
325325
assert_raise(JSON::ParserError) { parse('"\u111___"') }
326326
end
327327

328+
def test_unicode_followed_by_newline
329+
# Ref: https://github.com/ruby/json/issues/912
330+
assert_equal "🌌\n".bytes, JSON.parse('"\ud83c\udf0c\n"').bytes
331+
assert_equal "🌌\n", JSON.parse('"\ud83c\udf0c\n"')
332+
assert_predicate JSON.parse('"\ud83c\udf0c\n"'), :valid_encoding?
333+
end
334+
328335
def test_invalid_surogates
329336
assert_raise(JSON::ParserError) { parse('"\\uD800"') }
330337
assert_raise(JSON::ParserError) { parse('"\\uD800_________________"') }

0 commit comments

Comments
 (0)