diff options
author | Nathan Whitaker <17734409+nathanwhit@users.noreply.github.com> | 2024-03-11 15:49:43 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-11 15:49:43 -0700 |
commit | a77b2987bc90879af30a39ba274df9061cc7fbae (patch) | |
tree | ad7463374e66eb3aa61e41d96c512e67e717e349 /ext/node/polyfills/url.ts | |
parent | d69aab62b0789dd54b8c09b54af022a38f060b5b (diff) |
fix(ext/node): Match punycode module behavior to node (#22847)
Fixes #19214.
We were using the `idna` crate to implement our polyfill for
`punycode.toASCII` and `punycode.toUnicode`. The `idna` crate is
correct, and adheres to the IDNA2003/2008 spec, but it turns out
`node`'s implementations don't really follow any spec! Instead, node
splits the domain by `'.'` and punycode encodes/decodes each part. This
means that node's implementations will happily work on codepoints that
are disallowed by the IDNA specs, causing the error in #19214.
While fixing this, I went ahead and matched the node behavior on all of
the punycode functions and enabled node's punycode test in our
`node_compat` suite.
Diffstat (limited to 'ext/node/polyfills/url.ts')
-rw-r--r-- | ext/node/polyfills/url.ts | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/ext/node/polyfills/url.ts b/ext/node/polyfills/url.ts index 14195d146..6633334ba 100644 --- a/ext/node/polyfills/url.ts +++ b/ext/node/polyfills/url.ts @@ -70,7 +70,10 @@ import { CHAR_ZERO_WIDTH_NOBREAK_SPACE, } from "ext:deno_node/path/_constants.ts"; import * as path from "node:path"; -import { toASCII, toUnicode } from "node:punycode"; +import { + domainToASCII as idnaToASCII, + domainToUnicode as idnaToUnicode, +} from "ext:deno_node/internal/idna.ts"; import { isWindows, osType } from "ext:deno_node/_util/os.ts"; import { encodeStr, hexTable } from "ext:deno_node/internal/querystring.ts"; import querystring from "node:querystring"; @@ -813,7 +816,7 @@ export class Url { // Use lenient mode (`true`) to try to support even non-compliant // URLs. - this.hostname = toASCII(this.hostname); + this.hostname = idnaToASCII(this.hostname); // Prevent two potential routes of hostname spoofing. // 1. If this.hostname is empty, it must have become empty due to toASCII @@ -1251,7 +1254,7 @@ export function resolveObject(source: string | Url, relative: string) { * @see https://www.rfc-editor.org/rfc/rfc3490#section-4 */ export function domainToASCII(domain: string) { - return toASCII(domain); + return idnaToASCII(domain); } /** @@ -1261,7 +1264,7 @@ export function domainToASCII(domain: string) { * @see https://www.rfc-editor.org/rfc/rfc3490#section-4 */ export function domainToUnicode(domain: string) { - return toUnicode(domain); + return idnaToUnicode(domain); } /** @@ -1396,7 +1399,7 @@ export function pathToFileURL(filepath: string): URL { ); } - outURL.hostname = domainToASCII(hostname); + outURL.hostname = idnaToASCII(hostname); outURL.pathname = encodePathChars(paths.slice(3).join("/")); } else { let resolved = path.resolve(filepath); |