url_test.go (4026B)
1 // Copyright 2011 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 //go:build go1.13 && !windows 6 // +build go1.13,!windows 7 8 package template 9 10 import ( 11 "testing" 12 ) 13 14 func TestURLNormalizer(t *testing.T) { 15 tests := []struct { 16 url, want string 17 }{ 18 {"", ""}, 19 { 20 "http://example.com:80/foo/bar?q=foo%20&bar=x+y#frag", 21 "http://example.com:80/foo/bar?q=foo%20&bar=x+y#frag", 22 }, 23 {" ", "%20"}, 24 {"%7c", "%7c"}, 25 {"%7C", "%7C"}, 26 {"%2", "%252"}, 27 {"%", "%25"}, 28 {"%z", "%25z"}, 29 {"/foo|bar/%5c\u1234", "/foo%7cbar/%5c%e1%88%b4"}, 30 } 31 for _, test := range tests { 32 if got := urlNormalizer(test.url); test.want != got { 33 t.Errorf("%q: want\n\t%q\nbut got\n\t%q", test.url, test.want, got) 34 } 35 if test.want != urlNormalizer(test.want) { 36 t.Errorf("not idempotent: %q", test.want) 37 } 38 } 39 } 40 41 func TestURLFilters(t *testing.T) { 42 input := ("\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f" + 43 "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" + 44 ` !"#$%&'()*+,-./` + 45 `0123456789:;<=>?` + 46 `@ABCDEFGHIJKLMNO` + 47 `PQRSTUVWXYZ[\]^_` + 48 "`abcdefghijklmno" + 49 "pqrstuvwxyz{|}~\x7f" + 50 "\u00A0\u0100\u2028\u2029\ufeff\U0001D11E") 51 52 tests := []struct { 53 name string 54 escaper func(...any) string 55 escaped string 56 }{ 57 { 58 "urlEscaper", 59 urlEscaper, 60 "%00%01%02%03%04%05%06%07%08%09%0a%0b%0c%0d%0e%0f" + 61 "%10%11%12%13%14%15%16%17%18%19%1a%1b%1c%1d%1e%1f" + 62 "%20%21%22%23%24%25%26%27%28%29%2a%2b%2c-.%2f" + 63 "0123456789%3a%3b%3c%3d%3e%3f" + 64 "%40ABCDEFGHIJKLMNO" + 65 "PQRSTUVWXYZ%5b%5c%5d%5e_" + 66 "%60abcdefghijklmno" + 67 "pqrstuvwxyz%7b%7c%7d~%7f" + 68 "%c2%a0%c4%80%e2%80%a8%e2%80%a9%ef%bb%bf%f0%9d%84%9e", 69 }, 70 { 71 "urlNormalizer", 72 urlNormalizer, 73 "%00%01%02%03%04%05%06%07%08%09%0a%0b%0c%0d%0e%0f" + 74 "%10%11%12%13%14%15%16%17%18%19%1a%1b%1c%1d%1e%1f" + 75 "%20!%22#$%25&%27%28%29*+,-./" + 76 "0123456789:;%3c=%3e?" + 77 "@ABCDEFGHIJKLMNO" + 78 "PQRSTUVWXYZ[%5c]%5e_" + 79 "%60abcdefghijklmno" + 80 "pqrstuvwxyz%7b%7c%7d~%7f" + 81 "%c2%a0%c4%80%e2%80%a8%e2%80%a9%ef%bb%bf%f0%9d%84%9e", 82 }, 83 } 84 85 for _, test := range tests { 86 if s := test.escaper(input); s != test.escaped { 87 t.Errorf("%s: want\n\t%q\ngot\n\t%q", test.name, test.escaped, s) 88 continue 89 } 90 } 91 } 92 93 func TestSrcsetFilter(t *testing.T) { 94 tests := []struct { 95 name string 96 input string 97 want string 98 }{ 99 { 100 "one ok", 101 "http://example.com/img.png", 102 "http://example.com/img.png", 103 }, 104 { 105 "one ok with metadata", 106 " /img.png 200w", 107 " /img.png 200w", 108 }, 109 { 110 "one bad", 111 "javascript:alert(1) 200w", 112 "#ZgotmplZ", 113 }, 114 { 115 "two ok", 116 "foo.png, bar.png", 117 "foo.png, bar.png", 118 }, 119 { 120 "left bad", 121 "javascript:alert(1), /foo.png", 122 "#ZgotmplZ, /foo.png", 123 }, 124 { 125 "right bad", 126 "/bogus#, javascript:alert(1)", 127 "/bogus#,#ZgotmplZ", 128 }, 129 } 130 131 for _, test := range tests { 132 if got := srcsetFilterAndEscaper(test.input); got != test.want { 133 t.Errorf("%s: srcsetFilterAndEscaper(%q) want %q != %q", test.name, test.input, test.want, got) 134 } 135 } 136 } 137 138 func BenchmarkURLEscaper(b *testing.B) { 139 for i := 0; i < b.N; i++ { 140 urlEscaper("http://example.com:80/foo?q=bar%20&baz=x+y#frag") 141 } 142 } 143 144 func BenchmarkURLEscaperNoSpecials(b *testing.B) { 145 for i := 0; i < b.N; i++ { 146 urlEscaper("TheQuickBrownFoxJumpsOverTheLazyDog.") 147 } 148 } 149 150 func BenchmarkURLNormalizer(b *testing.B) { 151 for i := 0; i < b.N; i++ { 152 urlNormalizer("The quick brown fox jumps over the lazy dog.\n") 153 } 154 } 155 156 func BenchmarkURLNormalizerNoSpecials(b *testing.B) { 157 for i := 0; i < b.N; i++ { 158 urlNormalizer("http://example.com:80/foo?q=bar%20&baz=x+y#frag") 159 } 160 } 161 162 func BenchmarkSrcsetFilter(b *testing.B) { 163 for i := 0; i < b.N; i++ { 164 srcsetFilterAndEscaper(" /foo/bar.png 200w, /baz/boo(1).png") 165 } 166 } 167 168 func BenchmarkSrcsetFilterNoSpecials(b *testing.B) { 169 for i := 0; i < b.N; i++ { 170 srcsetFilterAndEscaper("http://example.com:80/foo?q=bar%20&baz=x+y#frag") 171 } 172 }