Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions NativeScript/runtime/URLPatternImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,19 @@ v8_regex_provider::regex_search(
auto array = matches.As<v8::Array>();
auto len = array->Length();
ret.reserve(len);
for (int i = 0; i < len; i++) {
// Skip element 0 (the whole-match string). ada's
// url_pattern_component::create_component_match_result pairs exec_result[i]
// with group_name_list[i], i.e. it expects only the capture groups.
// Including element 0 makes exec_result one longer than group_name_list and
// indexes it out of bounds (crash). ada documents this: the provider must
// drop the full match ("start from 1").
for (int i = 1; i < len; i++) {
v8::Local<v8::Value> item;
if (array->Get(isolate->GetCurrentContext(), i).ToLocal(&item)) {
// ToLocal returns true on success; bail only when reading the element
// fails. (This condition was inverted, which made every regex match
// report no match, so URLPattern test()/exec() always failed for patterns
// with capture groups.)
if (!array->Get(isolate->GetCurrentContext(), i).ToLocal(&item)) {
return std::nullopt;
}

Expand Down
19 changes: 19 additions & 0 deletions TestRunner/app/tests/URLPattern.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,23 @@ describe("URLPattern", function () {
expect(pattern.hostname).toBe("google.com");
});

it("test() matches a URL against a pattern with a capture group", function () {
const pattern = new URLPattern("https://example.com/books/:id");
expect(pattern.test("https://example.com/books/123")).toBe(true);
expect(pattern.test("https://example.com/movies/123")).toBe(false);
});

it("exec() extracts named capture groups", function () {
const pattern = new URLPattern("https://example.com/books/:id");
const result = pattern.exec("https://example.com/books/123");
expect(result).not.toBeNull();
expect(result.pathname.input).toBe("/books/123");
expect(result.pathname.groups.id).toBe("123");
});

it("exec() returns null when the URL does not match", function () {
const pattern = new URLPattern("https://example.com/books/:id");
expect(pattern.exec("https://example.com/movies/123")).toBeNull();
});

});
Loading