diff --git a/src/jsc/bindings/NodeURL.cpp b/src/jsc/bindings/NodeURL.cpp index 09af0674a4e..7218b764c42 100644 --- a/src/jsc/bindings/NodeURL.cpp +++ b/src/jsc/bindings/NodeURL.cpp @@ -117,11 +117,8 @@ JSC_DEFINE_HOST_FUNCTION(jsDomainToUnicode, (JSC::JSGlobalObject * globalObject, ) return JSC::JSValue::encode(jsEmptyString(vm)); - if (!domain.is8Bit()) - // this function is only for undoing punycode so its okay if utf-16 text makes it out unchanged. - return JSC::JSValue::encode(arg0); - - domain.convertTo16Bit(); + if (domain.is8Bit()) + domain.convertTo16Bit(); constexpr static int allowedNameToUnicodeErrors = UIDNA_ERROR_EMPTY_LABEL | UIDNA_ERROR_LABEL_TOO_LONG | UIDNA_ERROR_DOMAIN_NAME_TOO_LONG | UIDNA_ERROR_LEADING_HYPHEN | UIDNA_ERROR_TRAILING_HYPHEN | UIDNA_ERROR_HYPHEN_3_4; constexpr static int hostnameBufferLength = 2048; diff --git a/test/js/node/url/url-domain-ascii-unicode.test.js b/test/js/node/url/url-domain-ascii-unicode.test.js index d46b30f8c2e..5fe3f0dfa27 100644 --- a/test/js/node/url/url-domain-ascii-unicode.test.js +++ b/test/js/node/url/url-domain-ascii-unicode.test.js @@ -98,4 +98,34 @@ describe("url.domainToUnicode", () => { expect(url.domainToASCII(input)).toEqual(expected); }); } + + // The result must depend only on the string's value, not on whether JSC + // happened to back it with an 8-bit or 16-bit buffer. + test("does not depend on the string's internal representation", () => { + const eight = "xn--bcher-kva.de"; + const sixteen = "xn--bcher-kva.de\u4e2d".slice(0, -1); + expect(sixteen).toBe(eight); + expect({ + eight: url.domainToUnicode(eight), + sixteen: url.domainToUnicode(sixteen), + }).toEqual({ + eight: "bücher.de", + sixteen: "bücher.de", + }); + }); + + test("round-trips through domainToASCII", () => { + for (const [domain] of pairs) { + expect(url.domainToUnicode(url.domainToASCII(domain))).toBe(domain); + } + }); + + test("decodes A-labels that appear alongside non-Latin-1 labels", () => { + expect(url.domainToUnicode("中.xn--fiqs8s")).toBe("中.中国"); + expect(url.domainToUnicode("пример.xn--p1ai")).toBe("пример.рф"); + }); + + test("applies UTS #46 mapping to non-Latin-1 input", () => { + expect(url.domainToUnicode("\ufb00.COM")).toBe("ff.com"); + }); });