diff --git a/Libraries/LibRegex/RegexByteCode.cpp b/Libraries/LibRegex/RegexByteCode.cpp index 5afe9d8ca1b..7ff0b4a6dfb 100644 --- a/Libraries/LibRegex/RegexByteCode.cpp +++ b/Libraries/LibRegex/RegexByteCode.cpp @@ -1085,7 +1085,7 @@ ALWAYS_INLINE ExecutionResult OpCode_Checkpoint::execute(MatchInput const&, Matc ALWAYS_INLINE ExecutionResult OpCode_JumpNonEmpty::execute(MatchInput const& input, MatchState& state) const { u64 current_position = state.string_position; - auto checkpoint_position = state.checkpoints[checkpoint()]; + auto checkpoint_position = state.checkpoints.get(checkpoint()).value_or(0); if (checkpoint_position != 0 && checkpoint_position != current_position + 1) { auto form = this->form(); diff --git a/Tests/LibRegex/Regex.cpp b/Tests/LibRegex/Regex.cpp index 0f11865fc64..d32b5e820f1 100644 --- a/Tests/LibRegex/Regex.cpp +++ b/Tests/LibRegex/Regex.cpp @@ -1087,6 +1087,8 @@ TEST_CASE(optimizer_alternation) Tuple { "[0-9]{2}|[0-9]"sv, "92"sv, 2u }, // Don't ForkJump to the next instruction, rerunning it would produce the same result. see ladybird#2398. Tuple { "(xxxxxxxxxxxxxxxxxxxxxxx|xxxxxxxxxxxxxxxxxxxxxxx)?b"sv, "xxxxxxxxxxxxxxxxxxxxxxx"sv, 0u }, + // Don't take the jump in JumpNonEmpty with nonexistent checkpoints (also don't crash). + Tuple { "(?!\\d*|[g-ta-r]+|[h-l]|\\S|\\S|\\S){,9}|\\S{7,8}|\\d|(?)|[c-mj-tb-o]*|\\s"sv, "rjvogg7pm|li4nmct mjb2|pk7s8e0"sv, 0u }, }; for (auto& test : tests) {