From b612773fae2455125a85f0d591359eb6ffdce582 Mon Sep 17 00:00:00 2001 From: Yagiz Nizipli Date: Tue, 7 Feb 2023 14:17:58 -0500 Subject: [PATCH] url: fix url spec compliance issues Co-authored-by: Daniel Lemire --- lib/internal/url.js | 9 ++++++++- src/node_url.cc | 3 +++ test/parallel/test-whatwg-url-custom-inspect.js | 3 ++- test/wpt/status/url.json | 8 +++++++- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/lib/internal/url.js b/lib/internal/url.js index 886c70a13b806b..ae3a0b4470946c 100644 --- a/lib/internal/url.js +++ b/lib/internal/url.js @@ -153,6 +153,7 @@ class URLContext { hash = ''; hasHost = false; hasOpaquePath = false; + hasHash = false; } function isURLSearchParams(self) { @@ -628,7 +629,7 @@ class URL { #onParseComplete = (href, origin, protocol, host, hostname, pathname, search, username, password, port, hash, hasHost, - hasOpaquePath) => { + hasOpaquePath, hasHash) => { const ctx = this[context]; ctx.href = href; ctx.origin = origin; @@ -644,6 +645,7 @@ class URL { // TODO(@anonrig): Remove hasHost and hasOpaquePath when kFormat is removed. ctx.hasHost = hasHost; ctx.hasOpaquePath = hasOpaquePath; + ctx.hasHash = hasHash; if (!this[searchParams]) { // Invoked from URL constructor this[searchParams] = new URLSearchParams(); this[searchParams][context] = this; @@ -864,6 +866,11 @@ function update(url, params) { ctx.search = '?' + serializedParams; } else { ctx.search = ''; + + // Potentially strip trailing spaces from an opaque path + if (ctx.hasOpaquePath && !ctx.hasHash) { + ctx.pathname = ctx.pathname.trimEnd(); + } } ctx.href = constructHref(ctx); } diff --git a/src/node_url.cc b/src/node_url.cc index d41a956b1203e8..99fae67f12f9d5 100644 --- a/src/node_url.cc +++ b/src/node_url.cc @@ -62,6 +62,7 @@ void SetArgs(Environment* env, Local argv[12], const ada::result& url) { argv[10] = Utf8String(isolate, url->get_hash()); argv[11] = Boolean::New(isolate, url->host.has_value()); argv[12] = Boolean::New(isolate, url->has_opaque_path); + argv[13] = Boolean::New(isolate, url->fragment.has_value()); } void Parse(const FunctionCallbackInfo& args) { @@ -109,6 +110,7 @@ void Parse(const FunctionCallbackInfo& args) { undef, undef, undef, + undef, }; SetArgs(env, argv, out); USE(success_callback_->Call( @@ -260,6 +262,7 @@ void UpdateUrl(const FunctionCallbackInfo& args) { undef, undef, undef, + undef, }; SetArgs(env, argv, out); USE(success_callback_->Call( diff --git a/test/parallel/test-whatwg-url-custom-inspect.js b/test/parallel/test-whatwg-url-custom-inspect.js index e64f9991f5f0d9..97e1f9e1cf870e 100644 --- a/test/parallel/test-whatwg-url-custom-inspect.js +++ b/test/parallel/test-whatwg-url-custom-inspect.js @@ -58,7 +58,8 @@ assert.strictEqual( port: '8080', hash: '#hash', hasHost: true, - hasOpaquePath: false + hasOpaquePath: false, + hasHash: true } }`); diff --git a/test/wpt/status/url.json b/test/wpt/status/url.json index a1c90f210506db..b11a049b8b9685 100644 --- a/test/wpt/status/url.json +++ b/test/wpt/status/url.json @@ -7,7 +7,13 @@ "skip": "TODO: port from .window.js" }, "historical.any.js": { - "requires": ["small-icu"] + "requires": ["small-icu"], + "fail": { + "expected": [ + "URL: no structured serialize/deserialize support", + "URLSearchParams: no structured serialize/deserialize support" + ] + } }, "urlencoded-parser.any.js": { "requires": ["small-icu"]