Skip to content

Commit 39f050a

Browse files
Conform encoding-label matching to Encoding spec
This change makes the parser’s encoding-name matching conform to the current Encoding spec at https://encoding.spec.whatwg.org/#concept-encoding-get — which requires that only leading and trailing whitespace be removed from a string before checking if it matches any valid encoding name. Otherwise, without this change, the parser instead implements https://www.unicode.org/reports/tr22/tr22-8.html#Charset_Alias_Matching — which requires deleting “all characters except a-z, A-Z, and 0-9” from a string before checking if it matches any valid encoding name. That difference makes us fail two html5-tests cases. Relates to #47
1 parent 3f48926 commit 39f050a

File tree

1 file changed

+250
-14
lines changed

1 file changed

+250
-14
lines changed

src/nu/validator/htmlparser/io/Encoding.java

+250-14
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,238 @@ public class Encoding {
6464
"xutf32lebom", "xutf16oppositeendian", "xutf16platformendian",
6565
"xutf32oppositeendian", "xutf32platformendian" };
6666

67-
private static String[] NOT_OBSCURE = { "big5", "big5hkscs", "eucjp",
68-
"euckr", "gb18030", "gbk", "iso2022jp", "iso2022kr", "iso88591",
69-
"iso885913", "iso885915", "iso88592", "iso88593", "iso88594",
70-
"iso88595", "iso88596", "iso88597", "iso88598", "iso88599",
71-
"koi8r", "shiftjis", "tis620", "usascii", "utf16", "utf16be",
72-
"utf16le", "utf8", "windows1250", "windows1251", "windows1252",
73-
"windows1253", "windows1254", "windows1255", "windows1256",
74-
"windows1257", "windows1258" };
75-
67+
/* From the table at https://encoding.spec.whatwg.org/#names-and-labels,
68+
* everything in the Labels column, sorted */
69+
private static String[] NOT_OBSCURE = { //
70+
"866", //
71+
"ansi_x3.4-1968", //
72+
"arabic", //
73+
"ascii", //
74+
"asmo-708", //
75+
"big5", //
76+
"big5-hkscs", //
77+
"chinese", //
78+
"cn-big5", //
79+
"cp1250", //
80+
"cp1251", //
81+
"cp1252", //
82+
"cp1253", //
83+
"cp1254", //
84+
"cp1255", //
85+
"cp1256", //
86+
"cp1257", //
87+
"cp1258", //
88+
"cp819", //
89+
"cp866", //
90+
"csbig5", //
91+
"cseuckr", //
92+
"cseucpkdfmtjapanese", //
93+
"csgb2312", //
94+
"csibm866", //
95+
"csiso2022jp", //
96+
"csiso2022kr", //
97+
"csiso58gb231280", //
98+
"csiso88596e", //
99+
"csiso88596i", //
100+
"csiso88598e", //
101+
"csiso88598i", //
102+
"csisolatin1", //
103+
"csisolatin2", //
104+
"csisolatin3", //
105+
"csisolatin4", //
106+
"csisolatin5", //
107+
"csisolatin6", //
108+
"csisolatin9", //
109+
"csisolatinarabic", //
110+
"csisolatincyrillic", //
111+
"csisolatingreek", //
112+
"csisolatinhebrew", //
113+
"cskoi8r", //
114+
"csksc56011987", //
115+
"csmacintosh", //
116+
"csshiftjis", //
117+
"csunicode", //
118+
"cyrillic", //
119+
"dos-874", //
120+
"ecma-114", //
121+
"ecma-118", //
122+
"elot_928", //
123+
"euc-jp", //
124+
"euc-kr", //
125+
"gb18030", //
126+
"gb2312", //
127+
"gb_2312", //
128+
"gb_2312-80", //
129+
"gbk", //
130+
"greek", //
131+
"greek8", //
132+
"hebrew", //
133+
"hz-gb-2312", //
134+
"ibm819", //
135+
"ibm866", //
136+
"iso-10646-ucs-2", //
137+
"iso-2022-cn", //
138+
"iso-2022-cn-ext", //
139+
"iso-2022-jp", //
140+
"iso-2022-kr", //
141+
"iso-8859-1", //
142+
"iso-8859-10", //
143+
"iso-8859-11", //
144+
"iso-8859-13", //
145+
"iso-8859-14", //
146+
"iso-8859-15", //
147+
"iso-8859-16", //
148+
"iso-8859-2", //
149+
"iso-8859-3", //
150+
"iso-8859-4", //
151+
"iso-8859-5", //
152+
"iso-8859-6", //
153+
"iso-8859-6-e", //
154+
"iso-8859-6-i", //
155+
"iso-8859-7", //
156+
"iso-8859-8", //
157+
"iso-8859-8-e", //
158+
"iso-8859-8-i", //
159+
"iso-8859-9", //
160+
"iso-ir-100", //
161+
"iso-ir-101", //
162+
"iso-ir-109", //
163+
"iso-ir-110", //
164+
"iso-ir-126", //
165+
"iso-ir-127", //
166+
"iso-ir-138", //
167+
"iso-ir-144", //
168+
"iso-ir-148", //
169+
"iso-ir-149", //
170+
"iso-ir-157", //
171+
"iso-ir-58", //
172+
"iso8859-1", //
173+
"iso8859-10", //
174+
"iso8859-11", //
175+
"iso8859-13", //
176+
"iso8859-14", //
177+
"iso8859-15", //
178+
"iso8859-2", //
179+
"iso8859-3", //
180+
"iso8859-4", //
181+
"iso8859-5", //
182+
"iso8859-6", //
183+
"iso8859-7", //
184+
"iso8859-8", //
185+
"iso8859-9", //
186+
"iso88591", //
187+
"iso885910", //
188+
"iso885911", //
189+
"iso885913", //
190+
"iso885914", //
191+
"iso885915", //
192+
"iso88592", //
193+
"iso88593", //
194+
"iso88594", //
195+
"iso88595", //
196+
"iso88596", //
197+
"iso88597", //
198+
"iso88598", //
199+
"iso88599", //
200+
"iso_8859-1", //
201+
"iso_8859-15", //
202+
"iso_8859-1:1987", //
203+
"iso_8859-2", //
204+
"iso_8859-2:1987", //
205+
"iso_8859-3", //
206+
"iso_8859-3:1988", //
207+
"iso_8859-4", //
208+
"iso_8859-4:1988", //
209+
"iso_8859-5", //
210+
"iso_8859-5:1988", //
211+
"iso_8859-6", //
212+
"iso_8859-6:1987", //
213+
"iso_8859-7", //
214+
"iso_8859-7:1987", //
215+
"iso_8859-8", //
216+
"iso_8859-8:1988", //
217+
"iso_8859-9", //
218+
"iso_8859-9:1989", //
219+
"koi", //
220+
"koi8", //
221+
"koi8-r", //
222+
"koi8-ru", //
223+
"koi8-u", //
224+
"koi8_r", //
225+
"korean", //
226+
"ks_c_5601-1987", //
227+
"ks_c_5601-1989", //
228+
"ksc5601", //
229+
"ksc_5601", //
230+
"l1", //
231+
"l2", //
232+
"l3", //
233+
"l4", //
234+
"l5", //
235+
"l6", //
236+
"l9", //
237+
"latin1", //
238+
"latin2", //
239+
"latin3", //
240+
"latin4", //
241+
"latin5", //
242+
"latin6", //
243+
"logical", //
244+
"mac", //
245+
"macintosh", //
246+
"ms932", //
247+
"ms_kanji", //
248+
"replacement", //
249+
"shift-jis", //
250+
"shift_jis", //
251+
"sjis", //
252+
"sun_eu_greek", //
253+
"tis-620", //
254+
"ucs-2", //
255+
"unicode", //
256+
"unicode-1-1-utf-8", //
257+
"unicode11utf8", //
258+
"unicode20utf8", //
259+
"unicodefeff", //
260+
"unicodefffe", //
261+
"us-ascii", //
262+
"utf-16", //
263+
"utf-16be", //
264+
"utf-16le", //
265+
"utf-8", //
266+
"utf8", //
267+
"visual", //
268+
"windows-1250", //
269+
"windows-1251", //
270+
"windows-1252", //
271+
"windows-1253", //
272+
"windows-1254", //
273+
"windows-1255", //
274+
"windows-1256", //
275+
"windows-1257", //
276+
"windows-1258", //
277+
"windows-31j", //
278+
"windows-874", //
279+
"windows-949", //
280+
"x-cp1250", //
281+
"x-cp1251", //
282+
"x-cp1252", //
283+
"x-cp1253", //
284+
"x-cp1254", //
285+
"x-cp1255", //
286+
"x-cp1256", //
287+
"x-cp1257", //
288+
"x-cp1258", //
289+
"x-euc-jp", //
290+
"x-gbk", //
291+
"x-mac-cyrillic", //
292+
"x-mac-roman", //
293+
"x-mac-ukrainian", //
294+
"x-sjis", //
295+
"x-unicode20utf8", //
296+
"x-user-defined", //
297+
"x-x-big5", //
298+
};
76299
private static Map<String, Encoding> encodingByCookedName = new HashMap<String, Encoding>();
77300

