Skip to content
This repository was archived by the owner on Apr 5, 2024. It is now read-only.

Commit 9feb3f4

Browse files
committed
Rewrite parseUri to handle unusual but valid URI characters.
It drops support for the 'directory' and 'file' properties, but should otherwise be equivalent to the original version.
1 parent fdb9d05 commit 9feb3f4

File tree

2 files changed

+40
-10
lines changed

2 files changed

+40
-10
lines changed

lib/browser.js

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -584,20 +584,23 @@ hawk.utils = {
584584
},
585585

586586
parseUri: function (input) {
587+
// From RFC 3986 (except for some groups being non-capturing and two extra groups for 'resource' and 'relative')
588+
var uriRegex = /^(?:([^:\/?#]+):)?(?:\/\/([^\/?#]*))?((([^?#]*)(?:\?([^#]*))?)(?:#(.*))?)/;
589+
var uriKeys = ['source', 'protocol', 'authority', 'resource', 'relative', 'pathname', 'query', 'fragment'];
590+
var authRegex = /^(?:(([^:@]*)(?::([^@]*))?)@)?(\[[^\]]*\]|[^:]*)(?::(\d*))?/;
591+
var authKeys = ['authority', 'userInfo', 'user', 'password', 'hostname', 'port'];
592+
var uri = {}, i;
587593

588-
// Based on: parseURI 1.2.2
589-
// http://blog.stevenlevithan.com/archives/parseuri
590-
// (c) Steven Levithan <stevenlevithan.com>
591-
// MIT License
594+
var parts = uriRegex.exec(input);
592595

593-
var keys = ['source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'hostname', 'port', 'resource', 'relative', 'pathname', 'directory', 'file', 'query', 'fragment'];
596+
for (i = 0; i < parts.length; ++i) {
597+
uri[uriKeys[i]] = parts[i] || '';
598+
}
594599

595-
var uriRegex = /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?(((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?)(?:#(.*))?)/;
596-
var uriByNumber = input.match(uriRegex);
597-
var uri = {};
600+
parts = authRegex.exec(uri['authority']);
598601

599-
for (var i = 0, il = keys.length; i < il; ++i) {
600-
uri[keys[i]] = uriByNumber[i] || '';
602+
for (i = 0; i < parts.length; ++i) {
603+
uri[authKeys[i]] = parts[i] || '';
601604
}
602605

603606
if (uri.port === '') {

test/browser.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,6 +1442,33 @@ describe('Browser', function () {
14421442
expect(uri.port).to.equal('80');
14431443
done();
14441444
});
1445+
1446+
it('handles unusual characters correctly', function (done) {
1447+
var parts = {
1448+
protocol: 'http+vnd.my-extension',
1449+
user: 'user!$&\'()*+,;=%40my-domain.com',
1450+
password: 'pass!$&\'()*+,;=%40:word',
1451+
hostname: 'foo-bar.com',
1452+
port: '99',
1453+
pathname: '/path/%40/!$&\'()*+,;=:@/',
1454+
query: 'query%40/!$&\'()*+,;=:@/?',
1455+
fragment: 'fragm%40/!$&\'()*+,;=:@/?'
1456+
};
1457+
1458+
parts.userInfo = parts.user + ':' + parts.password;
1459+
parts.authority = parts.userInfo + '@' + parts.hostname + ':' + parts.port;
1460+
parts.relative = parts.pathname + '?' + parts.query;
1461+
parts.resource = parts.relative + '#' + parts.fragment;
1462+
parts.source = parts.protocol + '://' + parts.authority + parts.resource;
1463+
1464+
var uri = Browser.utils.parseUri(parts.source);
1465+
1466+
for (var part in parts) {
1467+
expect(uri[part]).to.equal(parts[part]);
1468+
}
1469+
1470+
done();
1471+
});
14451472
});
14461473

14471474
var str = 'https://www.google.ca/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=url';

0 commit comments

Comments
 (0)