From 4c6eeae071dae8163a238c7b2bf704a199e57335 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Wed, 25 Mar 2026 11:45:17 +0100 Subject: [PATCH] Fix handling of unescaped control characters preceeded by a backslash --- CHANGES.md | 2 ++ ext/json/ext/parser/parser.c | 4 +++- test/json/json_parser_test.rb | 9 +++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 3c23aa8f..4bb85ca0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,8 @@ ### Unreleased +* Fix handling of unescaped control characters preceeded by a backslash. + ### 2026-03-18 (2.19.2) * Fix a format string injection vulnerability in `JSON.parse(doc, allow_duplicate_key: false)`. `CVE-2026-33210`. diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index b05f3f52..38f3a48c 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -770,7 +770,9 @@ NOINLINE(static) VALUE json_string_unescape(JSON_ParserState *state, JSON_Parser } raise_parse_error_at("invalid ASCII control character in string: %s", state, pe - 1); } - } else if (config->allow_invalid_escape) { + } + + if (config->allow_invalid_escape) { APPEND_CHAR(*pe); } else { raise_parse_error_at("invalid escape character in string: %s", state, pe - 1); diff --git a/test/json/json_parser_test.rb b/test/json/json_parser_test.rb index 2d2f065e..af08d183 100644 --- a/test/json/json_parser_test.rb +++ b/test/json/json_parser_test.rb @@ -183,6 +183,15 @@ def test_parse_allowed_control_chars_in_string end end + def test_parsse_control_char_and_backslash + backslash_and_control_char = "\\\t" + assert_raise JSON::ParserError do + JSON.parse(%("#{'a' * 30}#{backslash_and_control_char}"), allow_control_characters: true, allow_invalid_escape: false) + end + + JSON.parse(%("#{'a' * 30}#{backslash_and_control_char}"), allow_control_characters: true, allow_invalid_escape: true) + end + def test_parse_invalid_escape assert_raise JSON::ParserError do parse(%("fo\\o"))