-
Notifications
You must be signed in to change notification settings - Fork 476
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make constructor throw on invalid ports. #345
Changes from 4 commits
362513b
dd6846b
7bfb89e
520d29d
a90bbec
dd40ca7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -243,7 +243,7 @@ | |
// allowed hostname characters according to RFC 3986 | ||
// ALPHA DIGIT "-" "." "_" "~" "!" "$" "&" "'" "(" ")" "*" "+" "," ";" "=" %encoded | ||
// I've never seen a (non-IDN) hostname other than: ALPHA DIGIT . - | ||
URI.invalid_hostname_characters = /[^a-zA-Z0-9\.-]/; | ||
URI.invalid_hostname_characters = /[^a-zA-Z0-9\.\-:]/; | ||
// map DOM Elements to their URI attribute | ||
URI.domAttributes = { | ||
'a': 'href', | ||
|
@@ -524,6 +524,8 @@ | |
// what's left must be the path | ||
parts.path = string; | ||
|
||
URI.basicValidation(parts); | ||
|
||
// and we're done | ||
return parts; | ||
}; | ||
|
@@ -575,6 +577,14 @@ | |
string = '/' + string; | ||
} | ||
|
||
if (parts.hostname) { | ||
URI.ensureValidHostname(parts.hostname); | ||
} | ||
|
||
if (parts.port) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this change should be covered by a test for the constructor ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added a negative and a positive test, one for each case. Is that enough? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think we need a positive test case, there are plenty of those :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, I've removed the positive testcase, improved the port validation code and 3 negative tests in total. |
||
URI.ensureValidPort(parts.port); | ||
} | ||
|
||
return string.substring(pos) || '/'; | ||
}; | ||
URI.parseAuthority = function(string, parts) { | ||
|
@@ -1024,11 +1034,41 @@ | |
if (!punycode) { | ||
throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.-] and Punycode.js is not available'); | ||
} | ||
|
||
if (punycode.toASCII(v).match(URI.invalid_hostname_characters)) { | ||
throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.-]'); | ||
throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.:-]'); | ||
} | ||
} | ||
}; | ||
|
||
URI.ensureValidPort = function(v) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could be simplified to URI.ensureValidPort = function(v) {
if (!v) {
return;
}
var port = Number(v);
if (Number.isInteger(port) && (port > 0) && (port < 65536)) {
return;
}
throw new TypeError('Port "' + v + '" is not a valid port');
}; There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
var valid = false; | ||
|
||
if (!v || !v.length) { | ||
// no custom port specified | ||
valid = true; | ||
} else { | ||
var port = Number(v); | ||
|
||
// verify type and range | ||
if (Number.isInteger(port) && (port > 0) && (port < 65536) | ||
) { | ||
valid = true; | ||
} | ||
} | ||
|
||
if (!valid) { | ||
throw new TypeError('Port "' + v + '" is not a valid port'); | ||
} | ||
}; | ||
|
||
URI.basicValidation = function(parts) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should this be called There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I put it here because I just wanted to prevent "http:///" being a valid input for the constructor. Since I am not only checking the hostname, but also protocol and path I extracted it into it's own function. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is not limited to HTTP/S, but also applies to ssh, ftp, and many more. Maybe we should create There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are you suggesting to reject all URLs of the form There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sorry for the delay… no, I'm suggesting putting the protocols for which we require a hostname into a map on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @rodneyrehm What do you think, is this ready to merge? |
||
var hasProtocol = !!parts.protocol; // not null and not empty an empty string | ||
var isHttpOrHttps = hasProtocol && (parts.protocol.indexOf('http') !== -1); | ||
var hasHostname = !!parts.hostname; // not null and not an empty string | ||
|
||
if (isHttpOrHttps && !hasHostname) { | ||
throw new TypeError('Hostname cannot be empty, if protocol is http(s)'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is true of any protocol, even the empty protocol There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've updated the code, because apparently my single negation was wrong anyways. |
||
} | ||
}; | ||
|
||
// noConflict | ||
|
@@ -1288,9 +1328,7 @@ | |
v = v.substring(1); | ||
} | ||
|
||
if (v.match(/[^0-9]/)) { | ||
throw new TypeError('Port "' + v + '" contains characters other than [0-9]'); | ||
} | ||
URI.ensureValidPort(v); | ||
} | ||
} | ||
return _port.call(this, v, build); | ||
|
@@ -1426,6 +1464,10 @@ | |
v += '.'; | ||
} | ||
|
||
if (v.indexOf(':') !== -1) { | ||
throw new TypeError('Domains cannot contain colons'); | ||
} | ||
|
||
if (v) { | ||
URI.ensureValidHostname(v); | ||
} | ||
|
@@ -1466,6 +1508,10 @@ | |
throw new TypeError('cannot set domain empty'); | ||
} | ||
|
||
if (v.indexOf(':') !== -1) { | ||
throw new TypeError('Domains cannot contain colons'); | ||
} | ||
|
||
URI.ensureValidHostname(v); | ||
|
||
if (!this._parts.hostname || this.is('IP')) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The validation should probably be done in
URI.parseHost()
? maybeURI#hostname()
's validation can be moved there, too?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've created and called the method this way because I wanted to put some validation there that isn't just about a specific part of the url but about a combination such as protocol, hostname, path.