1 /* Any copyright is dedicated to the Public Domain.
2  * https://creativecommons.org/publicdomain/zero/1.0/ */
3 
4 #[derive(Clone, Copy, Debug, PartialEq)]
5 pub enum Tld {
6     CentralWindows,
7     Cyrillic,
8     Western,
9     Greek,
10     TurkishAzeri,
11     Hebrew,
12     Arabic,
13     Baltic,
14     Vietnamese,
15     Thai,
16     Simplified,
17     Traditional,
18     Japanese,
19     Korean,
20     SimplifiedTraditional,
21     TraditionalSimplified,
22     CentralIso,
23     IcelandicFaroese,
24     WesternCyrillic,
25     CentralCyrillic,
26     WesternArabic,
27     Generic,
28     Eu,
29 }
30 
classify_tld(tld: &[u8]) -> Tld31 pub fn classify_tld(tld: &[u8]) -> Tld {
32     if tld.len() == 2 {
33         let key = [tld[0], tld[1]];
34         if let Ok(i) = TWO_LETTER_KEYS.binary_search(&key) {
35             TWO_LETTER_VALUES[i]
36         } else {
37             Tld::Western
38         }
39     } else if tld.len() == 3 {
40         match tld {
41             b"edu" | b"gov" | b"mil" => Tld::Western,
42             _ => Tld::Generic,
43         }
44     } else if tld.starts_with(b"xn--") && tld.len() >= 8 {
45         // It's unclear is including the IDNs here is a good idea.
46         // Clearly, they are an anachronism relative to the era
47         // of legacy encodings. The idea, consistent with previous
48         // approach in Firefox is to address the case where one
49         // of these TLDs is configured as an alternative name for
50         // a server that also serves the same content from a
51         // two-ASCII-letter TLD. This makes the detection result
52         // the same either way even though otherwise this thing
53         // does not make much sense.
54         if let Ok(i) = PUNYCODE_KEYS.binary_search(&&tld[4..]) {
55             PUNYCODE_VALUES[i]
56         } else {
57             Tld::Generic
58         }
59     } else {
60         Tld::Generic
61     }
62 }
63 
64 static TWO_LETTER_VALUES: [Tld; 87] = [
65     Tld::Generic,               // ac
66     Tld::Arabic,                // ae
67     Tld::Arabic,                // af
68     Tld::Generic,               // ai
69     Tld::WesternCyrillic,       // am
70     Tld::TurkishAzeri,          // az
71     Tld::CentralCyrillic,       // ba
72     Tld::Cyrillic,              // bg
73     Tld::Arabic,                // bh
74     Tld::Cyrillic,              // by
75     Tld::Generic,               // bz
76     Tld::Generic,               // cb
77     Tld::Generic,               // cc
78     Tld::Generic,               // cd
79     Tld::Simplified,            // cn
80     Tld::Generic,               // cx
81     Tld::Greek,                 // cy
82     Tld::CentralWindows,        // cz
83     Tld::Generic,               // dj
84     Tld::Arabic,                // dz
85     Tld::Arabic,                // eg
86     Tld::Eu,                    // eu
87     Tld::Generic,               // fm
88     Tld::IcelandicFaroese,      // fo
89     Tld::WesternCyrillic,       // ge
90     Tld::Greek,                 // gr
91     Tld::TraditionalSimplified, // hk
92     Tld::CentralWindows,        // hr
93     Tld::CentralIso,            // hu
94     Tld::Hebrew,                // il
95     Tld::Generic,               // in
96     Tld::Arabic,                // iq
97     Tld::Arabic,                // ir
98     Tld::IcelandicFaroese,      // is
99     Tld::Arabic,                // jo
100     Tld::Japanese,              // jp
101     Tld::Cyrillic,              // kg
102     Tld::Korean,                // kp
103     Tld::Korean,                // kr
104     Tld::Arabic,                // kw
105     Tld::Cyrillic,              // kz
106     Tld::Generic,               // la
107     Tld::Arabic,                // lb
108     Tld::Baltic,                // lt
109     Tld::Baltic,                // lv
110     Tld::Arabic,                // ly
111     Tld::Arabic,                // ma
112     Tld::Cyrillic,              // md
113     Tld::Generic,               // me
114     Tld::Cyrillic,              // mk
115     Tld::Cyrillic,              // mn
116     Tld::TraditionalSimplified, // mo
117     Tld::Arabic,                // mr
118     Tld::Generic,               // ms
119     Tld::WesternArabic,         // my
120     Tld::Generic,               // nu
121     Tld::Arabic,                // om
122     Tld::Arabic,                // pk
123     Tld::CentralIso,            // pl
124     Tld::Arabic,                // ps
125     Tld::Arabic,                // qa
126     Tld::CentralWindows,        // ro
127     Tld::Cyrillic,              // rs
128     Tld::Cyrillic,              // ru
129     Tld::Arabic,                // sa
130     Tld::Arabic,                // sd
131     Tld::SimplifiedTraditional, // sg
132     Tld::CentralIso,            // si
133     Tld::CentralWindows,        // sk
134     Tld::Generic,               // st
135     Tld::Cyrillic,              // su
136     Tld::Arabic,                // sy
137     Tld::Thai,                  // th
138     Tld::Cyrillic,              // tj
139     Tld::Generic,               // tk
140     Tld::Cyrillic,              // tm
141     Tld::Arabic,                // tn
142     Tld::Generic,               // to
143     Tld::TurkishAzeri,          // tr
144     Tld::Generic,               // tv
145     Tld::Traditional,           // tw
146     Tld::Cyrillic,              // ua
147     Tld::Cyrillic,              // uz
148     Tld::Generic,               // vc
149     Tld::Vietnamese,            // vn
150     Tld::Generic,               // vu
151     Tld::Arabic,                // ye
152 ];
153 
154 static TWO_LETTER_KEYS: [[u8; 2]; 87] = [
155     [b'a', b'c'], // Generic
156     [b'a', b'e'], // Arabic
157     [b'a', b'f'], // Arabic
158     [b'a', b'i'], // Generic
159     [b'a', b'm'], // WesternCyrillic
160     [b'a', b'z'], // TurkishAzeri
161     [b'b', b'a'], // CentralCyrillic
162     [b'b', b'g'], // Cyrillic
163     [b'b', b'h'], // Arabic
164     [b'b', b'y'], // Cyrillic
165     [b'b', b'z'], // Generic
166     [b'c', b'b'], // Generic
167     [b'c', b'c'], // Generic
168     [b'c', b'd'], // Generic
169     [b'c', b'n'], // Simplified
170     [b'c', b'x'], // Generic
171     [b'c', b'y'], // Greek
172     [b'c', b'z'], // CentralWindows
173     [b'd', b'j'], // Generic
174     [b'd', b'z'], // Arabic
175     [b'e', b'g'], // Arabic
176     [b'e', b'u'], // Eu
177     [b'f', b'm'], // Generic
178     [b'f', b'o'], // IcelandicFaroese
179     [b'g', b'e'], // WesternCyrillic
180     [b'g', b'r'], // Greek
181     [b'h', b'k'], // TraditionalSimplified
182     [b'h', b'r'], // CentralWindows
183     [b'h', b'u'], // CentralIso
184     [b'i', b'l'], // Hebrew
185     [b'i', b'n'], // Generic
186     [b'i', b'q'], // Arabic
187     [b'i', b'r'], // Arabic
188     [b'i', b's'], // IcelandicFaroese
189     [b'j', b'o'], // Arabic
190     [b'j', b'p'], // Japanese
191     [b'k', b'g'], // Cyrillic
192     [b'k', b'p'], // Korean
193     [b'k', b'r'], // Korean
194     [b'k', b'w'], // Arabic
195     [b'k', b'z'], // Cyrillic
196     [b'l', b'a'], // Generic
197     [b'l', b'b'], // Arabic
198     [b'l', b't'], // Baltic
199     [b'l', b'v'], // Baltic
200     [b'l', b'y'], // Arabic
201     [b'm', b'a'], // Arabic
202     [b'm', b'd'], // Cyrillic
203     [b'm', b'e'], // Generic
204     [b'm', b'k'], // Cyrillic
205     [b'm', b'n'], // Cyrillic
206     [b'm', b'o'], // TraditionalSimplified
207     [b'm', b'r'], // Arabic
208     [b'm', b's'], // Generic
209     [b'm', b'y'], // WesternArabic
210     [b'n', b'u'], // Generic
211     [b'o', b'm'], // Arabic
212     [b'p', b'k'], // Arabic
213     [b'p', b'l'], // CentralIso
214     [b'p', b's'], // Arabic
215     [b'q', b'a'], // Arabic
216     [b'r', b'o'], // CentralWindows
217     [b'r', b's'], // Cyrillic
218     [b'r', b'u'], // Cyrillic
219     [b's', b'a'], // Arabic
220     [b's', b'd'], // Arabic
221     [b's', b'g'], // SimplifiedTraditional
222     [b's', b'i'], // CentralIso
223     [b's', b'k'], // CentralWindows
224     [b's', b't'], // Generic
225     [b's', b'u'], // Cyrillic
226     [b's', b'y'], // Arabic
227     [b't', b'h'], // Thai
228     [b't', b'j'], // Cyrillic
229     [b't', b'k'], // Generic
230     [b't', b'm'], // Cyrillic
231     [b't', b'n'], // Arabic
232     [b't', b'o'], // Generic
233     [b't', b'r'], // TurkishAzeri
234     [b't', b'v'], // Generic
235     [b't', b'w'], // Traditional
236     [b'u', b'a'], // Cyrillic
237     [b'u', b'z'], // Cyrillic
238     [b'v', b'c'], // Generic
239     [b'v', b'n'], // Vietnamese
240     [b'v', b'u'], // Generic
241     [b'y', b'e'], // Arabic
242 ];
243 
244 static PUNYCODE_KEYS: [&'static [u8]; 46] = [
245     b"3e0b707e",           // Korean
246     b"54b7fta0cc",         // Western
247     b"80ao21a",            // Cyrillic
248     b"90a3ac",             // Cyrillic
249     b"90ae",               // Cyrillic
250     b"90ais",              // Cyrillic
251     b"clchc0ea0b2g2a9gcd", // SimplifiedTraditional
252     b"d1alf",              // Cyrillic
253     b"e1a4c",              // Eu
254     b"fiqs8S",             // Simplified
255     b"fiqz9S",             // Simplified
256     b"fzc2c9e2c",          // Western
257     b"j1amh",              // Cyrillic
258     b"j6w193g",            // TraditionalSimplified
259     b"kprw13d",            // Traditional
260     b"kpry57d",            // Traditional
261     b"l1acc",              // Cyrillic
262     b"lgbbat1ad8j",        // Arabic
263     b"mgb2ddes",           // Arabic
264     b"mgb9awbf",           // Arabic
265     b"mgba3a4f16a",        // Arabic
266     b"mgbaam7a8h",         // Arabic
267     b"mgbah1a3hjkrd",      // Arabic
268     b"mgbai9azgqp6j",      // Arabic
269     b"mgbayh7gpa",         // Arabic
270     b"mgbc0a9azcg",        // Arabic
271     b"mgbcpq6gpa1a",       // Arabic
272     b"mgberp4a5d4ar",      // Arabic
273     b"mgbpl2fh",           // Arabic
274     b"mgbtx2b",            // Arabic
275     b"mgbx4cd0ab",         // WesternArabic
276     b"mix891f",            // TraditionalSimplified
277     b"node",               // WesternCyrillic
278     b"o3cw4h",             // Thai
279     b"ogbpf8fl",           // Arabic
280     b"p1ai",               // Cyrillic
281     b"pgbs0dh",            // Arabic
282     b"q7ce6a",             // Arabic
283     b"qxa6a",              // Eu
284     b"qxam",               // Greek
285     b"wgbh1c",             // Arabic
286     b"wgbl6a",             // Arabic
287     b"xkc2al3hye2a",       // Western
288     b"y9a3aq",             // WesternCyrillic
289     b"yfro4i67o",          // SimplifiedTraditional
290     b"ygbi2ammx",          // Arabic
291 ];
292 
293 static PUNYCODE_VALUES: [Tld; 46] = [
294     Tld::Korean,                // 3e0b707e
295     Tld::Western,               // 54b7fta0cc
296     Tld::Cyrillic,              // 80ao21a
297     Tld::Cyrillic,              // 90a3ac
298     Tld::Cyrillic,              // 90ae
299     Tld::Cyrillic,              // 90ais
300     Tld::SimplifiedTraditional, // clchc0ea0b2g2a9gcd
301     Tld::Cyrillic,              // d1alf
302     Tld::Eu,                    // e1a4c
303     Tld::Simplified,            // fiqs8S
304     Tld::Simplified,            // fiqz9S
305     Tld::Western,               // fzc2c9e2c
306     Tld::Cyrillic,              // j1amh
307     Tld::TraditionalSimplified, // j6w193g
308     Tld::Traditional,           // kprw13d
309     Tld::Traditional,           // kpry57d
310     Tld::Cyrillic,              // l1acc
311     Tld::Arabic,                // lgbbat1ad8j
312     Tld::Arabic,                // mgb2ddes
313     Tld::Arabic,                // mgb9awbf
314     Tld::Arabic,                // mgba3a4f16a
315     Tld::Arabic,                // mgbaam7a8h
316     Tld::Arabic,                // mgbah1a3hjkrd
317     Tld::Arabic,                // mgbai9azgqp6j
318     Tld::Arabic,                // mgbayh7gpa
319     Tld::Arabic,                // mgbc0a9azcg
320     Tld::Arabic,                // mgbcpq6gpa1a
321     Tld::Arabic,                // mgberp4a5d4ar
322     Tld::Arabic,                // mgbpl2fh
323     Tld::Arabic,                // mgbtx2b
324     Tld::WesternArabic,         // mgbx4cd0ab
325     Tld::TraditionalSimplified, // mix891f
326     Tld::WesternCyrillic,       // node
327     Tld::Thai,                  // o3cw4h
328     Tld::Arabic,                // ogbpf8fl
329     Tld::Cyrillic,              // p1ai
330     Tld::Arabic,                // pgbs0dh
331     Tld::Arabic,                // q7ce6a
332     Tld::Eu,                    // qxa6a
333     Tld::Greek,                 // qxam
334     Tld::Arabic,                // wgbh1c
335     Tld::Arabic,                // wgbl6a
336     Tld::Western,               // xkc2al3hye2a
337     Tld::WesternCyrillic,       // y9a3aq
338     Tld::SimplifiedTraditional, // yfro4i67o
339     Tld::Arabic,                // ygbi2ammx
340 ];
341