diff --git a/index.js b/index.js index 517b6b6..d808b13 100644 --- a/index.js +++ b/index.js @@ -539,6 +539,17 @@ function toString(stringify) { } else if (url.password) { result += ':'+ url.password; result += '@'; + } else if ( + url.protocol !== 'file:' && + isSpecial(url.protocol) && + !url.host && + url.pathname !== '/' + ) { + // + // Add back the empty userinfo, otherwise the original invalid URL + // might be transformed into a valid one with `url.pathname` as host. + // + result += '@'; } result += url.host + url.pathname; diff --git a/test/test.js b/test/test.js index 6d53eb9..98880b3 100644 --- a/test/test.js +++ b/test/test.js @@ -771,6 +771,65 @@ describe('url-parse', function () { assume(parsed.pathname).equals('/'); assume(parsed.href).equals('http://user%40:pas%3As%40@www.example.com/'); }); + + it('adds @ to href if auth and host are empty', function () { + var parsed, i = 0; + var urls = [ + 'http:@/127.0.0.1', + 'http::@/127.0.0.1', + 'http:/@/127.0.0.1', + 'http:/:@/127.0.0.1', + 'http://@/127.0.0.1', + 'http://:@/127.0.0.1', + 'http:///@/127.0.0.1', + 'http:///:@/127.0.0.1' + ]; + + for (; i < urls.length; i++) { + parsed = parse(urls[i]); + + assume(parsed.protocol).equals('http:'); + assume(parsed.auth).equals(''); + assume(parsed.username).equals(''); + assume(parsed.password).equals(''); + assume(parsed.host).equals(''); + assume(parsed.hostname).equals(''); + assume(parsed.pathname).equals('/127.0.0.1'); + assume(parsed.origin).equals('null'); + assume(parsed.href).equals('http://@/127.0.0.1'); + assume(parsed.toString()).equals('http://@/127.0.0.1'); + } + + urls = [ + 'http:@/', + 'http:@', + 'http::@/', + 'http::@', + 'http:/@/', + 'http:/@', + 'http:/:@/', + 'http:/:@', + 'http://@/', + 'http://@', + 'http://:@/', + 'http://:@' + ]; + + for (i = 0; i < urls.length; i++) { + parsed = parse(urls[i]); + + assume(parsed.protocol).equals('http:'); + assume(parsed.auth).equals(''); + assume(parsed.username).equals(''); + assume(parsed.password).equals(''); + assume(parsed.host).equals(''); + assume(parsed.hostname).equals(''); + assume(parsed.pathname).equals('/'); + assume(parsed.origin).equals('null'); + assume(parsed.href).equals('http:///'); + assume(parsed.toString()).equals('http:///'); + } + }); }); it('accepts multiple ???', function () {