Skip to content

Commit

Permalink
Merge pull request #223 from unshiftio/fix/at-sign-handling-in-userinfo
Browse files Browse the repository at this point in the history
Correctly handle userinfo containing the at sign
  • Loading branch information
Swaagie authored Feb 13, 2022
2 parents e4a5807 + 9be7ee8 commit 7b0b8a6
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 7 deletions.
37 changes: 30 additions & 7 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,11 @@ function Url(address, location, parser) {
if (parse !== parse) {
url[key] = address;
} else if ('string' === typeof parse) {
if (~(index = address.indexOf(parse))) {
index = parse === '@'
? address.lastIndexOf(parse)
: address.indexOf(parse);

if (~index) {
if ('number' === typeof instruction[2]) {
url[key] = address.slice(0, index);
address = address.slice(index + instruction[2]);
Expand Down Expand Up @@ -372,10 +376,21 @@ function Url(address, location, parser) {
// Parse down the `auth` for the username and password.
//
url.username = url.password = '';

if (url.auth) {
instruction = url.auth.split(':');
url.username = instruction[0];
url.password = instruction[1] || '';
index = url.auth.indexOf(':');

if (~index) {
url.username = url.auth.slice(0, index);
url.username = encodeURIComponent(decodeURIComponent(url.username));

url.password = url.auth.slice(index + 1);
url.password = encodeURIComponent(decodeURIComponent(url.password))
} else {
url.username = encodeURIComponent(decodeURIComponent(url.auth));
}

url.auth = url.password ? url.username +':'+ url.password : url.username;
}

url.origin = url.protocol !== 'file:' && isSpecial(url.protocol) && url.host
Expand Down Expand Up @@ -467,9 +482,17 @@ function set(part, value, fn) {
break;

case 'auth':
var splits = value.split(':');
url.username = splits[0];
url.password = splits.length === 2 ? splits[1] : '';
var index = value.indexOf(':');

if (~index) {
url.username = value.slice(0, index);
url.username = encodeURIComponent(decodeURIComponent(url.username));

url.password = value.slice(index + 1);
url.password = encodeURIComponent(decodeURIComponent(url.password));
} else {
url.username = encodeURIComponent(decodeURIComponent(value));
}
}

for (var i = 0; i < rules.length; i++) {
Expand Down
68 changes: 68 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,54 @@ describe('url-parse', function () {
assume(parsed.hostname).equals('www.example.com');
assume(parsed.href).equals(url);
});

it('handles @ in username', function () {
var url = 'http://user@@www.example.com/'
, parsed = parse(url);

assume(parsed.protocol).equals('http:');
assume(parsed.auth).equals('user%40');
assume(parsed.username).equals('user%40');
assume(parsed.password).equals('');
assume(parsed.hostname).equals('www.example.com');
assume(parsed.pathname).equals('/');
assume(parsed.href).equals('http://user%[email protected]/');

url = 'http://user%[email protected]/';
parsed = parse(url);

assume(parsed.protocol).equals('http:');
assume(parsed.auth).equals('user%40');
assume(parsed.username).equals('user%40');
assume(parsed.password).equals('');
assume(parsed.hostname).equals('www.example.com');
assume(parsed.pathname).equals('/');
assume(parsed.href).equals('http://user%[email protected]/');
});

it('handles @ in password', function () {
var url = 'http://user@:pas:s@@www.example.com/'
, parsed = parse(url);

assume(parsed.protocol).equals('http:');
assume(parsed.auth).equals('user%40:pas%3As%40');
assume(parsed.username).equals('user%40');
assume(parsed.password).equals('pas%3As%40');
assume(parsed.hostname).equals('www.example.com');
assume(parsed.pathname).equals('/');
assume(parsed.href).equals('http://user%40:pas%3As%[email protected]/');

url = 'http://user%40:pas%3As%[email protected]/'
parsed = parse(url);

assume(parsed.protocol).equals('http:');
assume(parsed.auth).equals('user%40:pas%3As%40');
assume(parsed.username).equals('user%40');
assume(parsed.password).equals('pas%3As%40');
assume(parsed.hostname).equals('www.example.com');
assume(parsed.pathname).equals('/');
assume(parsed.href).equals('http://user%40:pas%3As%[email protected]/');
});
});

it('accepts multiple ???', function () {
Expand Down Expand Up @@ -1158,6 +1206,26 @@ describe('url-parse', function () {
assume(data.username).equals('');
assume(data.password).equals('quux');
assume(data.href).equals('https://:[email protected]/');

assume(data.set('auth', 'user@:pass@')).equals(data);
assume(data.username).equals('user%40');
assume(data.password).equals('pass%40');
assume(data.href).equals('https://user%40:pass%[email protected]/');

assume(data.set('auth', 'user%40:pass%40')).equals(data);
assume(data.username).equals('user%40');
assume(data.password).equals('pass%40');
assume(data.href).equals('https://user%40:pass%[email protected]/');

assume(data.set('auth', 'user:pass:word')).equals(data);
assume(data.username).equals('user');
assume(data.password).equals('pass%3Aword');
assume(data.href).equals('https://user:pass%[email protected]/');

assume(data.set('auth', 'user:pass%3Aword')).equals(data);
assume(data.username).equals('user');
assume(data.password).equals('pass%3Aword');
assume(data.href).equals('https://user:pass%[email protected]/');
});

it('updates other values', function () {
Expand Down

0 comments on commit 7b0b8a6

Please sign in to comment.