diff --git a/lib/url.js b/lib/url.js index 6562be5d8302e6..80d0824fbe72ea 100644 --- a/lib/url.js +++ b/lib/url.js @@ -217,13 +217,13 @@ Url.prototype.parse = function parse(url, parseQueryString, slashesDenoteHost) { if (slashesDenoteHost || proto || hostPattern.test(rest)) { var slashes = rest.charCodeAt(0) === 47/*/*/ && rest.charCodeAt(1) === 47/*/*/; - if (slashes && !(proto && hostlessProtocol[proto])) { + if (slashes && !(proto && hostlessProtocol[lowerProto])) { rest = rest.slice(2); this.slashes = true; } } - if (!hostlessProtocol[proto] && + if (!hostlessProtocol[lowerProto] && (slashes || (proto && !slashedProtocol[proto]))) { // there's a hostname. diff --git a/test/parallel/test-url-parse-format.js b/test/parallel/test-url-parse-format.js index 0e12fe52516f16..c8daf90c159508 100644 --- a/test/parallel/test-url-parse-format.js +++ b/test/parallel/test-url-parse-format.js @@ -890,6 +890,39 @@ const parseTests = { pathname: '/*', path: '/*', href: 'https:///*' + }, + + // The following two URLs are the same, but they differ for + // a capital A: it is important that we verify that the protocol + // is checked in a case-insensitive manner. + 'javascript:alert(1);a=\x27@white-listed.com\x27': { + protocol: 'javascript:', + slashes: null, + auth: null, + host: null, + port: null, + hostname: null, + hash: null, + search: null, + query: null, + pathname: "alert(1);a='@white-listed.com'", + path: "alert(1);a='@white-listed.com'", + href: "javascript:alert(1);a='@white-listed.com'" + }, + + 'javAscript:alert(1);a=\x27@white-listed.com\x27': { + protocol: 'javascript:', + slashes: null, + auth: null, + host: null, + port: null, + hostname: null, + hash: null, + search: null, + query: null, + pathname: "alert(1);a='@white-listed.com'", + path: "alert(1);a='@white-listed.com'", + href: "javascript:alert(1);a='@white-listed.com'" } }; @@ -921,3 +954,25 @@ for (const u in parseTests) { assert.strictEqual(actual, expected, `format(${u}) == ${u}\nactual:${actual}`); } + +{ + const parsed = url.parse('http://nodejs.org/') + .resolveObject('jAvascript:alert(1);a=\x27@white-listed.com\x27'); + + const expected = Object.assign(new url.Url(), { + protocol: 'javascript:', + slashes: null, + auth: null, + host: null, + port: null, + hostname: null, + hash: null, + search: null, + query: null, + pathname: "alert(1);a='@white-listed.com'", + path: "alert(1);a='@white-listed.com'", + href: "javascript:alert(1);a='@white-listed.com'" + }); + + assert.deepStrictEqual(parsed, expected); +}