From 2aff77f358909e36181e2b27b0b5c62027bd7602 Mon Sep 17 00:00:00 2001 From: ZiJian Liu Date: Mon, 28 Dec 2020 23:42:33 +0800 Subject: [PATCH] url: fix url.format with ipv6 hostname Fixes: https://github.com/nodejs/node/issues/36654 PR-URL: https://github.com/nodejs/node/pull/36665 Reviewed-By: Luigi Pinca Reviewed-By: Robert Nagy Reviewed-By: Rich Trott Reviewed-By: Daijiro Wachi Reviewed-By: Yash Ladha --- lib/url.js | 14 +++++++++++--- test/parallel/test-url-format.js | 6 ++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/lib/url.js b/lib/url.js index cc36216f9eb916..49f99a8b5fa621 100644 --- a/lib/url.js +++ b/lib/url.js @@ -26,6 +26,7 @@ const { ObjectCreate, ObjectKeys, SafeSet, + StringPrototypeCharCodeAt, } = primordials; const { toASCII } = require('internal/idna'); @@ -156,6 +157,14 @@ function urlParse(url, parseQueryString, slashesDenoteHost) { return urlObject; } +function isIpv6Hostname(hostname) { + return ( + StringPrototypeCharCodeAt(hostname, 0) === CHAR_LEFT_SQUARE_BRACKET && + StringPrototypeCharCodeAt(hostname, hostname.length - 1) === + CHAR_RIGHT_SQUARE_BRACKET + ); +} + Url.prototype.parse = function parse(url, parseQueryString, slashesDenoteHost) { validateString(url, 'url'); @@ -364,8 +373,7 @@ Url.prototype.parse = function parse(url, parseQueryString, slashesDenoteHost) { // If hostname begins with [ and ends with ] // assume that it's an IPv6 address. - const ipv6Hostname = hostname.charCodeAt(0) === CHAR_LEFT_SQUARE_BRACKET && - hostname.charCodeAt(hostname.length - 1) === CHAR_RIGHT_SQUARE_BRACKET; + const ipv6Hostname = isIpv6Hostname(hostname); // validate a little. if (!ipv6Hostname) { @@ -590,7 +598,7 @@ Url.prototype.format = function format() { host = auth + this.host; } else if (this.hostname) { host = auth + ( - this.hostname.includes(':') ? + this.hostname.includes(':') && !isIpv6Hostname(this.hostname) ? '[' + this.hostname + ']' : this.hostname ); diff --git a/test/parallel/test-url-format.js b/test/parallel/test-url-format.js index 2d0132eb38a0bb..720a10a97a979b 100644 --- a/test/parallel/test-url-format.js +++ b/test/parallel/test-url-format.js @@ -148,6 +148,12 @@ const formatTests = { host: '[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:61616', pathname: '/s/stopButton' }, + 'http://[::]/': { + href: 'http://[::]/', + protocol: 'http:', + hostname: '[::]', + pathname: '/' + }, // Encode context-specific delimiters in path and query, but do not touch // other non-delimiter chars like `%`.