@@ -177,7 +177,9 @@ function isIpv6Hostname(hostname) {
177
177
// as IPv6 by isIpv6Hostname above
178
178
//
179
179
// [1]: https://url.spec.whatwg.org/#forbidden-host-code-point
180
- const forbiddenHostChars = / [ \t \n \r # % / : < > ? @ [ \\ \] ^ | ] / ;
180
+ const forbiddenHostChars = / [ \0 \t \n \r # % / : < > ? @ [ \\ \] ^ | ] / ;
181
+ // For IPv6, permit '[', ']', and ':'.
182
+ const forbiddenHostCharsIpv6 = / [ \0 \t \n \r # % / < > ? @ \\ ^ | ] / ;
181
183
182
184
Url . prototype . parse = function parse ( url , parseQueryString , slashesDenoteHost ) {
183
185
validateString ( url , 'url' ) ;
@@ -400,27 +402,33 @@ Url.prototype.parse = function parse(url, parseQueryString, slashesDenoteHost) {
400
402
this . hostname = this . hostname . toLowerCase ( ) ;
401
403
}
402
404
403
- if ( ! ipv6Hostname && this . hostname !== '' ) {
404
- // IDNA Support: Returns a punycoded representation of "domain".
405
- // It only converts parts of the domain name that
406
- // have non-ASCII characters, i.e. it doesn't matter if
407
- // you call it with a domain that already is ASCII-only.
408
-
409
- // Use lenient mode (`true`) to try to support even non-compliant
410
- // URLs.
411
- this . hostname = toASCII ( this . hostname , true ) ;
412
-
413
- // Prevent two potential routes of hostname spoofing.
414
- // 1. If this.hostname is empty, it must have become empty due to toASCII
415
- // since we checked this.hostname above.
416
- // 2. If any of forbiddenHostChars appears in this.hostname, it must have
417
- // also gotten in due to toASCII. This is since getHostname would have
418
- // filtered them out otherwise.
419
- // Rather than trying to correct this by moving the non-host part into
420
- // the pathname as we've done in getHostname, throw an exception to
421
- // convey the severity of this issue.
422
- if ( this . hostname === '' || forbiddenHostChars . test ( this . hostname ) ) {
423
- throw new ERR_INVALID_URL ( url ) ;
405
+ if ( this . hostname !== '' ) {
406
+ if ( ipv6Hostname ) {
407
+ if ( forbiddenHostCharsIpv6 . test ( this . hostname ) ) {
408
+ throw new ERR_INVALID_URL ( url ) ;
409
+ }
410
+ } else {
411
+ // IDNA Support: Returns a punycoded representation of "domain".
412
+ // It only converts parts of the domain name that
413
+ // have non-ASCII characters, i.e. it doesn't matter if
414
+ // you call it with a domain that already is ASCII-only.
415
+
416
+ // Use lenient mode (`true`) to try to support even non-compliant
417
+ // URLs.
418
+ this . hostname = toASCII ( this . hostname , true ) ;
419
+
420
+ // Prevent two potential routes of hostname spoofing.
421
+ // 1. If this.hostname is empty, it must have become empty due to toASCII
422
+ // since we checked this.hostname above.
423
+ // 2. If any of forbiddenHostChars appears in this.hostname, it must have
424
+ // also gotten in due to toASCII. This is since getHostname would have
425
+ // filtered them out otherwise.
426
+ // Rather than trying to correct this by moving the non-host part into
427
+ // the pathname as we've done in getHostname, throw an exception to
428
+ // convey the severity of this issue.
429
+ if ( this . hostname === '' || forbiddenHostChars . test ( this . hostname ) ) {
430
+ throw new ERR_INVALID_URL ( url ) ;
431
+ }
424
432
}
425
433
}
426
434
0 commit comments