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
url: align URLPatternInit dictionary conversion with WebIDL
Read URLPatternInit dictionary members in lexicographical order so
getters and proxy traps observe the access sequence required by WebIDL.
Use sparse dictionary template values so URLPatternResult inputs only
expose members present after WebIDL conversion.

Fixes: #64780
Signed-off-by: piyushrajyadav <piyushyadavrajyadav@gmail.com>
  • Loading branch information
piyushrajyadav committed Aug 25, 2026
commit d3687d9bb7dd9072f5b8e65179982161aea9c8ab
47 changes: 18 additions & 29 deletions src/node_url_pattern.cc
Original file line number Diff line number Diff line change
Expand Up @@ -307,32 +307,21 @@ MaybeLocal<Value> URLPattern::URLPatternInit::ToJsObject(
auto tmpl = env->urlpatterninit_template();
if (tmpl.IsEmpty()) {
static constexpr std::string_view namesVec[] = {
"protocol",
"username",
"password",
"baseURL",
"hash",
"hostname",
"port",
"password",
"pathname",
"port",
"protocol",
"search",
"hash",
"baseURL",
"username",
};
tmpl = DictionaryTemplate::New(isolate, namesVec);
env->set_urlpatterninit_template(tmpl);
}

MaybeLocal<Value> values[] = {
Undefined(isolate), // protocol
Undefined(isolate), // username
Undefined(isolate), // password
Undefined(isolate), // hostname
Undefined(isolate), // port
Undefined(isolate), // pathname
Undefined(isolate), // search
Undefined(isolate), // hash
Undefined(isolate), // baseURL
};

MaybeLocal<Value> values[9];
int idx = 0;
Local<Value> temp;
const auto trySet = [&](const std::optional<std::string>& val) {
Expand All @@ -346,28 +335,28 @@ MaybeLocal<Value> URLPattern::URLPatternInit::ToJsObject(
return true;
};

if (!trySet(init.protocol) || !trySet(init.username) ||
!trySet(init.password) || !trySet(init.hostname) || !trySet(init.port) ||
!trySet(init.pathname) || !trySet(init.search) || !trySet(init.hash) ||
!trySet(init.base_url)) {
if (!trySet(init.base_url) || !trySet(init.hash) || !trySet(init.hostname) ||
!trySet(init.password) || !trySet(init.pathname) || !trySet(init.port) ||
!trySet(init.protocol) || !trySet(init.search) ||
!trySet(init.username)) {
return {};
}
return NewDictionaryInstance(env->context(), tmpl, values);
return tmpl->NewInstance(context, values);
}

std::optional<ada::url_pattern_init> URLPattern::URLPatternInit::FromJsObject(
Environment* env, Local<Object> obj) {
ada::url_pattern_init init{};
Local<String> components[] = {
env->protocol_string(),
env->username_string(),
env->password_string(),
env->base_url_string(),
env->hash_string(),
env->hostname_string(),
env->port_string(),
env->password_string(),
env->pathname_string(),
env->port_string(),
env->protocol_string(),
env->search_string(),
env->hash_string(),
env->base_url_string(),
env->username_string(),
};
auto isolate = env->isolate();
const auto set_parameter = [&](std::string_view key, std::string_view value) {
Expand Down
40 changes: 40 additions & 0 deletions test/parallel/test-urlpattern.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,43 @@ assert.throws(() => {
assert.strictEqual(result.pathname.input, '/test');
assert.strictEqual(result.pathname.groups.value, 'test');
}

{
const accessed = [];
const expected = [
'baseURL',
'hash',
'hostname',
'password',
'pathname',
'port',
'protocol',
'search',
'username',
];
const init = new Proxy({}, {
get(target, name, receiver) {
accessed.push(name);
return Reflect.get(target, name, receiver);
},
});

new URLPattern(init);
assert.deepStrictEqual(accessed, expected);
}

{
const input = new URLPattern({ pathname: '/x' })
.exec({
protocol: 'https',
pathname: '/x',
username: undefined,
}).inputs[0];

assert.deepStrictEqual(Object.keys(input), ['pathname', 'protocol']);
assert.strictEqual('username' in input, false);
assert.deepStrictEqual({ ...input }, {
pathname: '/x',
protocol: 'https',
});
}
Loading