diff --git a/Libraries/LibRegex/RegexOptimizer.cpp b/Libraries/LibRegex/RegexOptimizer.cpp index b043cef903a..9ef997ec5c7 100644 --- a/Libraries/LibRegex/RegexOptimizer.cpp +++ b/Libraries/LibRegex/RegexOptimizer.cpp @@ -898,6 +898,7 @@ void Regex::rewrite_with_useless_jumps_removed() auto target_old = is_repeat ? i.old_ip - old_off : i.old_ip + i.size + old_off; if (!new_ip.contains(target_old)) { dbgln("Target {} not found in new_ip (in {})", target_old, i.old_ip); + dbgln("Pattern: {}", pattern_value); RegexDebug dbg; dbg.print_bytecode(*this); } @@ -1585,7 +1586,7 @@ void Optimizer::append_alternation(ByteCode& target, Span alternatives } ssize_t target_value = *target_ip - patch_location - patch_size; if (should_negate) - target_value = -target_value + 2; // from -1 to +1. + target_value = -target_value - opcode.size(); target[patch_location] = static_cast(target_value); } else { patch_locations.append({ QualifiedIP { alternative_index, intended_jump_ip }, patch_location }); diff --git a/Tests/LibRegex/Regex.cpp b/Tests/LibRegex/Regex.cpp index d0cbc73790a..438864ec09e 100644 --- a/Tests/LibRegex/Regex.cpp +++ b/Tests/LibRegex/Regex.cpp @@ -1285,3 +1285,12 @@ TEST_CASE(mismatching_brackets) EXPECT_EQ(re.parser_result.error, regex::Error::MismatchingBracket); } } + +TEST_CASE(optimizer_repeat_offset) +{ + { + // Miscalculating the repeat offset in table reconstruction of alternatives would lead to crash here + // make sure that doesn't happen :) + Regex re("\\/?\\??#?([\\/?#]|[\\uD800-\\uDBFF]|%[c-f][0-9a-f](%[89ab][0-9a-f]){0,2}(%[89ab]?)?|%[0-9a-f]?)$"sv); + } +}