Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(147)

Side by Side Diff: tests/lib_strong/html/node_validator_important_if_you_suppress_make_the_bug_critical_test.dart

Issue 2771453003: Format all tests. (Closed)
Patch Set: Format files Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /// This tests HTML validation and sanitization, which is very important 5 /// This tests HTML validation and sanitization, which is very important
6 /// for prevent XSS or other attacks. If you suppress this, or parts of it 6 /// for prevent XSS or other attacks. If you suppress this, or parts of it
7 /// please make it a critical bug and bring it to the attention of the 7 /// please make it a critical bug and bring it to the attention of the
8 /// dart:html maintainers. 8 /// dart:html maintainers.
9 library node_validator_test; 9 library node_validator_test;
10 10
11 import 'dart:html'; 11 import 'dart:html';
12 import 'dart:svg' as svg; 12 import 'dart:svg' as svg;
13 13
14 import 'package:expect/minitest.dart'; 14 import 'package:expect/minitest.dart';
15 15
16 import 'utils.dart'; 16 import 'utils.dart';
17 17
18 void validateHtml(String html, String reference, NodeValidator validator) { 18 void validateHtml(String html, String reference, NodeValidator validator) {
19 var a = document.body.createFragment(html, validator: validator); 19 var a = document.body.createFragment(html, validator: validator);
20 var b = document.body.createFragment(reference, 20 var b = document.body
21 treeSanitizer: NodeTreeSanitizer.trusted); 21 .createFragment(reference, treeSanitizer: NodeTreeSanitizer.trusted);
22 22
23 // Prevent a false pass when both the html and the reference both get entirely 23 // Prevent a false pass when both the html and the reference both get entirely
24 // deleted, which is technically a match, but unlikely to be what we meant. 24 // deleted, which is technically a match, but unlikely to be what we meant.
25 if (reference != '') { 25 if (reference != '') {
26 expect(b.childNodes.length > 0, isTrue); 26 expect(b.childNodes.length > 0, isTrue);
27 } 27 }
28 validateNodeTree(a, b); 28 validateNodeTree(a, b);
29 } 29 }
30 30
31 class RecordingUriValidator implements UriPolicy { 31 class RecordingUriValidator implements UriPolicy {
32 final List<String> calls = <String>[]; 32 final List<String> calls = <String>[];
33 33
34 bool allowsUri(String uri) { 34 bool allowsUri(String uri) {
35 calls.add('$uri'); 35 calls.add('$uri');
36 return false; 36 return false;
37 } 37 }
38 38
39 void reset() { 39 void reset() {
40 calls.clear(); 40 calls.clear();
41 } 41 }
42 } 42 }
43 43
44 void testHtml(String name, NodeValidator validator, String html, 44 void testHtml(String name, NodeValidator validator, String html,
45 [String reference]) { 45 [String reference]) {
46 test(name, () { 46 test(name, () {
47 if (reference == null) { 47 if (reference == null) {
48 reference = html; 48 reference = html;
49 } 49 }
50 50
51 validateHtml(html, reference, validator); 51 validateHtml(html, reference, validator);
52 }); 52 });
53 } 53 }
54 54
55 main() { 55 main() {
56 group('DOM_sanitization', () { 56 group('DOM_sanitization', () {
57 var validator = new NodeValidatorBuilder.common(); 57 var validator = new NodeValidatorBuilder.common();
58 58
59 testHtml('allows simple constructs', 59 testHtml('allows simple constructs', validator,
60 validator,
61 '<div class="baz">something</div>'); 60 '<div class="baz">something</div>');
62 61
63 testHtml('blocks unknown attributes', 62 testHtml('blocks unknown attributes', validator,
64 validator, 63 '<div foo="baz">something</div>', '<div>something</div>');
65 '<div foo="baz">something</div>',
66 '<div>something</div>');
67 64
68 testHtml('blocks custom element', 65 testHtml('blocks custom element', validator,
69 validator, 66 '<x-my-element>something</x-my-element>', '');
70 '<x-my-element>something</x-my-element>',
71 '');
72 67
73 testHtml('blocks custom is element', 68 testHtml('blocks custom is element', validator,
74 validator, 69 '<div is="x-my-element">something</div>', '');
75 '<div is="x-my-element">something</div>',
76 '');
77 70
78 testHtml('blocks body elements', 71 testHtml(
79 validator, 72 'blocks body elements', validator, '<body background="s"></body>', '');
80 '<body background="s"></body>',
81 '');
82 73
83 testHtml('allows select elements', 74 testHtml(
75 'allows select elements',
84 validator, 76 validator,
85 '<select>' 77 '<select>'
86 '<option>a</option>' 78 '<option>a</option>'
87 '</select>'); 79 '</select>');
88 80
89 testHtml('blocks sequential script elements', 81 testHtml('blocks sequential script elements', validator,
90 validator, 82 '<div><script></script><script></script></div>', '<div></div>');
91 '<div><script></script><script></script></div>',
92 '<div></div>');
93 83
94 testHtml('blocks inline styles', 84 testHtml('blocks inline styles', validator,
95 validator, 85 '<div style="background: red"></div>', '<div></div>');
96 '<div style="background: red"></div>',
97 '<div></div>');
98 86
99 testHtml('blocks namespaced attributes', 87 testHtml('blocks namespaced attributes', validator,
100 validator, 88 '<div ns:foo="foo"></div>', '<div></div>');
101 '<div ns:foo="foo"></div>',
102 '<div></div>');
103 89
104 testHtml('blocks namespaced common attributes', 90 testHtml('blocks namespaced common attributes', validator,
105 validator, 91 '<div ns:class="foo"></div>', '<div></div>');
106 '<div ns:class="foo"></div>',
107 '<div></div>');
108 92
109 testHtml('blocks namespaced common elements', 93 testHtml('blocks namespaced common elements', validator,
110 validator, 94 '<ns:div></ns:div>', '');
111 '<ns:div></ns:div>',
112 '');
113 95
114 testHtml('allows CDATA sections', 96 testHtml('allows CDATA sections', validator,
115 validator,
116 '<span>![CDATA[ some text ]]></span>'); 97 '<span>![CDATA[ some text ]]></span>');
117 98
118 test('sanitizes template contents', () { 99 test('sanitizes template contents', () {
119 if (!TemplateElement.supported) return; 100 if (!TemplateElement.supported) return;
120 101
121 var html = '<template>' 102 var html = '<template>'
122 '<div></div>' 103 '<div></div>'
123 '<script></script>' 104 '<script></script>'
124 '<img src="http://example.com/foo"/>' 105 '<img src="http://example.com/foo"/>'
125 '</template>'; 106 '</template>';
126 107
127 var fragment = document.body.createFragment(html, validator: validator); 108 var fragment = document.body.createFragment(html, validator: validator);
128 var template = fragment.nodes.single as TemplateElement; 109 var template = fragment.nodes.single as TemplateElement;
129 110
130 var expectedContent = document.body.createFragment( 111 var expectedContent = document.body.createFragment('<div></div>'
131 '<div></div>'
132 '<img/>'); 112 '<img/>');
133 113
134 validateNodeTree(template.content, expectedContent); 114 validateNodeTree(template.content, expectedContent);
135 }); 115 });
136 116
137 test("appendHtml is sanitized", () { 117 test("appendHtml is sanitized", () {
138 var html = '<body background="s"></body><div></div>'; 118 var html = '<body background="s"></body><div></div>';
139 document.body.appendHtml('<div id="stuff"></div>'); 119 document.body.appendHtml('<div id="stuff"></div>');
140 var stuff = document.querySelector("#stuff"); 120 var stuff = document.querySelector("#stuff");
141 stuff.appendHtml(html); 121 stuff.appendHtml(html);
142 expect(stuff.childNodes.length, 1); 122 expect(stuff.childNodes.length, 1);
143 stuff.remove(); 123 stuff.remove();
144 }); 124 });
145 125
146 test("documentFragment.appendHtml is sanitized", () { 126 test("documentFragment.appendHtml is sanitized", () {
147 var html = '<div id="things></div>'; 127 var html = '<div id="things></div>';
148 var fragment = new DocumentFragment.html(html); 128 var fragment = new DocumentFragment.html(html);
149 fragment.appendHtml('<div id="bad"><script></script></div>'); 129 fragment.appendHtml('<div id="bad"><script></script></div>');
150 expect(fragment.childNodes.length, 1); 130 expect(fragment.childNodes.length, 1);
151 var child = fragment.childNodes[0] as Element; 131 var child = fragment.childNodes[0] as Element;
152 expect(child.id, "bad"); 132 expect(child.id, "bad");
153 expect(child.childNodes.length, 0); 133 expect(child.childNodes.length, 0);
154 }); 134 });
155 135
156 testHtml("sanitizes embed", 136 testHtml(
157 validator, 137 "sanitizes embed",
158 "<div><embed src='' type='application/x-shockwave-flash'></embed></div>", 138 validator,
159 "<div></div>"); 139 "<div><embed src='' type='application/x-shockwave-flash'></embed></div>" ,
140 "<div></div>");
160 }); 141 });
161 142
162 group('URI_sanitization', () { 143 group('URI_sanitization', () {
163 var recorder = new RecordingUriValidator(); 144 var recorder = new RecordingUriValidator();
164 var validator = new NodeValidatorBuilder()..allowHtml5(uriPolicy: recorder); 145 var validator = new NodeValidatorBuilder()..allowHtml5(uriPolicy: recorder);
165 146
166 checkUriPolicyCalls(String name, String html, String reference, 147 checkUriPolicyCalls(String name, String html, String reference,
167 List<String> expectedCalls) { 148 List<String> expectedCalls) {
168
169 test(name, () { 149 test(name, () {
170 recorder.reset(); 150 recorder.reset();
171 151
172 validateHtml(html, reference, validator); 152 validateHtml(html, reference, validator);
173 expect(recorder.calls, expectedCalls); 153 expect(recorder.calls, expectedCalls);
174 }); 154 });
175 } 155 }
176 156
177 checkUriPolicyCalls('a::href', 157 checkUriPolicyCalls('a::href', '<a href="s"></a>', '<a></a>', ['s']);
178 '<a href="s"></a>',
179 '<a></a>',
180 ['s']);
181 158
182 checkUriPolicyCalls('area::href', 159 checkUriPolicyCalls(
183 '<area href="s"></area>', 160 'area::href', '<area href="s"></area>', '<area></area>', ['s']);
184 '<area></area>',
185 ['s']);
186 161
187 checkUriPolicyCalls('blockquote::cite', 162 checkUriPolicyCalls(
163 'blockquote::cite',
188 '<blockquote cite="s"></blockquote>', 164 '<blockquote cite="s"></blockquote>',
189 '<blockquote></blockquote>', 165 '<blockquote></blockquote>',
190 ['s']); 166 ['s']);
191 checkUriPolicyCalls('command::icon', 167 checkUriPolicyCalls(
192 '<command icon="s"/>', 168 'command::icon', '<command icon="s"/>', '<command/>', ['s']);
193 '<command/>', 169 checkUriPolicyCalls('img::src', '<img src="s"/>', '<img/>', ['s']);
194 ['s']); 170 checkUriPolicyCalls('input::src', '<input src="s"/>', '<input/>', ['s']);
195 checkUriPolicyCalls('img::src', 171 checkUriPolicyCalls(
196 '<img src="s"/>', 172 'ins::cite', '<ins cite="s"></ins>', '<ins></ins>', ['s']);
197 '<img/>', 173 checkUriPolicyCalls('q::cite', '<q cite="s"></q>', '<q></q>', ['s']);
198 ['s']); 174 checkUriPolicyCalls(
199 checkUriPolicyCalls('input::src', 175 'video::poster', '<video poster="s"/>', '<video/>', ['s']);
200 '<input src="s"/>',
201 '<input/>',
202 ['s']);
203 checkUriPolicyCalls('ins::cite',
204 '<ins cite="s"></ins>',
205 '<ins></ins>',
206 ['s']);
207 checkUriPolicyCalls('q::cite',
208 '<q cite="s"></q>',
209 '<q></q>',
210 ['s']);
211 checkUriPolicyCalls('video::poster',
212 '<video poster="s"/>',
213 '<video/>',
214 ['s']);
215 }); 176 });
216 177
217 group('allowNavigation', () { 178 group('allowNavigation', () {
218 var validator = new NodeValidatorBuilder()..allowNavigation(); 179 var validator = new NodeValidatorBuilder()..allowNavigation();
219 180
220 testHtml('allows anchor tags', 181 testHtml('allows anchor tags', validator, '<a href="#foo">foo</a>');
221 validator,
222 '<a href="#foo">foo</a>');
223 182
224 testHtml('allows form elements', 183 testHtml('allows form elements', validator,
225 validator,
226 '<form method="post" action="/foo"></form>'); 184 '<form method="post" action="/foo"></form>');
227 185
228 testHtml('disallows script navigation', 186 testHtml('disallows script navigation', validator,
229 validator, 187 '<a href="javascript:foo = 1">foo</a>', '<a>foo</a>');
230 '<a href="javascript:foo = 1">foo</a>',
231 '<a>foo</a>');
232 188
233 testHtml('disallows cross-site navigation', 189 testHtml('disallows cross-site navigation', validator,
234 validator, 190 '<a href="http://example.com">example.com</a>', '<a>example.com</a>');
235 '<a href="http://example.com">example.com</a>',
236 '<a>example.com</a>');
237 191
238 testHtml('blocks other elements', 192 testHtml('blocks other elements', validator,
239 validator, 193 '<a href="#foo"><b>foo</b></a>', '<a href="#foo"></a>');
240 '<a href="#foo"><b>foo</b></a>',
241 '<a href="#foo"></a>');
242 194
243 testHtml('blocks tag extension', 195 testHtml('blocks tag extension', validator, '<a is="x-foo"></a>', '');
244 validator,
245 '<a is="x-foo"></a>',
246 '');
247 }); 196 });
248 197
249 group('allowImages', () { 198 group('allowImages', () {
250 var validator = new NodeValidatorBuilder()..allowImages(); 199 var validator = new NodeValidatorBuilder()..allowImages();
251 200
252 testHtml('allows images', 201 testHtml('allows images', validator,
253 validator,
254 '<img src="/foo.jpg" alt="something" width="100" height="100"/>'); 202 '<img src="/foo.jpg" alt="something" width="100" height="100"/>');
255 203
256 testHtml('blocks onerror', 204 testHtml('blocks onerror', validator,
257 validator, 205 '<img src="/foo.jpg" onerror="something"/>', '<img src="/foo.jpg"/>');
258 '<img src="/foo.jpg" onerror="something"/>',
259 '<img src="/foo.jpg"/>');
260 206
261 testHtml('enforces same-origin', 207 testHtml('enforces same-origin', validator,
262 validator, 208 '<img src="http://example.com/foo.jpg"/>', '<img/>');
263 '<img src="http://example.com/foo.jpg"/>',
264 '<img/>');
265 }); 209 });
266 210
267 group('allowCustomElement', () { 211 group('allowCustomElement', () {
268 var validator = new NodeValidatorBuilder() 212 var validator = new NodeValidatorBuilder()
269 ..allowCustomElement( 213 ..allowCustomElement('x-foo', attributes: ['bar'], uriAttributes: ['baz'])
270 'x-foo',
271 attributes: ['bar'],
272 uriAttributes: ['baz'])
273 ..allowHtml5(); 214 ..allowHtml5();
274 215
275 testHtml('allows custom elements', 216 testHtml('allows custom elements', validator,
276 validator,
277 '<x-foo bar="something" baz="/foo.jpg"></x-foo>'); 217 '<x-foo bar="something" baz="/foo.jpg"></x-foo>');
278 218
219 testHtml('validates custom tag URIs', validator,
220 '<x-foo baz="http://example.com/foo.jpg"></x-foo>', '<x-foo></x-foo>');
279 221
280 testHtml('validates custom tag URIs', 222 testHtml('blocks type extensions', validator, '<div is="x-foo"></div>', '');
281 validator,
282 '<x-foo baz="http://example.com/foo.jpg"></x-foo>',
283 '<x-foo></x-foo>');
284 223
285 testHtml('blocks type extensions', 224 testHtml('blocks tags on non-matching elements', validator,
286 validator, 225 '<div bar="foo"></div>', '<div></div>');
287 '<div is="x-foo"></div>',
288 '');
289
290 testHtml('blocks tags on non-matching elements',
291 validator,
292 '<div bar="foo"></div>',
293 '<div></div>');
294 }); 226 });
295 227
296 group('identify Uri attributes listed as attributes', () { 228 group('identify Uri attributes listed as attributes', () {
297 var validator = new NodeValidatorBuilder() 229 var validator = new NodeValidatorBuilder()
298 ..allowElement( 230 ..allowElement('a', attributes: ['href']);
299 'a',
300 attributes: ['href']);
301 231
302 testHtml('reject different-origin link', 232 testHtml(
303 validator, 233 'reject different-origin link',
234 validator,
304 '<a href="http://www.google.com/foo">Google-Foo</a>', 235 '<a href="http://www.google.com/foo">Google-Foo</a>',
305 '<a>Google-Foo</a>'); 236 '<a>Google-Foo</a>');
306 }); 237 });
307 238
308 group('allowTagExtension', () { 239 group('allowTagExtension', () {
309 var validator = new NodeValidatorBuilder() 240 var validator = new NodeValidatorBuilder()
310 ..allowTagExtension( 241 ..allowTagExtension('x-foo', 'div',
311 'x-foo', 242 attributes: ['bar'], uriAttributes: ['baz'])
312 'div',
313 attributes: ['bar'],
314 uriAttributes: ['baz'])
315 ..allowHtml5(); 243 ..allowHtml5();
316 244
317 testHtml('allows tag extensions', 245 testHtml('allows tag extensions', validator,
318 validator,
319 '<div is="x-foo" bar="something" baz="/foo.jpg"></div>'); 246 '<div is="x-foo" bar="something" baz="/foo.jpg"></div>');
320 247
321 testHtml('blocks custom elements', 248 testHtml('blocks custom elements', validator, '<x-foo></x-foo>', '');
322 validator,
323 '<x-foo></x-foo>',
324 '');
325 249
326 testHtml('validates tag extension URIs', 250 testHtml(
251 'validates tag extension URIs',
327 validator, 252 validator,
328 '<div is="x-foo" baz="http://example.com/foo.jpg"></div>', 253 '<div is="x-foo" baz="http://example.com/foo.jpg"></div>',
329 '<div is="x-foo"></div>'); 254 '<div is="x-foo"></div>');
330 255
331 testHtml('blocks tags on non-matching elements', 256 testHtml('blocks tags on non-matching elements', validator,
332 validator, 257 '<div bar="foo"></div>', '<div></div>');
333 '<div bar="foo"></div>',
334 '<div></div>');
335 258
336 testHtml('blocks non-matching tags', 259 testHtml('blocks non-matching tags', validator,
337 validator, 260 '<span is="x-foo">something</span>', '');
338 '<span is="x-foo">something</span>',
339 '');
340 261
341 validator = new NodeValidatorBuilder() 262 validator = new NodeValidatorBuilder()
342 ..allowTagExtension( 263 ..allowTagExtension('x-foo', 'div',
343 'x-foo', 264 attributes: ['bar'], uriAttributes: ['baz'])
344 'div', 265 ..allowTagExtension('x-else', 'div');
345 attributes: ['bar'],
346 uriAttributes: ['baz'])
347 ..allowTagExtension(
348 'x-else',
349 'div');
350 266
351 testHtml('blocks tags on non-matching custom elements', 267 testHtml('blocks tags on non-matching custom elements', validator,
352 validator, 268 '<div bar="foo" is="x-else"></div>', '<div is="x-else"></div>');
353 '<div bar="foo" is="x-else"></div>',
354 '<div is="x-else"></div>');
355 }); 269 });
356 270
357 group('allowTemplating', () { 271 group('allowTemplating', () {
358 var validator = new NodeValidatorBuilder() 272 var validator = new NodeValidatorBuilder()
359 ..allowTemplating() 273 ..allowTemplating()
360 ..allowHtml5(); 274 ..allowHtml5();
361 275
362 testHtml('allows templates', 276 testHtml(
363 validator, 277 'allows templates', validator, '<template bind="{{a}}"></template>');
364 '<template bind="{{a}}"></template>');
365 278
366 testHtml('allows template attributes', 279 testHtml('allows template attributes', validator,
367 validator,
368 '<template bind="{{a}}" ref="foo" repeat="{{}}" if="{{}}" syntax="foo">< /template>'); 280 '<template bind="{{a}}" ref="foo" repeat="{{}}" if="{{}}" syntax="foo">< /template>');
369 281
370 testHtml('allows template attribute', 282 testHtml('allows template attribute', validator,
371 validator,
372 '<div template repeat="{{}}"></div>'); 283 '<div template repeat="{{}}"></div>');
373 284
374 testHtml('blocks illegal template attribute', 285 testHtml('blocks illegal template attribute', validator,
375 validator, 286 '<div template="foo" repeat="{{}}"></div>', '<div></div>');
376 '<div template="foo" repeat="{{}}"></div>',
377 '<div></div>');
378 }); 287 });
379 288
380 group('allowSvg', () { 289 group('allowSvg', () {
381 var validator = new NodeValidatorBuilder() 290 var validator = new NodeValidatorBuilder()
382 ..allowSvg() 291 ..allowSvg()
383 ..allowTextElements(); 292 ..allowTextElements();
384 293
385 testHtml('allows basic SVG', 294 testHtml(
386 validator, 295 'allows basic SVG',
387 '<svg xmlns="http://www.w3.org/2000/svg' 296 validator,
388 'xmlns:xlink="http://www.w3.org/1999/xlink">' 297 '<svg xmlns="http://www.w3.org/2000/svg'
298 'xmlns:xlink="http://www.w3.org/1999/xlink">'
389 '<image xlink:href="foo" data-foo="bar"/>' 299 '<image xlink:href="foo" data-foo="bar"/>'
390 '</svg>'); 300 '</svg>');
391 301
392 testHtml('blocks script elements', 302 testHtml(
393 validator, 303 'blocks script elements',
394 '<svg xmlns="http://www.w3.org/2000/svg>' 304 validator,
305 '<svg xmlns="http://www.w3.org/2000/svg>'
395 '<script></script>' 306 '<script></script>'
396 '</svg>', 307 '</svg>',
397 ''); 308 '');
398 309
399 testHtml('blocks script elements but allows other', 310 testHtml(
400 validator, 311 'blocks script elements but allows other',
401 '<svg xmlns="http://www.w3.org/2000/svg>' 312 validator,
313 '<svg xmlns="http://www.w3.org/2000/svg>'
402 '<script></script><ellipse cx="200" cy="80" rx="100" ry="50"></ellipse>' 314 '<script></script><ellipse cx="200" cy="80" rx="100" ry="50"></ellipse>'
403 '</svg>', 315 '</svg>',
404 '<svg xmlns="http://www.w3.org/2000/svg>' 316 '<svg xmlns="http://www.w3.org/2000/svg>'
405 '<ellipse cx="200" cy="80" rx="100" ry="50"></ellipse>' 317 '<ellipse cx="200" cy="80" rx="100" ry="50"></ellipse>'
406 '</svg>'); 318 '</svg>');
407 319
408 testHtml('blocks script handlers', 320 testHtml(
409 validator, 321 'blocks script handlers',
410 '<svg xmlns="http://www.w3.org/2000/svg' 322 validator,
411 'xmlns:xlink="http://www.w3.org/1999/xlink">' 323 '<svg xmlns="http://www.w3.org/2000/svg'
324 'xmlns:xlink="http://www.w3.org/1999/xlink">'
412 '<image xlink:href="foo" onerror="something"/>' 325 '<image xlink:href="foo" onerror="something"/>'
413 '</svg>', 326 '</svg>',
414 '<svg xmlns="http://www.w3.org/2000/svg' 327 '<svg xmlns="http://www.w3.org/2000/svg'
415 'xmlns:xlink="http://www.w3.org/1999/xlink">' 328 'xmlns:xlink="http://www.w3.org/1999/xlink">'
416 '<image xlink:href="foo"/>' 329 '<image xlink:href="foo"/>'
417 '</svg>'); 330 '</svg>');
418 331
419 testHtml('blocks foreignObject content', 332 testHtml(
420 validator, 333 'blocks foreignObject content',
421 '<svg xmlns="http://www.w3.org/2000/svg">' 334 validator,
335 '<svg xmlns="http://www.w3.org/2000/svg">'
422 '<foreignobject width="100" height="150">' 336 '<foreignobject width="100" height="150">'
423 '<body xmlns="http://www.w3.org/1999/xhtml">' 337 '<body xmlns="http://www.w3.org/1999/xhtml">'
424 '<div>Some content</div>' 338 '<div>Some content</div>'
425 '</body>' 339 '</body>'
426 '</foreignobject>' 340 '</foreignobject>'
427 '<b>42</b>' 341 '<b>42</b>'
428 '</svg>', 342 '</svg>',
429 '<svg xmlns="http://www.w3.org/2000/svg">' 343 '<svg xmlns="http://www.w3.org/2000/svg">'
430 '<b>42</b>' 344 '<b>42</b>'
431 '</svg>'); 345 '</svg>');
432 }); 346 });
433 347
434 group('allowInlineStyles', () { 348 group('allowInlineStyles', () {
435 var validator = new NodeValidatorBuilder() 349 var validator = new NodeValidatorBuilder()
436 ..allowTextElements() 350 ..allowTextElements()
437 ..allowInlineStyles(); 351 ..allowInlineStyles();
438 352
439 testHtml('allows inline styles', 353 testHtml('allows inline styles', validator,
440 validator,
441 '<span style="background-color:red">text</span>'); 354 '<span style="background-color:red">text</span>');
442 355
443 testHtml('blocks other attributes', 356 testHtml('blocks other attributes', validator,
444 validator, 357 '<span class="red-span"></span>', '<span></span>');
445 '<span class="red-span"></span>',
446 '<span></span>');
447 358
448 validator = new NodeValidatorBuilder() 359 validator = new NodeValidatorBuilder()
449 ..allowTextElements() 360 ..allowTextElements()
450 ..allowInlineStyles(tagName: 'span'); 361 ..allowInlineStyles(tagName: 'span');
451 362
452 testHtml('scoped allows inline styles on spans', 363 testHtml('scoped allows inline styles on spans', validator,
453 validator,
454 '<span style="background-color:red">text</span>'); 364 '<span style="background-color:red">text</span>');
455 365
456 testHtml('scoped blocks inline styles on LIs', 366 testHtml('scoped blocks inline styles on LIs', validator,
457 validator, 367 '<li style="background-color:red">text</li>', '<li>text</li>');
458 '<li style="background-color:red">text</li>',
459 '<li>text</li>');
460 }); 368 });
461 369
462 group('throws', () { 370 group('throws', () {
463 var validator = new NodeValidator.throws(new NodeValidatorBuilder.common()); 371 var validator = new NodeValidator.throws(new NodeValidatorBuilder.common());
464 372
465 var validationError = throwsArgumentError; 373 var validationError = throwsArgumentError;
466 374
467 test('does not throw on valid syntax', () { 375 test('does not throw on valid syntax', () {
468 expect(() { 376 expect(() {
469 document.body.createFragment('<div></div>', validator: validator); 377 document.body.createFragment('<div></div>', validator: validator);
470 }, returnsNormally); 378 }, returnsNormally);
471 }); 379 });
472 380
473 test('throws on invalid elements', () { 381 test('throws on invalid elements', () {
474 expect(() { 382 expect(() {
475 document.body.createFragment('<foo></foo>', validator: validator); 383 document.body.createFragment('<foo></foo>', validator: validator);
476 }, validationError); 384 }, validationError);
477 }); 385 });
478 386
479 test('throws on invalid attributes', () { 387 test('throws on invalid attributes', () {
480 expect(() { 388 expect(() {
481 document.body.createFragment('<div foo="bar"></div>', 389 document.body
482 validator: validator); 390 .createFragment('<div foo="bar"></div>', validator: validator);
483 }, validationError); 391 }, validationError);
484 }); 392 });
485 393
486 test('throws on invalid attribute values', () { 394 test('throws on invalid attribute values', () {
487 expect(() { 395 expect(() {
488 document.body.createFragment('<img src="http://example.com/foo.jpg"/>', 396 document.body.createFragment('<img src="http://example.com/foo.jpg"/>',
489 validator: validator); 397 validator: validator);
490 }, validationError); 398 }, validationError);
491 }); 399 });
492 }); 400 });
493 401
494 group('svg', () { 402 group('svg', () {
495 test('parsing', () { 403 test('parsing', () {
496 var svgText = 404 var svgText = '<svg xmlns="http://www.w3.org/2000/svg'
497 '<svg xmlns="http://www.w3.org/2000/svg' 405 'xmlns:xlink="http://www.w3.org/1999/xlink">'
498 'xmlns:xlink="http://www.w3.org/1999/xlink">'
499 '<image xlink:href="foo" data-foo="bar"/>' 406 '<image xlink:href="foo" data-foo="bar"/>'
500 '</svg>'; 407 '</svg>';
501 408
502 var fragment = new DocumentFragment.svg(svgText); 409 var fragment = new DocumentFragment.svg(svgText);
503 var element = fragment.nodes.first as Element; 410 var element = fragment.nodes.first as Element;
504 expect(element is svg.SvgSvgElement, isTrue); 411 expect(element is svg.SvgSvgElement, isTrue);
505 expect(element.children[0] is svg.ImageElement, isTrue); 412 expect(element.children[0] is svg.ImageElement, isTrue);
506 }); 413 });
507 }); 414 });
508 415
509 group('dom_clobbering', () { 416 group('dom_clobbering', () {
510 var validator = new NodeValidatorBuilder.common(); 417 var validator = new NodeValidatorBuilder.common();
511 418
512 testHtml('DOM clobbering of attributes with single node', 419 testHtml(
513 validator, 420 'DOM clobbering of attributes with single node',
514 "<form id='single_node_clobbering' onmouseover='alert(1)'><input name='attri butes'>", 421 validator,
515 ""); 422 "<form id='single_node_clobbering' onmouseover='alert(1)'><input name='a ttributes'>",
423 "");
516 424
517 testHtml('DOM clobbering of attributes with multiple nodes', 425 testHtml(
518 validator, 426 'DOM clobbering of attributes with multiple nodes',
519 "<form onmouseover='alert(1)'><input name='attributes'>" 427 validator,
520 "<input name='attributes'>", 428 "<form onmouseover='alert(1)'><input name='attributes'>"
521 ""); 429 "<input name='attributes'>",
430 "");
522 431
523 testHtml('DOM clobbering of lastChild', 432 testHtml('DOM clobbering of lastChild', validator,
524 validator, 433 "<form><input name='lastChild'><input onmouseover='alert(1)'>", "");
525 "<form><input name='lastChild'><input onmouseover='alert(1)'>",
526 "");
527 434
528 testHtml('DOM clobbering of both children and lastChild', 435 testHtml(
529 validator, 436 'DOM clobbering of both children and lastChild',
530 "<form><input name='lastChild'><input name='children'>" 437 validator,
531 "<input id='children'><input onmouseover='alert(1)'>", 438 "<form><input name='lastChild'><input name='children'>"
532 ""); 439 "<input id='children'><input onmouseover='alert(1)'>",
440 "");
533 441
534 testHtml('DOM clobbering of both children and lastChild, different order', 442 testHtml(
535 validator, 443 'DOM clobbering of both children and lastChild, different order',
536 "<form><input name='children'><input name='children'>" 444 validator,
537 "<input id='children' name='lastChild'>" 445 "<form><input name='children'><input name='children'>"
538 "<input id='bad' onmouseover='alert(1)'>", 446 "<input id='children' name='lastChild'>"
539 ""); 447 "<input id='bad' onmouseover='alert(1)'>",
448 "");
540 449
541 test('tagName makes containing form invalid', () { 450 test('tagName makes containing form invalid', () {
542 var fragment = document.body.createFragment( 451 var fragment = document.body.createFragment(
543 "<form onmouseover='alert(2)'><input name='tagName'>", 452 "<form onmouseover='alert(2)'><input name='tagName'>",
544 validator: validator); 453 validator: validator);
545 var form = fragment.lastChild as FormElement; 454 var form = fragment.lastChild as FormElement;
546 // If the tagName was clobbered, the sanitizer should have removed 455 // If the tagName was clobbered, the sanitizer should have removed
547 // the whole thing and form is null. 456 // the whole thing and form is null.
548 // If the tagName was not clobbered, then there will be content, 457 // If the tagName was not clobbered, then there will be content,
549 // but the tagName should be the normal value. IE11 has started 458 // but the tagName should be the normal value. IE11 has started
550 // doing this. 459 // doing this.
551 if (form != null) { 460 if (form != null) {
552 expect(form.tagName, 'FORM'); 461 expect(form.tagName, 'FORM');
553 } 462 }
554 }); 463 });
555 464
556 test('tagName without mouseover', () { 465 test('tagName without mouseover', () {
557 var fragment = document.body.createFragment( 466 var fragment = document.body
558 "<form><input name='tagName'>", 467 .createFragment("<form><input name='tagName'>", validator: validator);
559 validator: validator);
560 var form = fragment.lastChild as FormElement; 468 var form = fragment.lastChild as FormElement;
561 // If the tagName was clobbered, the sanitizer should have removed 469 // If the tagName was clobbered, the sanitizer should have removed
562 // the whole thing and form is null. 470 // the whole thing and form is null.
563 // If the tagName was not clobbered, then there will be content, 471 // If the tagName was not clobbered, then there will be content,
564 // but the tagName should be the normal value. 472 // but the tagName should be the normal value.
565 if (form != null) { 473 if (form != null) {
566 expect(form.tagName, 'FORM'); 474 expect(form.tagName, 'FORM');
567 } 475 }
568 }); 476 });
569 }); 477 });
570 } 478 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698