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
6 changes: 5 additions & 1 deletion src/node_url.cc
Original file line number Diff line number Diff line change
Expand Up @@ -443,8 +443,12 @@ void BindingData::Update(const FunctionCallbackInfo<Value>& args) {
Utf8Value new_value(isolate, args[2].As<String>());

std::string_view new_value_view = new_value.ToStringView();
// A serialized URL is not always reparsable: the IDNA encoder can emit a
// host label that the decoder rejects. Fail the update instead of crashing.
auto out = ada::parse<ada::url_aggregator>(input.ToStringView());
CHECK(out);
if (!out) {
return args.GetReturnValue().Set(false);
}

bool result{true};

Expand Down
26 changes: 26 additions & 0 deletions test/parallel/test-whatwg-url-custom-setters.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,32 @@ const additionalTestCases =
}
}

// The parser can produce a serialization it rejects when parsing it back: a
// Unicode host encodes to an `xn--xn--` label that the punycode decoder turns
// down. Setters reparse `href`, so the failure must not take the process down.
// Implementations backed by ICU accept that label, and ada does too as of
// https://github.com/ada-url/idna/pull/72, so this URL round-trips once that
// lands here and the setters below apply as usual.
test(function() {
const url = new URL('http:\u{1F600}xn-');
const setters = {
hostname: 'example.com',
host: 'example.com:8080',
protocol: 'https:',
pathname: '/path',
search: '?search',
hash: '#hash',
port: '8080',
username: 'username',
password: 'password',
};

for (const [property, value] of Object.entries(setters)) {
url[property] = value;
assert_equals(typeof url.href, 'string', `Setting ${property} does not crash`);
}
Comment thread
mcollina marked this conversation as resolved.
}, 'URL: setting properties with an unparsable serialized URL');

{
const url = new URL('http://example.com/');
const obj = {
Expand Down
Loading