Skip to content

Commit 09cd52e

Browse files
authored
Fix useSTD3ASCIIRules regression, with tests
Closes #69.
1 parent a034468 commit 09cd52e

File tree

2 files changed

+100
-1
lines changed

2 files changed

+100
-1
lines changed

index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ function validateLabel(label, {
132132
// be a lowercase letter (a-z), a digit (0-9), or a hyphen-minus (U+002D). (Note: This excludes uppercase ASCII
133133
// A-Z which are mapped in UTS #46 and disallowed in IDNA2008.)"
134134
if (useSTD3ASCIIRules && codePoint <= 0x7F) {
135-
if (!/^[a-z][0-9]-$/u.test(ch)) {
135+
if (!/^(?:[a-z]|[0-9]|-)$/u.test(ch)) {
136136
return false;
137137
}
138138
}

test/std3ASCIIRules.js

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
"use strict";
2+
const { describe, test } = require("node:test");
3+
const assert = require("assert");
4+
const tr46 = require("../index.js");
5+
6+
function testToASCIIWithSTD3ASCIIRules(testCase) {
7+
const result = tr46.toASCII(testCase.input, {
8+
checkBidi: false,
9+
checkHyphens: false,
10+
checkJoiners: false,
11+
useSTD3ASCIIRules: true,
12+
verifyDNSLength: false
13+
});
14+
15+
assert.strictEqual(result, testCase.output);
16+
}
17+
18+
describe("ToASCII with useSTD3ASCIIRules = true", () => {
19+
const testCases = [];
20+
21+
// Add test cases for valid characters
22+
const alphabet = "abcdefghijklmnopqrstuvwxyz";
23+
const digits = "0123456789";
24+
const hyphen = "-";
25+
const allowedChars = alphabet + digits + hyphen;
26+
for (const char of allowedChars) {
27+
testCases.push({
28+
input: char,
29+
output: char,
30+
comment: "STD3 range"
31+
});
32+
}
33+
34+
// Add not supported ascii characters
35+
for (let i = 0; i < 128; i++) {
36+
const char = String.fromCharCode(i);
37+
if (allowedChars.includes(char)) {
38+
continue;
39+
}
40+
41+
// Upper-case letters are converted to lower case, so we we exclude them from a negative test case
42+
if (allowedChars.includes(char.toLowerCase())) {
43+
continue;
44+
}
45+
46+
// Dot is exclude from negative test cases, since it is allowed in domain names
47+
if (char === ".") {
48+
continue;
49+
}
50+
51+
testCases.push({
52+
input: char,
53+
output: null,
54+
comment: "Outside of STD3 range"
55+
});
56+
}
57+
58+
// Add a unicode character, since it should be converted to punycode
59+
testCases.push({
60+
input: "é",
61+
output: "xn--9ca",
62+
comment: "Unicode"
63+
});
64+
65+
// Additional test cases, with mixed valid and invalid characters
66+
testCases.push({
67+
input: "inv@alid",
68+
output: null,
69+
comment: "Invalid label"
70+
});
71+
testCases.push({
72+
input: "valid",
73+
output: "valid",
74+
comment: "Valid label"
75+
});
76+
testCases.push({
77+
input: "unicodé",
78+
output: "xn--unicod-gva",
79+
comment: "Valid uncode label"
80+
});
81+
testCases.push({
82+
input: "uni!codé",
83+
output: null,
84+
comment: "Invalid uncode label"
85+
});
86+
87+
for (const testCase of testCases) {
88+
let description = testCase.input;
89+
90+
if (testCase.comment) {
91+
description += ` (${testCase.comment})`;
92+
}
93+
94+
test(description, () => {
95+
testToASCIIWithSTD3ASCIIRules(testCase);
96+
});
97+
}
98+
});
99+

0 commit comments

Comments
 (0)