~ubuntu-branches/ubuntu/trusty/juju-core/trusty-proposed

« back to all changes in this revision

Viewing changes to src/golang.org/x/net/publicsuffix/list_test.go

  • Committer: Package Import Robot
  • Author(s): Robie Basak
  • Date: 2015-07-15 13:09:07 UTC
  • mfrom: (35.1.15 wily-proposed)
  • Revision ID: package-import@ubuntu.com-20150715130907-wqak1zpebzzdvy3q
Tags: 1.22.6-0ubuntu1~14.04.1
* No change backport to 14.04 (LP: #1469744). This results in the
  following packaging delta from the previous 1.20.11-0ubuntu0.14.04.1
  in trusty-updates:
  - distro-info added and libgo5 removed from Build-Depends.
  - Standards-Version bumped.
  - cloud-image-utils | cloud-utils added to juju-local Depends.
  - d/copyright updated.
  - dep8 tests updated.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2012 The Go Authors. All rights reserved.
 
2
// Use of this source code is governed by a BSD-style
 
3
// license that can be found in the LICENSE file.
 
4
 
 
5
package publicsuffix
 
6
 
 
7
import (
 
8
        "sort"
 
9
        "strings"
 
10
        "testing"
 
11
)
 
12
 
 
13
func TestNodeLabel(t *testing.T) {
 
14
        for i, want := range nodeLabels {
 
15
                got := nodeLabel(uint32(i))
 
16
                if got != want {
 
17
                        t.Errorf("%d: got %q, want %q", i, got, want)
 
18
                }
 
19
        }
 
20
}
 
21
 
 
22
func TestFind(t *testing.T) {
 
23
        testCases := []string{
 
24
                "",
 
25
                "a",
 
26
                "a0",
 
27
                "aaaa",
 
28
                "ao",
 
29
                "ap",
 
30
                "ar",
 
31
                "aro",
 
32
                "arp",
 
33
                "arpa",
 
34
                "arpaa",
 
35
                "arpb",
 
36
                "az",
 
37
                "b",
 
38
                "b0",
 
39
                "ba",
 
40
                "z",
 
41
                "zu",
 
42
                "zv",
 
43
                "zw",
 
44
                "zx",
 
45
                "zy",
 
46
                "zz",
 
47
                "zzzz",
 
48
        }
 
49
        for _, tc := range testCases {
 
50
                got := find(tc, 0, numTLD)
 
51
                want := notFound
 
52
                for i := uint32(0); i < numTLD; i++ {
 
53
                        if tc == nodeLabel(i) {
 
54
                                want = i
 
55
                                break
 
56
                        }
 
57
                }
 
58
                if got != want {
 
59
                        t.Errorf("%q: got %d, want %d", tc, got, want)
 
60
                }
 
61
        }
 
62
}
 
63
 
 
64
func TestICANN(t *testing.T) {
 
65
        testCases := map[string]bool{
 
66
                "foo.org":            true,
 
67
                "foo.co.uk":          true,
 
68
                "foo.dyndns.org":     false,
 
69
                "foo.go.dyndns.org":  false,
 
70
                "foo.blogspot.co.uk": false,
 
71
                "foo.intranet":       false,
 
72
        }
 
73
        for domain, want := range testCases {
 
74
                _, got := PublicSuffix(domain)
 
75
                if got != want {
 
76
                        t.Errorf("%q: got %v, want %v", domain, got, want)
 
77
                }
 
78
        }
 
79
}
 
80
 
 
81
var publicSuffixTestCases = []struct {
 
82
        domain, want string
 
83
}{
 
84
        // Empty string.
 
85
        {"", ""},
 
86
 
 
87
        // The .ao rules are:
 
88
        // ao
 
89
        // ed.ao
 
90
        // gv.ao
 
91
        // og.ao
 
92
        // co.ao
 
93
        // pb.ao
 
94
        // it.ao
 
95
        {"ao", "ao"},
 
96
        {"www.ao", "ao"},
 
97
        {"pb.ao", "pb.ao"},
 
98
        {"www.pb.ao", "pb.ao"},
 
99
        {"www.xxx.yyy.zzz.pb.ao", "pb.ao"},
 
100
 
 
101
        // The .ar rules are:
 
102
        // ar
 
103
        // com.ar
 
104
        // edu.ar
 
105
        // gob.ar
 
106
        // gov.ar
 
107
        // int.ar
 
108
        // mil.ar
 
109
        // net.ar
 
110
        // org.ar
 
111
        // tur.ar
 
112
        // blogspot.com.ar
 
113
        {"ar", "ar"},
 
114
        {"www.ar", "ar"},
 
115
        {"nic.ar", "ar"},
 
116
        {"www.nic.ar", "ar"},
 
117
        {"com.ar", "com.ar"},
 
118
        {"www.com.ar", "com.ar"},
 
119
        {"blogspot.com.ar", "blogspot.com.ar"},
 
120
        {"www.blogspot.com.ar", "blogspot.com.ar"},
 
121
        {"www.xxx.yyy.zzz.blogspot.com.ar", "blogspot.com.ar"},
 
122
        {"logspot.com.ar", "com.ar"},
 
123
        {"zlogspot.com.ar", "com.ar"},
 
124
        {"zblogspot.com.ar", "com.ar"},
 
125
 
 
126
        // The .arpa rules are:
 
127
        // arpa
 
128
        // e164.arpa
 
129
        // in-addr.arpa
 
130
        // ip6.arpa
 
131
        // iris.arpa
 
132
        // uri.arpa
 
133
        // urn.arpa
 
134
        {"arpa", "arpa"},
 
135
        {"www.arpa", "arpa"},
 
136
        {"urn.arpa", "urn.arpa"},
 
137
        {"www.urn.arpa", "urn.arpa"},
 
138
        {"www.xxx.yyy.zzz.urn.arpa", "urn.arpa"},
 
139
 
 
140
        // The relevant {kobe,kyoto}.jp rules are:
 
141
        // jp
 
142
        // *.kobe.jp
 
143
        // !city.kobe.jp
 
144
        // kyoto.jp
 
145
        // ide.kyoto.jp
 
146
        {"jp", "jp"},
 
147
        {"kobe.jp", "jp"},
 
148
        {"c.kobe.jp", "c.kobe.jp"},
 
149
        {"b.c.kobe.jp", "c.kobe.jp"},
 
150
        {"a.b.c.kobe.jp", "c.kobe.jp"},
 
151
        {"city.kobe.jp", "kobe.jp"},
 
152
        {"www.city.kobe.jp", "kobe.jp"},
 
153
        {"kyoto.jp", "kyoto.jp"},
 
154
        {"test.kyoto.jp", "kyoto.jp"},
 
155
        {"ide.kyoto.jp", "ide.kyoto.jp"},
 
156
        {"b.ide.kyoto.jp", "ide.kyoto.jp"},
 
157
        {"a.b.ide.kyoto.jp", "ide.kyoto.jp"},
 
158
 
 
159
        // The .tw rules are:
 
160
        // tw
 
161
        // edu.tw
 
162
        // gov.tw
 
163
        // mil.tw
 
164
        // com.tw
 
165
        // net.tw
 
166
        // org.tw
 
167
        // idv.tw
 
168
        // game.tw
 
169
        // ebiz.tw
 
170
        // club.tw
 
171
        // 網路.tw (xn--zf0ao64a.tw)
 
172
        // 組織.tw (xn--uc0atv.tw)
 
173
        // 商業.tw (xn--czrw28b.tw)
 
174
        // blogspot.tw
 
175
        {"tw", "tw"},
 
176
        {"aaa.tw", "tw"},
 
177
        {"www.aaa.tw", "tw"},
 
178
        {"xn--czrw28b.aaa.tw", "tw"},
 
179
        {"edu.tw", "edu.tw"},
 
180
        {"www.edu.tw", "edu.tw"},
 
181
        {"xn--czrw28b.edu.tw", "edu.tw"},
 
182
        {"xn--czrw28b.tw", "xn--czrw28b.tw"},
 
183
        {"www.xn--czrw28b.tw", "xn--czrw28b.tw"},
 
184
        {"xn--uc0atv.xn--czrw28b.tw", "xn--czrw28b.tw"},
 
185
        {"xn--kpry57d.tw", "tw"},
 
186
 
 
187
        // The .uk rules are:
 
188
        // uk
 
189
        // ac.uk
 
190
        // co.uk
 
191
        // gov.uk
 
192
        // ltd.uk
 
193
        // me.uk
 
194
        // net.uk
 
195
        // nhs.uk
 
196
        // org.uk
 
197
        // plc.uk
 
198
        // police.uk
 
199
        // *.sch.uk
 
200
        // blogspot.co.uk
 
201
        {"uk", "uk"},
 
202
        {"aaa.uk", "uk"},
 
203
        {"www.aaa.uk", "uk"},
 
204
        {"mod.uk", "uk"},
 
205
        {"www.mod.uk", "uk"},
 
206
        {"sch.uk", "uk"},
 
207
        {"mod.sch.uk", "mod.sch.uk"},
 
208
        {"www.sch.uk", "www.sch.uk"},
 
209
        {"blogspot.co.uk", "blogspot.co.uk"},
 
210
        {"blogspot.nic.uk", "uk"},
 
211
        {"blogspot.sch.uk", "blogspot.sch.uk"},
 
212
 
 
213
        // The .рф rules are
 
214
        // рф (xn--p1ai)
 
215
        {"xn--p1ai", "xn--p1ai"},
 
216
        {"aaa.xn--p1ai", "xn--p1ai"},
 
217
        {"www.xxx.yyy.xn--p1ai", "xn--p1ai"},
 
218
 
 
219
        // The .zw rules are:
 
220
        // *.zw
 
221
        {"zw", "zw"},
 
222
        {"www.zw", "www.zw"},
 
223
        {"zzz.zw", "zzz.zw"},
 
224
        {"www.zzz.zw", "zzz.zw"},
 
225
        {"www.xxx.yyy.zzz.zw", "zzz.zw"},
 
226
 
 
227
        // There are no .nosuchtld rules.
 
228
        {"nosuchtld", "nosuchtld"},
 
229
        {"foo.nosuchtld", "nosuchtld"},
 
230
        {"bar.foo.nosuchtld", "nosuchtld"},
 
231
}
 
232
 
 
233
func BenchmarkPublicSuffix(b *testing.B) {
 
234
        for i := 0; i < b.N; i++ {
 
235
                for _, tc := range publicSuffixTestCases {
 
236
                        List.PublicSuffix(tc.domain)
 
237
                }
 
238
        }
 
239
}
 
240
 
 
241
func TestPublicSuffix(t *testing.T) {
 
242
        for _, tc := range publicSuffixTestCases {
 
243
                got := List.PublicSuffix(tc.domain)
 
244
                if got != tc.want {
 
245
                        t.Errorf("%q: got %q, want %q", tc.domain, got, tc.want)
 
246
                }
 
247
        }
 
248
}
 
249
 
 
250
func TestSlowPublicSuffix(t *testing.T) {
 
251
        for _, tc := range publicSuffixTestCases {
 
252
                got := slowPublicSuffix(tc.domain)
 
253
                if got != tc.want {
 
254
                        t.Errorf("%q: got %q, want %q", tc.domain, got, tc.want)
 
255
                }
 
256
        }
 
257
}
 
258
 
 
259
// slowPublicSuffix implements the canonical (but O(number of rules)) public
 
260
// suffix algorithm described at http://publicsuffix.org/list/.
 
261
//
 
262
// 1. Match domain against all rules and take note of the matching ones.
 
263
// 2. If no rules match, the prevailing rule is "*".
 
264
// 3. If more than one rule matches, the prevailing rule is the one which is an exception rule.
 
265
// 4. If there is no matching exception rule, the prevailing rule is the one with the most labels.
 
266
// 5. If the prevailing rule is a exception rule, modify it by removing the leftmost label.
 
267
// 6. The public suffix is the set of labels from the domain which directly match the labels of the prevailing rule (joined by dots).
 
268
// 7. The registered or registrable domain is the public suffix plus one additional label.
 
269
//
 
270
// This function returns the public suffix, not the registrable domain, and so
 
271
// it stops after step 6.
 
272
func slowPublicSuffix(domain string) string {
 
273
        match := func(rulePart, domainPart string) bool {
 
274
                switch rulePart[0] {
 
275
                case '*':
 
276
                        return true
 
277
                case '!':
 
278
                        return rulePart[1:] == domainPart
 
279
                }
 
280
                return rulePart == domainPart
 
281
        }
 
282
 
 
283
        domainParts := strings.Split(domain, ".")
 
284
        var matchingRules [][]string
 
285
 
 
286
loop:
 
287
        for _, rule := range rules {
 
288
                ruleParts := strings.Split(rule, ".")
 
289
                if len(domainParts) < len(ruleParts) {
 
290
                        continue
 
291
                }
 
292
                for i := range ruleParts {
 
293
                        rulePart := ruleParts[len(ruleParts)-1-i]
 
294
                        domainPart := domainParts[len(domainParts)-1-i]
 
295
                        if !match(rulePart, domainPart) {
 
296
                                continue loop
 
297
                        }
 
298
                }
 
299
                matchingRules = append(matchingRules, ruleParts)
 
300
        }
 
301
        if len(matchingRules) == 0 {
 
302
                matchingRules = append(matchingRules, []string{"*"})
 
303
        } else {
 
304
                sort.Sort(byPriority(matchingRules))
 
305
        }
 
306
        prevailing := matchingRules[0]
 
307
        if prevailing[0][0] == '!' {
 
308
                prevailing = prevailing[1:]
 
309
        }
 
310
        if prevailing[0][0] == '*' {
 
311
                replaced := domainParts[len(domainParts)-len(prevailing)]
 
312
                prevailing = append([]string{replaced}, prevailing[1:]...)
 
313
        }
 
314
        return strings.Join(prevailing, ".")
 
315
}
 
316
 
 
317
type byPriority [][]string
 
318
 
 
319
func (b byPriority) Len() int      { return len(b) }
 
320
func (b byPriority) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
 
321
func (b byPriority) Less(i, j int) bool {
 
322
        if b[i][0][0] == '!' {
 
323
                return true
 
324
        }
 
325
        if b[j][0][0] == '!' {
 
326
                return false
 
327
        }
 
328
        return len(b[i]) > len(b[j])
 
329
}
 
330
 
 
331
// eTLDPlusOneTestCases come from
 
332
// http://mxr.mozilla.org/mozilla-central/source/netwerk/test/unit/data/test_psl.txt
 
333
var eTLDPlusOneTestCases = []struct {
 
334
        domain, want string
 
335
}{
 
336
        // Empty input.
 
337
        {"", ""},
 
338
        // Unlisted TLD.
 
339
        {"example", ""},
 
340
        {"example.example", "example.example"},
 
341
        {"b.example.example", "example.example"},
 
342
        {"a.b.example.example", "example.example"},
 
343
        // TLD with only 1 rule.
 
344
        {"biz", ""},
 
345
        {"domain.biz", "domain.biz"},
 
346
        {"b.domain.biz", "domain.biz"},
 
347
        {"a.b.domain.biz", "domain.biz"},
 
348
        // TLD with some 2-level rules.
 
349
        {"com", ""},
 
350
        {"example.com", "example.com"},
 
351
        {"b.example.com", "example.com"},
 
352
        {"a.b.example.com", "example.com"},
 
353
        {"uk.com", ""},
 
354
        {"example.uk.com", "example.uk.com"},
 
355
        {"b.example.uk.com", "example.uk.com"},
 
356
        {"a.b.example.uk.com", "example.uk.com"},
 
357
        {"test.ac", "test.ac"},
 
358
        // TLD with only 1 (wildcard) rule.
 
359
        {"cy", ""},
 
360
        {"c.cy", ""},
 
361
        {"b.c.cy", "b.c.cy"},
 
362
        {"a.b.c.cy", "b.c.cy"},
 
363
        // More complex TLD.
 
364
        {"jp", ""},
 
365
        {"test.jp", "test.jp"},
 
366
        {"www.test.jp", "test.jp"},
 
367
        {"ac.jp", ""},
 
368
        {"test.ac.jp", "test.ac.jp"},
 
369
        {"www.test.ac.jp", "test.ac.jp"},
 
370
        {"kyoto.jp", ""},
 
371
        {"test.kyoto.jp", "test.kyoto.jp"},
 
372
        {"ide.kyoto.jp", ""},
 
373
        {"b.ide.kyoto.jp", "b.ide.kyoto.jp"},
 
374
        {"a.b.ide.kyoto.jp", "b.ide.kyoto.jp"},
 
375
        {"c.kobe.jp", ""},
 
376
        {"b.c.kobe.jp", "b.c.kobe.jp"},
 
377
        {"a.b.c.kobe.jp", "b.c.kobe.jp"},
 
378
        {"city.kobe.jp", "city.kobe.jp"},
 
379
        {"www.city.kobe.jp", "city.kobe.jp"},
 
380
        // TLD with a wildcard rule and exceptions.
 
381
        {"ck", ""},
 
382
        {"test.ck", ""},
 
383
        {"b.test.ck", "b.test.ck"},
 
384
        {"a.b.test.ck", "b.test.ck"},
 
385
        {"www.ck", "www.ck"},
 
386
        {"www.www.ck", "www.ck"},
 
387
        // US K12.
 
388
        {"us", ""},
 
389
        {"test.us", "test.us"},
 
390
        {"www.test.us", "test.us"},
 
391
        {"ak.us", ""},
 
392
        {"test.ak.us", "test.ak.us"},
 
393
        {"www.test.ak.us", "test.ak.us"},
 
394
        {"k12.ak.us", ""},
 
395
        {"test.k12.ak.us", "test.k12.ak.us"},
 
396
        {"www.test.k12.ak.us", "test.k12.ak.us"},
 
397
        // Punycoded IDN labels
 
398
        {"xn--85x722f.com.cn", "xn--85x722f.com.cn"},
 
399
        {"xn--85x722f.xn--55qx5d.cn", "xn--85x722f.xn--55qx5d.cn"},
 
400
        {"www.xn--85x722f.xn--55qx5d.cn", "xn--85x722f.xn--55qx5d.cn"},
 
401
        {"shishi.xn--55qx5d.cn", "shishi.xn--55qx5d.cn"},
 
402
        {"xn--55qx5d.cn", ""},
 
403
        {"xn--85x722f.xn--fiqs8s", "xn--85x722f.xn--fiqs8s"},
 
404
        {"www.xn--85x722f.xn--fiqs8s", "xn--85x722f.xn--fiqs8s"},
 
405
        {"shishi.xn--fiqs8s", "shishi.xn--fiqs8s"},
 
406
        {"xn--fiqs8s", ""},
 
407
}
 
408
 
 
409
func TestEffectiveTLDPlusOne(t *testing.T) {
 
410
        for _, tc := range eTLDPlusOneTestCases {
 
411
                got, _ := EffectiveTLDPlusOne(tc.domain)
 
412
                if got != tc.want {
 
413
                        t.Errorf("%q: got %q, want %q", tc.domain, got, tc.want)
 
414
                }
 
415
        }
 
416
}