diff --git a/index.js b/index.js index 976268b..1954ae1 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,5 @@ 'use strict' -const punycodeRegex = require('punycode-regex')() const urlRegex = require('url-regex-safe') const REGEX_HTTP_PROTOCOL = /^https?:\/\//i @@ -9,12 +8,14 @@ module.exports = url => { try { const { href, hostname, origin, username, password } = new URL(url) if (!REGEX_HTTP_PROTOCOL.test(href) || username || password) return false - const isIPv6 = hostname.startsWith('[') && hostname.endsWith(']') - const isPunycode = punycodeRegex.test(hostname) - // url-regex-safe cannot exact-match IPv6 or punycode authorities. - const exact = !isIPv6 && !isPunycode + // url-regex-safe cannot exact-match IPv6 authorities. + const exact = !(hostname.startsWith('[') && hostname.endsWith(']')) + + // url-regex-safe's TLD list has no xn-- entries, so an IDN TLD has to be + // supplied; an ASCII one stays subject to the built-in public-suffix list. + const tld = hostname.slice(hostname.lastIndexOf('.') + 1) + const tlds = tld.startsWith('xn--') ? [tld] : undefined - const tlds = isPunycode ? [] : undefined const regex = urlRegex({ apostrophes: true, exact, parens: true, tlds }) if (!regex.test(href)) return false diff --git a/package.json b/package.json index c626f25..e6fd44d 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,6 @@ "whatwg" ], "dependencies": { - "punycode-regex": "~1.0.1", "re2": "~1.26.0", "url-regex-safe": "~4.0.0" }, diff --git a/test/index.js b/test/index.js index 183baf0..79b02c6 100644 --- a/test/index.js +++ b/test/index.js @@ -59,7 +59,12 @@ const test = require('ava').default 'http://-kikobeats.com', 'http://internal/https://example.com/#:~:text=x', 'http://metadata/https://example.com/#:~:text=x', - 'http://xn--internal/https://example.com/' + 'http://xn--internal/https://example.com/', + 'https://example.local/', + 'https://xn--e1afmkfd.local/', + 'https://пример.local/', + 'https://xn--80a0aaa.internal/', + 'https://xn--80a0aaa.invalidtld/' ]) ).forEach(input => { const url = httpUrl(input)