1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
Description: Correctly handle userinfo containing the at sign
Author: Luigi Pinca <luigipinca@gmail.com>
Origin: upstream, https://github.com/unshiftio/url-parse/commit/9be7ee88
Bug: https://huntr.dev/bounties/6d1bc51f-1876-4f5b-a2c2-734e09e8e05b
Forwarded: not-needed
Applied-Upstream: 1.5.6, commit:9be7ee88
Reviewed-By: Yadd <yadd@debian.org>
Last-Update: 2023-05-31
--- a/index.js
+++ b/index.js
@@ -306,7 +306,11 @@
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]);
@@ -373,9 +377,19 @@
//
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
--- a/test/test.js
+++ b/test/test.js
@@ -712,6 +712,54 @@
});
});
+ 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%40@www.example.com/');
+
+ url = 'http://user%40@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%40@www.example.com/');
+ });
+
+ 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%40@www.example.com/');
+
+ url = 'http://user%40:pas%3As%40@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%40@www.example.com/');
+ });
+
it('accepts multiple ???', function () {
var url = 'http://mt0.google.com/vt/lyrs=m@114???&hl=en&src=api&x=2&y=2&z=3&s=';
assume(parse(url).query).equals('???&hl=en&src=api&x=2&y=2&z=3&s=');
@@ -1078,6 +1126,30 @@
assume(data.username).equals('foo');
assume(data.href).equals('https://foo@google.com/?foo=bar');
+
+ data = parse('https://user@:pass@@example.com/');
+ 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%40@example.com/');
+
+ data = parse('https://user%40:pass%40@example.com/');
+ 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%40@example.com/');
+
+ data = parse('https://user:pass:word@example.com/');
+ 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%3Aword@example.com/');
+
+ data = parse('https://user:pass%3Aword@example.com/');
+ 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%3Aword@example.com/');
});
it('lowercases the required values', function () {
|