Sitelet https://github.com/nodejs/node/pull/24495/commits/8be84ac58930db9c9250ae9b89e6866d3aa0dff5
Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
url: reuse existing context in href setter
Correctness-wise, this removes side effects in the href setter if parsing
fails. Style-wise, this allows removing the parse() wrapper function around C++
_parse().

Also fix an existing bug with whitespace trimming in C++ that was previously
circumvented by additionally trimming the input in JavaScript.

Fixes: #24345
Refs: #24218 (comment)
  • Loading branch information
TimothyGu committed Nov 19, 2018
commit 8be84ac58930db9c9250ae9b89e6866d3aa0dff5
34 changes: 15 additions & 19 deletions lib/internal/url.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const {
domainToUnicode: _domainToUnicode,
encodeAuth,
toUSVString: _toUSVString,
parse: _parse,
parse,
setURLConstructor,
URL_FLAGS_CANNOT_BE_BASE,
URL_FLAGS_HAS_FRAGMENT,
Expand Down Expand Up @@ -242,14 +242,6 @@ function onParseError(flags, input) {
throw error;
}

// Reused by URL constructor and URL#href setter.
function parse(url, input, base) {
const base_context = base ? base[context] : undefined;
url[context] = new URLContext();
_parse(input.trim(), -1, base_context, undefined,
onParseComplete.bind(url), onParseError);
}

function onParseProtocolComplete(flags, protocol, username, password,
host, port, path, query, fragment) {
const ctx = this[context];
Expand Down Expand Up @@ -318,10 +310,13 @@ class URL {
constructor(input, base) {
// toUSVString is not needed.
input = `${input}`;
let base_context;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be camelCase, for consistency?

if (base !== undefined) {
base = new url(/sitelet?url=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2F24495%2Fcommits%2Fbase);
base_context = new url(/sitelet?url=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2F24495%2Fcommits%2Fbase)[context];
}
parse(this, input, base);
this[context] = new URLContext();
parse(input, -1, base_context, undefined, onParseComplete.bind(this),
onParseError);
}

get [special]() {
Expand Down Expand Up @@ -444,7 +439,8 @@ Object.defineProperties(URL.prototype, {
set(input) {
// toUSVString is not needed.
input = `${input}`;
parse(this, input);
parse(input, -1, undefined, undefined, onParseComplete.bind(this),
onParseError);
}
},
origin: { // readonly
Expand Down Expand Up @@ -490,7 +486,7 @@ Object.defineProperties(URL.prototype, {
(ctx.host === '' || ctx.host === null)) {
return;
}
_parse(scheme, kSchemeStart, null, ctx,
parse(scheme, kSchemeStart, null, ctx,
onParseProtocolComplete.bind(this));
}
},
Expand Down Expand Up @@ -554,7 +550,7 @@ Object.defineProperties(URL.prototype, {
// Cannot set the host if cannot-be-base is set
return;
}
_parse(host, kHost, null, ctx, onParseHostComplete.bind(this));
parse(host, kHost, null, ctx, onParseHostComplete.bind(this));
}
},
hostname: {
Expand All @@ -571,7 +567,7 @@ Object.defineProperties(URL.prototype, {
// Cannot set the host if cannot-be-base is set
return;
}
_parse(host, kHostname, null, ctx, onParseHostnameComplete.bind(this));
parse(host, kHostname, null, ctx, onParseHostnameComplete.bind(this));
}
},
port: {
Expand All @@ -591,7 +587,7 @@ Object.defineProperties(URL.prototype, {
ctx.port = null;
return;
}
_parse(port, kPort, null, ctx, onParsePortComplete.bind(this));
parse(port, kPort, null, ctx, onParsePortComplete.bind(this));
}
},
pathname: {
Expand All @@ -610,7 +606,7 @@ Object.defineProperties(URL.prototype, {
path = `${path}`;
if (this[cannotBeBase])
return;
_parse(path, kPathStart, null, this[context],
parse(path, kPathStart, null, this[context],
onParsePathComplete.bind(this));
}
},
Expand All @@ -634,7 +630,7 @@ Object.defineProperties(URL.prototype, {
ctx.query = '';
ctx.flags |= URL_FLAGS_HAS_QUERY;
if (search) {
_parse(search, kQuery, null, ctx, onParseSearchComplete.bind(this));
parse(search, kQuery, null, ctx, onParseSearchComplete.bind(this));
}
}
initSearchParams(this[searchParams], search);
Expand Down Expand Up @@ -668,7 +664,7 @@ Object.defineProperties(URL.prototype, {
if (hash[0] === '#') hash = hash.slice(1);
ctx.fragment = '';
ctx.flags |= URL_FLAGS_HAS_FRAGMENT;
_parse(hash, kFragment, null, ctx, onParseHashComplete.bind(this));
parse(hash, kFragment, null, ctx, onParseHashComplete.bind(this));
}
},
toJSON: {
Expand Down
1 change: 1 addition & 0 deletions src/node_url.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1375,6 +1375,7 @@ void URL::Parse(const char* input,
else
break;
}
input = p;
len = end - p;
}

Expand Down
15 changes: 15 additions & 0 deletions test/parallel/test-whatwg-url-custom-href-side-effect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use strict';

// Tests below are not from WPT.
const common = require('../common');
const assert = require('assert');

const ref = new url(/sitelet?url=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2F24495%2Fcommits%2F%26%2339%3Bhttp%3A%2F%2Fexample.com%2Fpath%26%2339%3B);
const url = new url(/sitelet?url=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2F24495%2Fcommits%2F%26%2339%3Bhttp%3A%2F%2Fexample.com%2Fpath%26%2339%3B);
common.expectsError(() => {
url.href = '';
}, {
type: TypeError
});

assert.deepStrictEqual(url, ref);