Skip to content

Commit

Permalink
url: fix url.parse() for @hostname
Browse files Browse the repository at this point in the history
Make url.parse() behave more like browsers and WHATWHG URL when dealing
with URLs that of the format `http:@example.com`. This is the same as
`http://example.com`.
  • Loading branch information
Trott committed Feb 26, 2022
1 parent e84b635 commit 1bc1d06
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 16 deletions.
25 changes: 16 additions & 9 deletions lib/url.js
Original file line number Diff line number Diff line change
Expand Up @@ -294,22 +294,29 @@ Url.prototype.parse = function parse(url, parseQueryString, slashesDenoteHost) {
rest = rest.slice(proto.length);
}

// Figure out if it's got a host
// user@server is *always* interpreted as a hostname, and url
// Figure out if it's got a host.
// user@server is *always* interpreted as a hostname, and URL
// resolution will treat //foo/bar as host=foo,path=bar because that's
// how the browser resolves relative URLs.
let slashes;
// how the browser resolves relative URLs. http:@example.com is treated
// the same as http://example.com.
let removedCharsCount = 0;
if (slashesDenoteHost || proto || hostPattern.test(rest)) {
slashes = rest.charCodeAt(0) === CHAR_FORWARD_SLASH &&
rest.charCodeAt(1) === CHAR_FORWARD_SLASH;
if (slashes && !(proto && hostlessProtocol.has(lowerProto))) {
rest = rest.slice(2);
if (rest.charCodeAt(0) === CHAR_FORWARD_SLASH &&rest.charCodeAt(1) === CHAR_FORWARD_SLASH) {
this.slashes = true;
}
if (!(proto && hostlessProtocol.has(lowerProto))) {
if (this.slashes) {
rest = rest.slice(2);
} else if (slashedProtocol.has(lowerProto)) {
const newRest = rest.replace(/^[/\\]*@?/, '');
removedCharsCount = rest.length - newRest;
rest = newRest;
}
}
}

if (!hostlessProtocol.has(lowerProto) &&
(slashes || (proto && !slashedProtocol.has(proto)))) {
(this.slashes || removedCharsCount > 0 || proto)) {

// there's a hostname.
// the first instance of /, ?, ;, or # ends the host.
Expand Down
48 changes: 41 additions & 7 deletions test/parallel/test-url-parse-format.js
Original file line number Diff line number Diff line change
Expand Up @@ -348,10 +348,12 @@ const parseTests = {
},

'http:/baz/../foo/bar': {
href: 'http:/baz/../foo/bar',
href: 'http://baz/../foo/bar',
protocol: 'http:',
pathname: '/baz/../foo/bar',
path: '/baz/../foo/bar'
hostname: 'baz',
host: 'baz',
pathname: '/../foo/bar',
path: '/../foo/bar'
},

'http://user:pass@example.com:8000/foo/bar?baz=quux#frag': {
Expand Down Expand Up @@ -393,13 +395,15 @@ const parseTests = {
},

'http:/foo/bar?baz=quux#frag': {
href: 'http:/foo/bar?baz=quux#frag',
href: 'http://foo/bar?baz=quux#frag',
protocol: 'http:',
hash: '#frag',
host: 'foo',
hostname: 'foo',
search: '?baz=quux',
query: 'baz=quux',
pathname: '/foo/bar',
path: '/foo/bar?baz=quux'
pathname: '/bar',
path: '/bar?baz=quux'
},

'mailto:foo@bar.com?subject=hello': {
Expand Down Expand Up @@ -975,7 +979,37 @@ const parseTests = {
query: null,
pathname: '/everybody',
path: '/everybody',
href: '//fhqwhgads@example.com/everybody#to-the-limit'
href: '//fhqwhgads@example.com/everybody#to-the-limit',
},

'http:@localhost': {
protocol: 'http:',
slashes: null,
auth: null,
host: 'localhost',
port: null,
hostname: 'localhost',
hash: null,
search: null,
query: null,
pathname: '/',
path: '/',
href: 'http://localhost/',
},

'http:example.com': {
protocol: 'http:',
slashes: null,
auth: null,
host: 'example.com',
port: null,
hostname: 'example.com',
hash: null,
search: null,
query: null,
pathname: '/',
path: '/',
href: 'http://example.com/',
},
};

Expand Down

0 comments on commit 1bc1d06

Please sign in to comment.