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.
13 func TestEndsWithCSSKeyword(t
*testing
.T
) {
22 {"url", "important", false},
23 {"important", "important", true},
24 {"image-url", "url", false},
25 {"imageurl", "url", false},
26 {"image url", "url", true},
28 for _
, test
:= range tests
{
29 got
:= endsWithCSSKeyword([]byte(test
.css
), test
.kw
)
31 t
.Errorf("want %t but got %t for css=%v, kw=%v", test
.want
, got
, test
.css
, test
.kw
)
36 func TestIsCSSNmchar(t
*testing
.T
) {
62 for _
, test
:= range tests
{
63 got
:= isCSSNmchar(test
.rune
)
65 t
.Errorf("%q: want %t but got %t", string(test
.rune
), test
.want
, got
)
70 func TestDecodeCSS(t
*testing
.T
) {
83 {`\000000a`, "\u0000a"},
84 {`\1234 5`, "\u1234" + "5"},
85 {`\1234\20 5`, "\u1234" + " 5"},
86 {`\1234\A 5`, "\u1234" + "\n5"},
87 {"\\1234\t5", "\u1234" + "5"},
88 {"\\1234\n5", "\u1234" + "5"},
89 {"\\1234\r\n5", "\u1234" + "5"},
90 {`\12345`, "\U00012345"},
98 `The \3c i\3equick\3c/i\3e,\d\A\3cspan style=\27 color:brown\27\3e brown\3c/span\3e fox jumps\2028over the \3c canine class=\22lazy\22 \3e dog\3c/canine\3e`,
99 "The <i>quick</i>,\r\n<span style='color:brown'>brown</span> fox jumps\u2028over the <canine class=\"lazy\">dog</canine>",
102 for _
, test
:= range tests
{
103 got1
:= string(decodeCSS([]byte(test
.css
)))
104 if got1
!= test
.want
{
105 t
.Errorf("%q: want\n\t%q\nbut got\n\t%q", test
.css
, test
.want
, got1
)
107 recoded
:= cssEscaper(got1
)
108 if got2
:= string(decodeCSS([]byte(recoded
))); got2
!= test
.want
{
109 t
.Errorf("%q: escape & decode not dual for %q", test
.css
, recoded
)
114 func TestHexDecode(t
*testing
.T
) {
115 for i
:= 0; i
< 0x200000; i
+= 101 /* coprime with 16 */ {
116 s
:= strconv
.FormatInt(int64(i
), 16)
117 if got
:= int(hexDecode([]byte(s
))); got
!= i
{
118 t
.Errorf("%s: want %d but got %d", s
, i
, got
)
120 s
= strings
.ToUpper(s
)
121 if got
:= int(hexDecode([]byte(s
))); got
!= i
{
122 t
.Errorf("%s: want %d but got %d", s
, i
, got
)
127 func TestSkipCSSSpace(t
*testing
.T
) {
143 for _
, test
:= range tests
{
144 got
:= string(skipCSSSpace([]byte(test
.css
)))
145 if got
!= test
.want
{
146 t
.Errorf("%q: want %q but got %q", test
.css
, test
.want
, got
)
151 func TestCSSEscaper(t
*testing
.T
) {
152 input
:= ("\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f" +
153 "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" +
159 "pqrstuvwxyz{|}~\x7f" +
160 "\u00A0\u0100\u2028\u2029\ufeff\U0001D11E")
162 want
:= ("\\0\x01\x02\x03\x04\x05\x06\x07" +
163 "\x08\\9 \\a\x0b\\c \\d\x0E\x0F" +
164 "\x10\x11\x12\x13\x14\x15\x16\x17" +
165 "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" +
166 ` !\22#$%\26\27\28\29*\2b,-.\2f ` +
167 `0123456789\3a\3b\3c=\3e?` +
169 `PQRSTUVWXYZ[\\]^_` +
171 `pqrstuvwxyz\7b|\7d~` + "\u007f" +
172 "\u00A0\u0100\u2028\u2029\ufeff\U0001D11E")
174 got
:= cssEscaper(input
)
176 t
.Errorf("encode: want\n\t%q\nbut got\n\t%q", want
, got
)
179 got
= string(decodeCSS([]byte(got
)))
181 t
.Errorf("decode: want\n\t%q\nbut got\n\t%q", input
, got
)
185 func TestCSSValueFilter(t
*testing
.T
) {
194 {"1.25in", "1.25in"},
195 {"+.33em", "+.33em"},
200 {"corner-radius", "corner-radius"},
201 {"-moz-corner-radius", "-moz-corner-radius"},
204 {"#123456", "#123456"},
205 {"U+00-FF, U+980-9FF", "U+00-FF, U+980-9FF"},
206 {"color: red", "color: red"},
207 {"<!--", "ZgotmplZ"},
209 {"<![CDATA[", "ZgotmplZ"},
211 {"</style", "ZgotmplZ"},
215 {"\x00", "ZgotmplZ"},
216 {"/* foo */", "ZgotmplZ"},
218 {"[href=~", "ZgotmplZ"},
219 {"expression(alert(1337))", "ZgotmplZ"},
220 {"-expression(alert(1337))", "ZgotmplZ"},
221 {"expression", "ZgotmplZ"},
222 {"Expression", "ZgotmplZ"},
223 {"EXPRESSION", "ZgotmplZ"},
224 {"-moz-binding", "ZgotmplZ"},
225 {"-expr\x00ession(alert(1337))", "ZgotmplZ"},
226 {`-expr\0ession(alert(1337))`, "ZgotmplZ"},
227 {`-express\69on(alert(1337))`, "ZgotmplZ"},
228 {`-express\69 on(alert(1337))`, "ZgotmplZ"},
229 {`-exp\72 ession(alert(1337))`, "ZgotmplZ"},
230 {`-exp\52 ession(alert(1337))`, "ZgotmplZ"},
231 {`-exp\000052 ession(alert(1337))`, "ZgotmplZ"},
232 {`-expre\0000073sion`, "-expre\x073sion"},
233 {`@import url evil.css`, "ZgotmplZ"},
235 for _
, test
:= range tests
{
236 got
:= cssValueFilter(test
.css
)
237 if got
!= test
.want
{
238 t
.Errorf("%q: want %q but got %q", test
.css
, test
.want
, got
)
243 func BenchmarkCSSEscaper(b
*testing
.B
) {
244 for i
:= 0; i
< b
.N
; i
++ {
245 cssEscaper("The <i>quick</i>,\r\n<span style='color:brown'>brown</span> fox jumps\u2028over the <canine class=\"lazy\">dog</canine>")
249 func BenchmarkCSSEscaperNoSpecials(b
*testing
.B
) {
250 for i
:= 0; i
< b
.N
; i
++ {
251 cssEscaper("The quick, brown fox jumps over the lazy dog.")
255 func BenchmarkDecodeCSS(b
*testing
.B
) {
256 s
:= []byte(`The \3c i\3equick\3c/i\3e,\d\A\3cspan style=\27 color:brown\27\3e brown\3c/span\3e fox jumps\2028over the \3c canine class=\22lazy\22 \3edog\3c/canine\3e`)
258 for i
:= 0; i
< b
.N
; i
++ {
263 func BenchmarkDecodeCSSNoSpecials(b
*testing
.B
) {
264 s
:= []byte("The quick, brown fox jumps over the lazy dog.")
266 for i
:= 0; i
< b
.N
; i
++ {
271 func BenchmarkCSSValueFilter(b
*testing
.B
) {
272 for i
:= 0; i
< b
.N
; i
++ {
273 cssValueFilter(` e\78preS\0Sio/**/n(alert(1337))`)
277 func BenchmarkCSSValueFilterOk(b
*testing
.B
) {
278 for i
:= 0; i
< b
.N
; i
++ {
279 cssValueFilter(`Times New Roman`)