78301
private final String canonName;
@@ -106,11 +329,12 @@ public class Encoding {
106329
Charset cs = entry.getValue();
107330
String name = toNameKey(cs.name());
108331
String canonName = toAsciiLowerCase(cs.name());
109-
if (!isBanned(name)) {
332+
if (!isBanned(stripDashAndUnderscore(name))) {
110333
name = name.intern();
111334
boolean asciiSuperset = asciiMapsToBasicLatin(testBuf, cs);
112335
Encoding enc = new Encoding(canonName.intern(), cs,
113-
asciiSuperset, isObscure(name), isShouldNot(name),
336+
asciiSuperset, isObscure(name),
337+
isShouldNot(stripDashAndUnderscore(name)),
114338
isLikelyEbcdic(name, asciiSuperset));
115339
encodings.add(enc);
116340
Set<String> aliases = cs.aliases();
@@ -254,16 +478,28 @@ public static String toNameKey(String str) {
254478
if (c >= 'A' && c <= 'Z') {
255479
c += 0x20;
256480
}
257-
if (!((c >= '\t' && c <= '\r') || (c >= '\u0020' && c <= '\u002F')
258-
|| (c >= '\u003A' && c <= '\u0040')
259-
|| (c >= '\u005B' && c <= '\u0060') || (c >= '\u007B' && c <= '\u007E'))) {
481+
if (!(c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\r')) {
260482
buf[j] = c;
261483
j++;
262484
}
263485
}
264486
return new String(buf, 0, j);
265487
}
266488

489+
public static String stripDashAndUnderscore(String str) {
490+
if (str == null) {
491+
return null;
492+
}
493+
char[] buf = new char[str.length()];
494+
for (int i = 0; i < str.length(); i++) {
495+
char c = str.charAt(i);
496+
if (c == '-' || c == '_') {
497+
buf[i] = c;
498+
}
499+
}
500+
return new String(buf);
501+
}
502+
267503
public static String toAsciiLowerCase(String str) {
268504
if (str == null) {
269505
return null;

0 commit comments

Comments
 (0)