-
Notifications
You must be signed in to change notification settings - Fork 30.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
url: Fix error type in constructor #19299
Conversation
About semverness - I feel like this is a semver-patch since it's a bugfig. Technically it changes an error message in an edge case. |
@@ -22,6 +22,7 @@ const failureTests = tests.filter((test) => test.failure).concat([ | |||
{ input: null }, | |||
{ input: new Date() }, | |||
{ input: new RegExp() }, | |||
{ input: 'test', base: null}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, my example in the issue was not very good. This throws because 'test'
is not a valid URL. With this change, a valid input with a base of null
will not throw. To make it work, we still need to reach the line with base = new URL(base);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for clarifying!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added two relevant examples below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@targos please take another look - I've changed the code since that review.
lib/internal/url.js
Outdated
@@ -312,6 +312,7 @@ class URL { | |||
// toUSVString is not needed. | |||
input = `${input}`; | |||
if (base !== undefined && | |||
base !== null && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to the current specification of URL, it might not be needed to checking base as like instanceof since base is guaranteed to be a USVString. Also, in this case, it should display an error for parsing base = null
, so I think we can simply write like the following:
if (base !== undefined) {
base = new URL(base);
}
/*
The result in my local is here:
> new URL('test', null)
internal/url.js:228
throw error;
^
TypeError [ERR_INVALID_URL]: Invalid URL: null
at onParseError (internal/url.js:226:17)
at parse (internal/url.js:235:3)
at new URL (internal/url.js:317:5)
at new URL (internal/url.js:315:14)
at Object.<anonymous> (/Users/watilde/Development/tmp/1/a.js:2:1)
at Module._compile (module.js:671:30)
at Object.Module._extensions..js (module.js:682:10)
at Module.load (module.js:582:32)
at tryModuleLoad (module.js:522:12)
at Function.Module._load (module.js:514:3)
*/
Refs: https://github.com/jsdom/whatwg-url/blob/master/lib/URL-impl.js#L12-L17
Spec: https://github.com/whatwg/url/blob/master/url.bs#L2592-L2599
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah you're right, the undefined check is also incorrect
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your quick update!
@watilde @targos please take a look, I've added a test for a valid URL with invalid base and changed the implementation to not check if the object passed in is a URL and build a new URL anyway. I didn't notice any regression compared to the optimization done in https://github.com/nodejs/node/pull/11690/files - I can readd the check here but I wonder how common the case a URL is passed in as a baseUrl (which becomes a little slower) is vs a string (which becomes a little faster, and is the more important case IMO). If either of you feels strongly about it I can re-add that check inside a Another question - I currently check |
lib/internal/url.js
Outdated
@@ -311,8 +311,7 @@ class URL { | |||
constructor(input, base) { | |||
// toUSVString is not needed. | |||
input = `${input}`; | |||
if (base !== undefined && | |||
(!base[searchParams] || !base[searchParams][searchParams])) { | |||
if (arguments.length === 2) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should still allow to explicitly pass undefined
. I don't know what the spec says, but Chrome accepts it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@targos https://github.com/whatwg/url/blob/master/url.bs#L2592-L2599 implies it doesn't allow it - but I'm all for Chrome compatibility and I'm not sure what the spec reads as.
What do you think about just removing the base[searchParams]
and staying compatible with the URL impl at https://github.com/jsdom/whatwg-url/blob/master/lib/URL-impl.js#L12-L17 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Staying compatible with whatwg-url SGTM. I would actually like us to throw a more precise error saying which URL us invalid but that's out of scope for this PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is about how we can write "If base is given" and both sound good to me if CI gets green.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@TimothyGu What do you think about this?
To be clear, undefined is allowed, it's just then the spec steps for "base is given" do not run. (Undefined = not present, as always in JS.) So parsedBase gets left as null. In that case the first argument has to be an absolute URL, or the parser will fail (because that's what happens when you parse a relative URL against a null base). |
@domenic and what should the behavior for |
|
Ok, I basically ended up removing the optimization for passing an "already URL" as base (since I suspect that's not the interesting case anyway) - that removes the bug and I don't see a big performance difference. I think given the different approaches it ended up being both the simplest and most "obviously correct"' one. Thanks everyone! |
@targos please take another look - I've changed the code to what I believe is correct
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM if the test is fixed
@@ -22,6 +22,9 @@ const failureTests = tests.filter((test) => test.failure).concat([ | |||
{ input: null }, | |||
{ input: new Date() }, | |||
{ input: new RegExp() }, | |||
{ input: 'test', base: null}, | |||
{ input: 'http://nodejs.org', base: null}, | |||
{ input: 'http://nodejs.org', base: undefined}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this still error? It should not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point! I forgot to push, I'll run the tests again on my box
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, also squashed.
6c7130c
to
f50f6f1
Compare
@@ -22,6 +22,8 @@ const failureTests = tests.filter((test) => test.failure).concat([ | |||
{ input: null }, | |||
{ input: new Date() }, | |||
{ input: new RegExp() }, | |||
{ input: 'test', base: null}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nits: space is required before }
. Also on line 26.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very concerned that the linter didn't fail locally - thanks!
Currently whatwg URLs fail with an incorrect error when null is passed as the base. Adding a check before accessing a symbol for the URL makes the URL error correctly. Add test for it. PR-URL: nodejs#19299 Reviewed-By: Daijiro Wachi <daijiro.wachi@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Fixes: nodejs#19254
f50f6f1
to
b735681
Compare
@benjamingr would you be interested in submitting a pull request to Web Platform Tests as well, to ensure that the same bug doesn't happen in browsers? |
Just wondering, how did you measure the performance difference? I don't believe we have a benchmark for this case yet. |
Currently whatwg URLs fail with an incorrect error when null is passed as the base. Adding a check before accessing a symbol for the URL makes the URL error correctly. Add test for it. PR-URL: nodejs#19299 Fixes: nodejs#19254 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Daijiro Wachi <daijiro.wachi@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Landed in cc6abc6 🎉 |
Currently whatwg URLs fail with an incorrect error when null is passed as the base. Adding a check before accessing a symbol for the URL makes the URL error correctly. Add test for it. PR-URL: #19299 Fixes: #19254 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Daijiro Wachi <daijiro.wachi@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Currently whatwg URLs fail with an incorrect error when null is passed as the base. Adding a check before accessing a symbol for the URL makes the URL error correctly.
Add test for it.
Fixes: #19254
cc @targos @nodejs/url