From 6e8c4e004aac9a181950430e4b02c57eee7aad05 Mon Sep 17 00:00:00 2001 From: uzlopak Date: Sun, 30 Jul 2023 18:32:13 +0200 Subject: [PATCH 1/2] perf: avoid domainToAscii on pure cases --- index.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index c9b69dd..553ed4b 100644 --- a/index.js +++ b/index.js @@ -178,6 +178,8 @@ function serialize (cmpts, opts) { return uriTokens.join('') } +const NON_ASCII_HOST = /[^!"$&'()*+,.;=_`a-z{}~-]/ + const URI_PARSE = /^(?:([^:/?#]+):)?(?:\/\/((?:([^/?#@]*)@)?(\[[^/?#\]]+\]|[^/?#:]*)(?::(\d*))?))?([^?#]*)(?:\?([^#]*))?(?:#((?:.|\n|\r)*))?/i function parse (uri, opts) { @@ -239,7 +241,7 @@ function parse (uri, opts) { // check if scheme can't handle IRIs if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport)) { // if host component is a domain name - if (parsed.host && (options.domainHost || (schemeHandler && schemeHandler.domainHost))) { + if (parsed.host && (options.domainHost || (schemeHandler && schemeHandler.domainHost)) && NON_ASCII_HOST.test(parsed.host)) { // convert Unicode IDN -> ASCII IDN try { parsed.host = URL.domainToASCII(parsed.host.toLowerCase()) From 92f7e8883ac6b93ecdff6db7295280127176b45a Mon Sep 17 00:00:00 2001 From: uzlopak Date: Tue, 15 Aug 2023 13:24:30 +0200 Subject: [PATCH 2/2] use fn instead of re --- index.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 553ed4b..873041a 100644 --- a/index.js +++ b/index.js @@ -178,7 +178,18 @@ function serialize (cmpts, opts) { return uriTokens.join('') } -const NON_ASCII_HOST = /[^!"$&'()*+,.;=_`a-z{}~-]/ +const hexLookUp = Array.from({ length: 127 }, (v, k) => /[^!"$&'()*+,.;=_`a-z{}~-]/.test(String.fromCharCode(k))) + +function nonSimpleDomain (value) { + let code = 0 + for (let i = 0, len = value.length; i < len; ++i) { + code = value.charCodeAt(i) + if (code > 126 || hexLookUp[code]) { + return true + } + } + return false +} const URI_PARSE = /^(?:([^:/?#]+):)?(?:\/\/((?:([^/?#@]*)@)?(\[[^/?#\]]+\]|[^/?#:]*)(?::(\d*))?))?([^?#]*)(?:\?([^#]*))?(?:#((?:.|\n|\r)*))?/i @@ -241,7 +252,7 @@ function parse (uri, opts) { // check if scheme can't handle IRIs if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport)) { // if host component is a domain name - if (parsed.host && (options.domainHost || (schemeHandler && schemeHandler.domainHost)) && NON_ASCII_HOST.test(parsed.host)) { + if (parsed.host && (options.domainHost || (schemeHandler && schemeHandler.domainHost)) && nonSimpleDomain(parsed.host)) { // convert Unicode IDN -> ASCII IDN try { parsed.host = URL.domainToASCII(parsed.host.toLowerCase())