Skip to content

Commit

Permalink
fix(parse): add URI.preventInvalidHostname to make hostname validatio…
Browse files Browse the repository at this point in the history
…n optional - #345, 352, #354, #355
  • Loading branch information
rodneyrehm committed Oct 1, 2017
1 parent 29ab103 commit d1cedf2
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 13 deletions.
42 changes: 31 additions & 11 deletions src/URI.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,15 @@
query: null,
fragment: null,
// state
preventInvalidHostname: URI.preventInvalidHostname,
duplicateQueryParameters: URI.duplicateQueryParameters,
escapeQuerySpace: URI.escapeQuerySpace
};
};
// state: throw on invalid hostname
// see https://github.com/medialize/URI.js/pull/345
// and https://github.com/medialize/URI.js/issues/354
URI.preventInvalidHostname = false;
// state: allow duplicate query parameters (a=1&a=1)
URI.duplicateQueryParameters = false;
// state: replaces + with %20 (space in query strings)
Expand Down Expand Up @@ -485,7 +490,9 @@
URI.parse = function(string, parts) {
var pos;
if (!parts) {
parts = {};
parts = {
preventInvalidHostname: URI.preventInvalidHostname
};
}
// [protocol"://"[username[":"password]"@"]hostname[":"port]"/"?][path]["?"querystring]["#"fragment]

Expand Down Expand Up @@ -538,6 +545,10 @@
return parts;
};
URI.parseHost = function(string, parts) {
if (!string) {
string = '';
}

// Copy chrome, IE, opera backslash-handling behavior.
// Back slashes before the query string get converted to forward slashes
// See: https://github.com/joyent/node/blob/386fd24f49b0e9d1a8a076592a404168faeecc34/lib/url.js#L115-L124
Expand Down Expand Up @@ -585,7 +596,9 @@
string = '/' + string;
}

URI.ensureValidHostname(parts.hostname, parts.protocol);
if (parts.preventInvalidHostname) {
URI.ensureValidHostname(parts.hostname, parts.protocol);
}

if (parts.port) {
URI.ensureValidPort(parts.port);
Expand Down Expand Up @@ -1312,16 +1325,15 @@
var _hostname = p.hostname;

p.protocol = function(v, build) {
if (v !== undefined) {
if (v) {
// accept trailing ://
v = v.replace(/:(\/\/)?$/, '');
if (v) {
// accept trailing ://
v = v.replace(/:(\/\/)?$/, '');

if (!v.match(URI.protocol_expression)) {
throw new TypeError('Protocol "' + v + '" contains characters other than [A-Z0-9.+-] or doesn\'t start with [A-Z]');
}
if (!v.match(URI.protocol_expression)) {
throw new TypeError('Protocol "' + v + '" contains characters other than [A-Z0-9.+-] or doesn\'t start with [A-Z]');
}
}

return _protocol.call(this, v, build);
};
p.scheme = p.protocol;
Expand Down Expand Up @@ -1352,15 +1364,18 @@
}

if (v !== undefined) {
var x = {};
var x = { preventInvalidHostname: this._parts.preventInvalidHostname };
var res = URI.parseHost(v, x);
if (res !== '/') {
throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.-]');
}

v = x.hostname;
URI.ensureValidHostname(v, this._parts.protocol);
if (this._parts.preventInvalidHostname) {
URI.ensureValidHostname(v, this._parts.protocol);
}
}

return _hostname.call(this, v, build);
};

Expand Down Expand Up @@ -2300,6 +2315,11 @@
};

// state
p.preventInvalidHostname = function(v) {
this._parts.preventInvalidHostname = !!v;
return this;
};

p.duplicateQueryParameters = function(v) {
this._parts.duplicateQueryParameters = !!v;
return this;
Expand Down
14 changes: 14 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,15 @@
}, TypeError, "throws TypeError");
});
test('function URI(string) with protocol and without hostname should throw', function () {
new URI('http://');

URI.preventInvalidHostname = true;
raises(function () {
new URI('http://');
}, TypeError, "throws TypeError");

URI.preventInvalidHostname = false;
new URI('http://');
});
test('new URI(string, string)', function() {
// see http://dvcs.w3.org/hg/url/raw-file/tip/Overview.html#constructor
Expand Down Expand Up @@ -251,9 +257,17 @@
u.hostname('foo\\bar.com');
}, TypeError, 'Failing backslash detection in hostname');

// instance does not fall back to global setting
URI.preventInvalidHostname = true;
u.hostname('');
u.hostname(null);
URI.preventInvalidHostname = false;

u.preventInvalidHostname(true);
raises(function() {
u.hostname('');
}, TypeError, "Trying to set an empty hostname with http(s) protocol throws a TypeError");

raises(function() {
u.hostname(null);
}, TypeError, "Trying to set hostname to null with http(s) protocol throws a TypeError");
Expand Down
4 changes: 2 additions & 2 deletions test/test_jim.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@
domain = "com";
for (j=0; j<3; j++) {
//start new subdomain
domain = "." + domain;
domain = "." + domain;
for (i=0; i<70; i++) {
domain = "a" + domain;
}
Expand All @@ -155,4 +155,4 @@
equals(u.hostname() == domain, true, "set domain() with 70-character subdomain not valid domainname");
});
*/
})();
})();

0 comments on commit d1cedf2

Please sign in to comment.