diff options
author | Ali Mohammad Pur <ali.mpfard@gmail.com> | 2022-11-09 21:34:36 +0330 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-11-09 21:28:54 +0100 |
commit | 00326a63ed6b07acfe437ccae1253b593463c75b (patch) | |
tree | 4d7ad16dc335155a29b599a10a65a676332bdad6 | |
parent | 0ea399d8d691d4446f632f54a22942277edcb5e1 (diff) | |
download | serenity-00326a63ed6b07acfe437ccae1253b593463c75b.zip |
LibRegex: Don't treat ForkReplace* as new forks
-rw-r--r-- | Tests/LibRegex/Regex.cpp | 6 | ||||
-rw-r--r-- | Userland/Libraries/LibRegex/RegexByteCode.cpp | 13 |
2 files changed, 15 insertions, 4 deletions
diff --git a/Tests/LibRegex/Regex.cpp b/Tests/LibRegex/Regex.cpp index abcfa93513..15e972a24d 100644 --- a/Tests/LibRegex/Regex.cpp +++ b/Tests/LibRegex/Regex.cpp @@ -1067,6 +1067,12 @@ TEST_CASE(negative_lookahead) EXPECT_EQ(re.match(":1"sv).success, false); EXPECT_EQ(re.match(":foobar"sv).success, true); } + { + // Correctly count forks with nested groups and optimised loops + Regex<ECMA262> re("^((?:[^\\n]|\\n(?! *\\n))+)(?:\\n *)+\\n"); + EXPECT_EQ(re.match("foo\n\n"sv).success, true); + EXPECT_EQ(re.match("foo\n"sv).success, false); + } } TEST_CASE(single_match_flag) diff --git a/Userland/Libraries/LibRegex/RegexByteCode.cpp b/Userland/Libraries/LibRegex/RegexByteCode.cpp index e0c0ca4a27..e94ec356da 100644 --- a/Userland/Libraries/LibRegex/RegexByteCode.cpp +++ b/Userland/Libraries/LibRegex/RegexByteCode.cpp @@ -267,7 +267,6 @@ ALWAYS_INLINE ExecutionResult OpCode_ForkReplaceStay::execute(MatchInput const& { state.fork_at_position = state.instruction_position + size() + offset(); input.fork_to_replace = state.instruction_position; - state.forks_since_last_save++; return ExecutionResult::Fork_PrioLow; } @@ -384,8 +383,10 @@ ALWAYS_INLINE ExecutionResult OpCode_SaveRightCaptureGroup::execute(MatchInput c { auto& match = state.capture_group_matches.at(input.match_index).at(id()); auto start_position = match.left_column; - if (state.string_position < start_position) + if (state.string_position < start_position) { + dbgln("Right capture group {} is before left capture group {}!", state.string_position, start_position); return ExecutionResult::Failed_ExecuteLowPrioForks; + } auto length = state.string_position - start_position; @@ -1071,11 +1072,15 @@ ALWAYS_INLINE ExecutionResult OpCode_JumpNonEmpty::execute(MatchInput const& inp state.fork_at_position = state.instruction_position + size() + offset(); - if (form == OpCodeId::ForkJump) + if (form == OpCodeId::ForkJump) { + state.forks_since_last_save++; return ExecutionResult::Fork_PrioHigh; + } - if (form == OpCodeId::ForkStay) + if (form == OpCodeId::ForkStay) { + state.forks_since_last_save++; return ExecutionResult::Fork_PrioLow; + } if (form == OpCodeId::ForkReplaceStay) { input.fork_to_replace = state.instruction_position; |