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

Commit

Permalink
Rewrite parseUri to handle unusual but valid URI characters.
Browse files Browse the repository at this point in the history
It drops support for the 'directory' and 'file' properties, but should
otherwise be equivalent to the original version.
  • Loading branch information
LeviticusMB committed Oct 10, 2015
1 parent fdb9d05 commit 9feb3f4
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 10 deletions.
23 changes: 13 additions & 10 deletions lib/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -584,20 +584,23 @@ hawk.utils = {
},

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

// Based on: parseURI 1.2.2
// http://blog.stevenlevithan.com/archives/parseuri
// (c) Steven Levithan <stevenlevithan.com>
// MIT License
var parts = uriRegex.exec(input);

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

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

for (var i = 0, il = keys.length; i < il; ++i) {
uri[keys[i]] = uriByNumber[i] || '';
for (i = 0; i < parts.length; ++i) {
uri[authKeys[i]] = parts[i] || '';
}

if (uri.port === '') {
Expand Down
27 changes: 27 additions & 0 deletions test/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -1442,6 +1442,33 @@ describe('Browser', function () {
expect(uri.port).to.equal('80');
done();
});

it('handles unusual characters correctly', function (done) {
var parts = {
protocol: 'http+vnd.my-extension',
user: 'user!$&\'()*+,;=%40my-domain.com',
password: 'pass!$&\'()*+,;=%40:word',
hostname: 'foo-bar.com',
port: '99',
pathname: '/path/%40/!$&\'()*+,;=:@/',
query: 'query%40/!$&\'()*+,;=:@/?',
fragment: 'fragm%40/!$&\'()*+,;=:@/?'
};

parts.userInfo = parts.user + ':' + parts.password;
parts.authority = parts.userInfo + '@' + parts.hostname + ':' + parts.port;
parts.relative = parts.pathname + '?' + parts.query;
parts.resource = parts.relative + '#' + parts.fragment;
parts.source = parts.protocol + '://' + parts.authority + parts.resource;

var uri = Browser.utils.parseUri(parts.source);

for (var part in parts) {
expect(uri[part]).to.equal(parts[part]);
}

done();
});
});

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

0 comments on commit 9feb3f4

Please sign in to comment.