Browse Source

LibRegex: Make sure there are as many group matches as actual matches

Fixes #6131.
AnotherTest 4 năm trước cách đây
mục cha
commit
ade97d4094

+ 18 - 0
Userland/Libraries/LibJS/Tests/builtins/RegExp/RegExp.prototype.exec.js

@@ -101,3 +101,21 @@ test("optionally seen capture group", () => {
     expect(res[1]).toBe("mozilla");
     expect(res[2]).toBeUndefined();
 });
+
+// #6131
+test("capture group with two '?' qualifiers", () => {
+    let res = /()??/.exec("");
+
+    expect(res.length).toBe(2);
+    expect(res[0]).toBe("");
+    expect(res[1]).toBeUndefined();
+});
+
+test("named capture group with two '?' qualifiers", () => {
+    let res = /(?<foo>)??/.exec("");
+
+    expect(res.length).toBe(2);
+    expect(res[0]).toBe("");
+    expect(res[1]).toBeUndefined();
+    expect(res.groups.foo).toBeUndefined();
+});

+ 6 - 0
Userland/Libraries/LibRegex/RegexMatcher.cpp

@@ -254,6 +254,9 @@ RegexResult Matcher<Parser>::match(const Vector<RegexStringView> views, Optional
     MatchOutput output_copy;
     if (match_count) {
         output_copy.capture_group_matches = output.capture_group_matches;
+        // Make sure there are as many capture matches as there are actual matches.
+        if (output_copy.capture_group_matches.size() < match_count)
+            output_copy.capture_group_matches.resize(match_count);
         for (auto& matches : output_copy.capture_group_matches)
             matches.resize(m_pattern.parser_result.capture_groups_count + 1);
         if (!input.regex_options.has_flag_set(AllFlags::SkipTrimEmptyMatches)) {
@@ -262,6 +265,9 @@ RegexResult Matcher<Parser>::match(const Vector<RegexStringView> views, Optional
         }
 
         output_copy.named_capture_group_matches = output.named_capture_group_matches;
+        // Make sure there are as many capture matches as there are actual matches.
+        if (output_copy.named_capture_group_matches.size() < match_count)
+            output_copy.named_capture_group_matches.resize(match_count);
 
         output_copy.matches = output.matches;
     } else {