LibURL/Pattern: Ignore extra RegExp captures in match result
execResult may contain additional captures from nested groups in user-provided regexp parts, exceeding the number of URLPattern groups. Fixes a crash in the updated WPT test. See: https://github.com/whatwg/urlpattern/commit/203d435c32
This commit is contained in:
parent
e817b13c2a
commit
f4f6aefe32
3 changed files with 182 additions and 6 deletions
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Shannon Booth <shannon@serenityos.org>
|
||||
* Copyright (c) 2025-2026, Shannon Booth <shannon@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
|
@ -285,8 +285,8 @@ Component::Result Component::create_match_result(String const& input, regex::Reg
|
|||
OrderedHashMap<String, Variant<String, Empty>> groups;
|
||||
|
||||
// 4. Let index be 1.
|
||||
// 5. While index is less than Get(execResult, "length"):
|
||||
for (size_t index = 1; index <= exec_result.n_capture_groups; ++index) {
|
||||
// 5. While index is less than or equal to component’s group name list’s size:
|
||||
for (size_t index = 1; index <= group_name_list.size(); ++index) {
|
||||
auto const& capture = exec_result.capture_group_matches[0][index - 1];
|
||||
|
||||
// 1. Let name be component’s group name list[index − 1].
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 354 tests
|
||||
Found 367 tests
|
||||
|
||||
354 Pass
|
||||
367 Pass
|
||||
Pass Loading data...
|
||||
Pass Pattern: [{"pathname":"/foo/bar"}] Inputs: [{"pathname":"/foo/bar"}]
|
||||
Pass Pattern: [{"pathname":"/foo/bar"}] Inputs: [{"pathname":"/foo/ba"}]
|
||||
|
|
@ -356,4 +356,17 @@ Pass Pattern: ["#foo","https://example.com/?q=*&v=?&hmm={}&umm=()"] Inputs: ["ht
|
|||
Pass Pattern: [{"pathname":"/([[a-z]--a])"}] Inputs: [{"pathname":"/a"}]
|
||||
Pass Pattern: [{"pathname":"/([[a-z]--a])"}] Inputs: [{"pathname":"/z"}]
|
||||
Pass Pattern: [{"pathname":"/([\\d&&[0-1]])"}] Inputs: [{"pathname":"/0"}]
|
||||
Pass Pattern: [{"pathname":"/([\\d&&[0-1]])"}] Inputs: [{"pathname":"/3"}]
|
||||
Pass Pattern: [{"pathname":"/([\\d&&[0-1]])"}] Inputs: [{"pathname":"/3"}]
|
||||
Pass Pattern: [{"protocol":"http","hostname":"example.com/ignoredpath"}] Inputs: ["http://example.com/"]
|
||||
Pass Pattern: [{"protocol":"http","hostname":"example.com\\?ignoredsearch"}] Inputs: ["http://example.com/"]
|
||||
Pass Pattern: [{"protocol":"http","hostname":"example.com#ignoredhash"}] Inputs: ["http://example.com/"]
|
||||
Pass Pattern: ["https://www.example.com/*"] Inputs: ["https://www.example.com/x"]
|
||||
Pass Pattern: ["https://www.example.com/*"] Inputs: ["https://www.example.com/xyz"]
|
||||
Pass Pattern: ["https://www.example.com/*"] Inputs: ["https://www.example.com/example"]
|
||||
Pass Pattern: ["https://www.example.com/*"] Inputs: ["https://www.example.com/text"]
|
||||
Pass Pattern: ["https://www.example.com/*"] Inputs: ["https://www.example.com/path/with/x"]
|
||||
Pass Pattern: [{"hostname":":domain(.*)"}] Inputs: [{"hostname":"localhost"}]
|
||||
Pass Pattern: ["((?R)):"] Inputs: undefined
|
||||
Pass Pattern: ["(\\H):"] Inputs: undefined
|
||||
Pass Pattern: [{"pathname":"/:foo((?<x>a))"}] Inputs: [{"pathname":"/a"}]
|
||||
Pass Pattern: [{"pathname":"/foo/(bar(?<x>baz))"}] Inputs: [{"pathname":"/foo/barbaz"}]
|
||||
|
|
@ -2991,5 +2991,168 @@
|
|||
"pattern": [{ "pathname": "/([\\d&&[0-1]])" }],
|
||||
"inputs": [{ "pathname": "/3" }],
|
||||
"expected_match": null
|
||||
},
|
||||
{
|
||||
"pattern": [{ "protocol": "http", "hostname": "example.com/ignoredpath" }],
|
||||
"inputs": ["http://example.com/"],
|
||||
"expected_obj": {
|
||||
"protocol": "http",
|
||||
"hostname": "example.com",
|
||||
"pathname": "*"
|
||||
},
|
||||
"expected_match": {
|
||||
"protocol": { "input": "http", "groups": {} },
|
||||
"hostname": { "input": "example.com", "groups": {} },
|
||||
"pathname": { "input": "/", "groups": { "0": "/" } }
|
||||
}
|
||||
},
|
||||
{
|
||||
"pattern": [{ "protocol": "http", "hostname": "example.com\\?ignoredsearch" }],
|
||||
"inputs": ["http://example.com/"],
|
||||
"expected_obj": {
|
||||
"protocol": "http",
|
||||
"hostname": "example.com",
|
||||
"search": "*"
|
||||
},
|
||||
"expected_match": {
|
||||
"protocol": { "input": "http", "groups": {} },
|
||||
"hostname": { "input": "example.com", "groups": {} },
|
||||
"pathname": { "input": "/", "groups": { "0": "/" } }
|
||||
}
|
||||
},
|
||||
{
|
||||
"pattern": [{ "protocol": "http", "hostname": "example.com#ignoredhash" }],
|
||||
"inputs": ["http://example.com/"],
|
||||
"expected_obj": {
|
||||
"protocol": "http",
|
||||
"hostname": "example.com",
|
||||
"hash": "*"
|
||||
},
|
||||
"expected_match": {
|
||||
"protocol": { "input": "http", "groups": {} },
|
||||
"hostname": { "input": "example.com", "groups": {} },
|
||||
"pathname": { "input": "/", "groups": { "0": "/" } }
|
||||
}
|
||||
},
|
||||
{
|
||||
"pattern": ["https://www.example.com/*"],
|
||||
"inputs": ["https://www.example.com/x"],
|
||||
"exactly_empty_components": ["port"],
|
||||
"expected_obj": {
|
||||
"protocol": "https",
|
||||
"hostname": "www.example.com",
|
||||
"pathname": "/*"
|
||||
},
|
||||
"expected_match": {
|
||||
"protocol": { "input": "https", "groups": {} },
|
||||
"hostname": { "input": "www.example.com", "groups": {} },
|
||||
"pathname": { "input": "/x", "groups": { "0": "x" } }
|
||||
}
|
||||
},
|
||||
{
|
||||
"pattern": ["https://www.example.com/*"],
|
||||
"inputs": ["https://www.example.com/xyz"],
|
||||
"exactly_empty_components": ["port"],
|
||||
"expected_obj": {
|
||||
"protocol": "https",
|
||||
"hostname": "www.example.com",
|
||||
"pathname": "/*"
|
||||
},
|
||||
"expected_match": {
|
||||
"protocol": { "input": "https", "groups": {} },
|
||||
"hostname": { "input": "www.example.com", "groups": {} },
|
||||
"pathname": { "input": "/xyz", "groups": { "0": "xyz" } }
|
||||
}
|
||||
},
|
||||
{
|
||||
"pattern": ["https://www.example.com/*"],
|
||||
"inputs": ["https://www.example.com/example"],
|
||||
"exactly_empty_components": ["port"],
|
||||
"expected_obj": {
|
||||
"protocol": "https",
|
||||
"hostname": "www.example.com",
|
||||
"pathname": "/*"
|
||||
},
|
||||
"expected_match": {
|
||||
"protocol": { "input": "https", "groups": {} },
|
||||
"hostname": { "input": "www.example.com", "groups": {} },
|
||||
"pathname": { "input": "/example", "groups": { "0": "example" } }
|
||||
}
|
||||
},
|
||||
{
|
||||
"pattern": ["https://www.example.com/*"],
|
||||
"inputs": ["https://www.example.com/text"],
|
||||
"exactly_empty_components": ["port"],
|
||||
"expected_obj": {
|
||||
"protocol": "https",
|
||||
"hostname": "www.example.com",
|
||||
"pathname": "/*"
|
||||
},
|
||||
"expected_match": {
|
||||
"protocol": { "input": "https", "groups": {} },
|
||||
"hostname": { "input": "www.example.com", "groups": {} },
|
||||
"pathname": { "input": "/text", "groups": { "0": "text" } }
|
||||
}
|
||||
},
|
||||
{
|
||||
"pattern": ["https://www.example.com/*"],
|
||||
"inputs": ["https://www.example.com/path/with/x"],
|
||||
"exactly_empty_components": ["port"],
|
||||
"expected_obj": {
|
||||
"protocol": "https",
|
||||
"hostname": "www.example.com",
|
||||
"pathname": "/*"
|
||||
},
|
||||
"expected_match": {
|
||||
"protocol": { "input": "https", "groups": {} },
|
||||
"hostname": { "input": "www.example.com", "groups": {} },
|
||||
"pathname": { "input": "/path/with/x", "groups": { "0": "path/with/x" } }
|
||||
}
|
||||
},
|
||||
{
|
||||
"pattern": [{ "hostname": ":domain(.*)" }],
|
||||
"inputs": [{ "hostname": "localhost" }],
|
||||
"expected_obj": {
|
||||
"hostname": ":domain(.*)"
|
||||
},
|
||||
"expected_match": {
|
||||
"hostname": { "input": "localhost", "groups": { "domain" : "localhost"} }
|
||||
}
|
||||
},
|
||||
{
|
||||
"pattern": ["((?R)):"],
|
||||
"expected_obj": "error"
|
||||
},
|
||||
{
|
||||
"pattern": ["(\\H):"],
|
||||
"expected_obj": "error"
|
||||
},
|
||||
{
|
||||
"pattern": [
|
||||
{"pathname": "/:foo((?<x>a))"}
|
||||
],
|
||||
"inputs": [
|
||||
{"pathname": "/a"}
|
||||
],
|
||||
"expected_match": {
|
||||
"pathname": {
|
||||
"input": "/a",
|
||||
"groups": {"foo": "a"}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"pattern": [
|
||||
{"pathname": "/foo/(bar(?<x>baz))"}
|
||||
],
|
||||
"inputs": [
|
||||
{"pathname": "/foo/barbaz"}
|
||||
],
|
||||
"expected_match": {
|
||||
"pathname": {
|
||||
"input": "/foo/barbaz",
|
||||
"groups": {"0": "barbaz"}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
|||
Loading…
Reference in a new issue