mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-15 20:33:10 +00:00
LibJS: Don't assume match for each capture group in RegExp.prototype.exec()
This was not implementing the following part of the spec correctly: 27. For each integer i such that i ≥ 1 and i ≤ n, do a. Let captureI be ith element of r's captures List. b. If captureI is undefined, let capturedValue be undefined. Expecting a capture group match to exist for each of the RegExp's capture groups would assert in Vector's operator[] if that's not the case, for example: /(foo)(bar)?/.exec("foo") Append undefined instead. Fixes #5256.
This commit is contained in:
parent
1d843c46eb
commit
83c29bd8d7
|
@ -190,8 +190,12 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::exec)
|
|||
array->indexed_properties().put(array, 0, js_string(vm, match.view.to_string()));
|
||||
|
||||
for (size_t i = 0; i < result.n_capture_groups; ++i) {
|
||||
auto& capture = result.capture_group_matches[0][i];
|
||||
array->indexed_properties().put(array, i + 1, js_string(vm, capture.view.to_string()));
|
||||
auto capture_value = js_undefined();
|
||||
if (result.capture_group_matches[0].size() > i) {
|
||||
auto& capture = result.capture_group_matches[0][i];
|
||||
capture_value = js_string(vm, capture.view.to_string());
|
||||
}
|
||||
array->indexed_properties().put(array, i + 1, capture_value);
|
||||
}
|
||||
|
||||
Value groups = js_undefined();
|
||||
|
|
|
@ -18,6 +18,16 @@ test("basic unnamed captures", () => {
|
|||
expect(res[1]).toBe("ooooo");
|
||||
expect(res.groups).toBe(undefined);
|
||||
expect(res.index).toBe(0);
|
||||
|
||||
re = /(foo)(bar)?/;
|
||||
res = re.exec("foo");
|
||||
|
||||
expect(res.length).toBe(3);
|
||||
expect(res[0]).toBe("foo");
|
||||
expect(res[1]).toBe("foo");
|
||||
expect(res[2]).toBe(undefined);
|
||||
expect(res.groups).toBe(undefined);
|
||||
expect(res.index).toBe(0);
|
||||
});
|
||||
|
||||
test("basic named captures", () => {
|
||||
|
|
Loading…
Reference in a new issue