From eba466b8e766bd69992b8cf2dcd300538713fda5 Mon Sep 17 00:00:00 2001 From: Ali Mohammad Pur Date: Thu, 13 Apr 2023 21:12:59 +0330 Subject: [PATCH] LibRegex: Avoid calling GenericLexer::consume() past EOF The consume(size_t) overload consumes "at most" as many bytes as requested, but consume() consumes exactly one byte. This commit makes sure to avoid consuming past EOF. Fixes #18324. Fixes #18325. --- Tests/LibRegex/Regex.cpp | 2 ++ Userland/Libraries/LibRegex/RegexParser.cpp | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Tests/LibRegex/Regex.cpp b/Tests/LibRegex/Regex.cpp index 0e47191a18..44792ad4cc 100644 --- a/Tests/LibRegex/Regex.cpp +++ b/Tests/LibRegex/Regex.cpp @@ -606,6 +606,8 @@ TEST_CASE(ECMA262_parse) { "((?=lg)?[vl]k\\-?\\d{3}) bui| 3\\.[-\\w; ]{10}lg?-([06cv9]{3,4})"sv, regex::Error::NoError, ECMAScriptFlags::BrowserExtended }, // #12373, quantifiable assertions. { parse_test_case_long_disjunction_chain.view() }, // A whole lot of disjunctions, should not overflow the stack. { "(\"|')(?:(?!\\2)[^\\\\\\r\\n]|\\\\.)*\\2"sv, regex::Error::NoError, ECMAScriptFlags::BrowserExtended }, // LegacyOctalEscapeSequence should not consume too many chars (and should not crash) + // #18324, Capture group counter skipped past EOF. + { "\\1[\\"sv, regex::Error::InvalidNumber }, }; for (auto& test : tests) { diff --git a/Userland/Libraries/LibRegex/RegexParser.cpp b/Userland/Libraries/LibRegex/RegexParser.cpp index 136b7a97f2..24d378e8a9 100644 --- a/Userland/Libraries/LibRegex/RegexParser.cpp +++ b/Userland/Libraries/LibRegex/RegexParser.cpp @@ -2695,17 +2695,22 @@ size_t ECMA262Parser::ensure_total_number_of_capturing_parenthesis() while (!lexer.is_eof()) { switch (lexer.peek()) { case '\\': - lexer.consume(2); + lexer.consume(min(lexer.tell_remaining(), 2)); continue; case '[': while (!lexer.is_eof()) { if (lexer.consume_specific('\\')) { + if (lexer.is_eof()) + break; lexer.consume(); continue; } if (lexer.consume_specific(']')) { break; } + + if (lexer.is_eof()) + break; lexer.consume(); } break;