diff --git a/Tests/LibRegex/Regex.cpp b/Tests/LibRegex/Regex.cpp index 452d97fed5b..366b414819d 100644 --- a/Tests/LibRegex/Regex.cpp +++ b/Tests/LibRegex/Regex.cpp @@ -1089,6 +1089,18 @@ TEST_CASE(single_match_flag) } } +TEST_CASE(empty_string_wildcard_match) +{ + { + // Ensure that the wildcard ".*" matches the empty string exactly once + Regex re(".*"sv, ECMAScriptFlags::Global); + auto result = re.match(""sv); + EXPECT_EQ(result.success, true); + EXPECT_EQ(result.matches.size(), 1u); + EXPECT_EQ(result.matches.first().view.to_deprecated_string(), ""sv); + } +} + TEST_CASE(inversion_state_in_char_class) { { diff --git a/Userland/Libraries/LibRegex/RegexMatcher.cpp b/Userland/Libraries/LibRegex/RegexMatcher.cpp index 71caf5cecdf..bf6571680a0 100644 --- a/Userland/Libraries/LibRegex/RegexMatcher.cpp +++ b/Userland/Libraries/LibRegex/RegexMatcher.cpp @@ -222,6 +222,11 @@ RegexResult Matcher::match(Vector const& views, Optiona // Nothing was *actually* matched, so append an empty match. append_match(input, state, view_index); ++match_count; + + // This prevents a regex pattern like ".*" from matching the empty string + // multiple times, once in this block and once in the following for loop. + if (view_index == 0 && view_length == 0) + ++view_index; } } }