diff --git a/Libraries/LibRegex/RegexParser.cpp b/Libraries/LibRegex/RegexParser.cpp index 9a0b2e5f641..5a0fc608646 100644 --- a/Libraries/LibRegex/RegexParser.cpp +++ b/Libraries/LibRegex/RegexParser.cpp @@ -1627,9 +1627,14 @@ bool ECMA262Parser::parse_atom_escape(ByteCode& stack, size_t& match_length_mini set_error(Error::InvalidNameForCaptureGroup); return false; } - match_length_minimum += maybe_capture_group->minimum_length; + auto maybe_length = m_parser_state.capture_group_minimum_lengths.get(maybe_capture_group.value()); + if (!maybe_length.has_value()) { + set_error(Error::InvalidNameForCaptureGroup); + return false; + } + match_length_minimum += maybe_length.value(); - stack.insert_bytecode_compare_values({ { CharacterCompareType::Reference, (ByteCodeValueType)maybe_capture_group->group_index } }); + stack.insert_bytecode_compare_values({ { CharacterCompareType::Reference, (ByteCodeValueType)maybe_capture_group.value() } }); return true; } @@ -2674,6 +2679,8 @@ bool ECMA262Parser::parse_capture_group(ByteCode& stack, size_t& match_length_mi return false; } + m_parser_state.named_capture_groups.set(name, group_index); + ByteCode capture_group_bytecode; size_t length = 0; enter_capture_group_scope(); @@ -2693,7 +2700,6 @@ bool ECMA262Parser::parse_capture_group(ByteCode& stack, size_t& match_length_mi match_length_minimum += length; m_parser_state.capture_group_minimum_lengths.set(group_index, length); - m_parser_state.named_capture_groups.set(name, { group_index, length }); return true; } diff --git a/Libraries/LibRegex/RegexParser.h b/Libraries/LibRegex/RegexParser.h index f7e5073d0ca..d5634e89246 100644 --- a/Libraries/LibRegex/RegexParser.h +++ b/Libraries/LibRegex/RegexParser.h @@ -98,11 +98,6 @@ protected: size_t tell() const { return m_parser_state.current_token.position(); } - struct NamedCaptureGroup { - size_t group_index { 0 }; - size_t minimum_length { 0 }; - }; - struct ParserState { Lexer& lexer; Token current_token; @@ -114,8 +109,8 @@ protected: size_t match_length_minimum { 0 }; size_t repetition_mark_count { 0 }; AllOptions regex_options; - HashMap capture_group_minimum_lengths; - HashMap named_capture_groups; + HashMap capture_group_minimum_lengths; + HashMap named_capture_groups; explicit ParserState(Lexer& lexer) : lexer(lexer) diff --git a/Tests/LibRegex/Regex.cpp b/Tests/LibRegex/Regex.cpp index e975ee96c55..0f11865fc64 100644 --- a/Tests/LibRegex/Regex.cpp +++ b/Tests/LibRegex/Regex.cpp @@ -597,6 +597,7 @@ TEST_CASE(ECMA262_parse) { "a{9007199254740992,9007199254740992}"sv, regex::Error::InvalidBraceContent }, { "(?a)(?b)"sv, regex::Error::DuplicateNamedCapture }, { "(?a)(?b)(?c)"sv, regex::Error::DuplicateNamedCapture }, + { "(?(?a))"sv, regex::Error::DuplicateNamedCapture }, { "(?<1a>a)"sv, regex::Error::InvalidNameForCaptureGroup }, { "(?<\\a>a)"sv, regex::Error::InvalidNameForCaptureGroup }, { "(?<\ta>a)"sv, regex::Error::InvalidNameForCaptureGroup },