OLD | NEW |
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 library validator_test; | 5 library validator_test; |
6 | 6 |
7 import 'dart:async'; | |
8 import 'dart:html'; | 7 import 'dart:html'; |
9 import 'dart:svg' as svg; | 8 import 'dart:svg' as svg; |
10 import 'package:unittest/unittest.dart'; | 9 import 'package:unittest/unittest.dart'; |
11 import 'package:unittest/html_individual_config.dart'; | 10 import 'package:unittest/html_individual_config.dart'; |
12 import 'utils.dart'; | 11 import 'utils.dart'; |
13 | 12 |
14 | 13 |
15 var nullSanitizer = new NullTreeSanitizer(); | 14 var nullSanitizer = new NullTreeSanitizer(); |
16 | 15 |
17 void validateHtml(String html, String reference, NodeValidator validator) { | 16 void validateHtml(String html, String reference, NodeValidator validator) { |
18 var a = document.body.createFragment(html, validator: validator); | 17 var a = document.body.createFragment(html, validator: validator); |
19 var b = document.body.createFragment(reference, | 18 var b = document.body.createFragment(reference, |
20 treeSanitizer: nullSanitizer); | 19 treeSanitizer: nullSanitizer); |
21 | 20 |
| 21 // Prevent a false pass when both the html and the reference both get entirely |
| 22 // deleted, which is technically a match, but unlikely to be what we meant. |
| 23 if (reference != '') { |
| 24 expect(b.childNodes.length > 0, isTrue); |
| 25 } |
22 validateNodeTree(a, b); | 26 validateNodeTree(a, b); |
23 } | 27 } |
24 | 28 |
25 class RecordingUriValidator implements UriPolicy { | 29 class RecordingUriValidator implements UriPolicy { |
26 final List<String> calls = <String>[]; | 30 final List<String> calls = <String>[]; |
27 | 31 |
28 bool allowsUri(String uri) { | 32 bool allowsUri(String uri) { |
29 calls.add('$uri'); | 33 calls.add('$uri'); |
30 return false; | 34 return false; |
31 } | 35 } |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 var template = fragment.nodes.single; | 128 var template = fragment.nodes.single; |
125 | 129 |
126 var expectedContent = document.body.createFragment( | 130 var expectedContent = document.body.createFragment( |
127 '<div></div>' | 131 '<div></div>' |
128 '<img/>'); | 132 '<img/>'); |
129 | 133 |
130 validateNodeTree(template.content, expectedContent); | 134 validateNodeTree(template.content, expectedContent); |
131 }); | 135 }); |
132 }); | 136 }); |
133 | 137 |
134 group('URI sanitization', () { | 138 group('URI_sanitization', () { |
135 var recorder = new RecordingUriValidator(); | 139 var recorder = new RecordingUriValidator(); |
136 var validator = new NodeValidatorBuilder()..allowHtml5(uriPolicy: recorder); | 140 var validator = new NodeValidatorBuilder()..allowHtml5(uriPolicy: recorder); |
137 | 141 |
138 checkUriPolicyCalls(String name, String html, String reference, | 142 checkUriPolicyCalls(String name, String html, String reference, |
139 List<String> expectedCalls) { | 143 List<String> expectedCalls) { |
140 | 144 |
141 test(name, () { | 145 test(name, () { |
142 recorder.reset(); | 146 recorder.reset(); |
143 | 147 |
144 validateHtml(html, reference, validator); | 148 validateHtml(html, reference, validator); |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 '<svg xmlns="http://www.w3.org/2000/svg' | 351 '<svg xmlns="http://www.w3.org/2000/svg' |
348 'xmlns:xlink="http://www.w3.org/1999/xlink">' | 352 'xmlns:xlink="http://www.w3.org/1999/xlink">' |
349 '<image xlink:href="foo" data-foo="bar"/>' | 353 '<image xlink:href="foo" data-foo="bar"/>' |
350 '</svg>'); | 354 '</svg>'); |
351 | 355 |
352 testHtml('blocks script elements', | 356 testHtml('blocks script elements', |
353 validator, | 357 validator, |
354 '<svg xmlns="http://www.w3.org/2000/svg>' | 358 '<svg xmlns="http://www.w3.org/2000/svg>' |
355 '<script></script>' | 359 '<script></script>' |
356 '</svg>', | 360 '</svg>', |
357 '<svg xmlns="http://www.w3.org/2000/svg></svg>'); | 361 ''); |
| 362 |
| 363 testHtml('blocks script elements but allows other', |
| 364 validator, |
| 365 '<svg xmlns="http://www.w3.org/2000/svg>' |
| 366 '<script></script><ellipse cx="200" cy="80" rx="100" ry="50"></ellipse>' |
| 367 '</svg>', |
| 368 '<svg xmlns="http://www.w3.org/2000/svg>' |
| 369 '<ellipse cx="200" cy="80" rx="100" ry="50"></ellipse>' |
| 370 '</svg>'); |
358 | 371 |
359 testHtml('blocks script handlers', | 372 testHtml('blocks script handlers', |
360 validator, | 373 validator, |
361 '<svg xmlns="http://www.w3.org/2000/svg' | 374 '<svg xmlns="http://www.w3.org/2000/svg' |
362 'xmlns:xlink="http://www.w3.org/1999/xlink">' | 375 'xmlns:xlink="http://www.w3.org/1999/xlink">' |
363 '<image xlink:href="foo" onerror="something"/>' | 376 '<image xlink:href="foo" onerror="something"/>' |
364 '</svg>', | 377 '</svg>', |
365 '<svg xmlns="http://www.w3.org/2000/svg' | 378 '<svg xmlns="http://www.w3.org/2000/svg' |
366 'xmlns:xlink="http://www.w3.org/1999/xlink">' | 379 'xmlns:xlink="http://www.w3.org/1999/xlink">' |
367 '<image xlink:href="foo"/>' | 380 '<image xlink:href="foo"/>' |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 'xmlns:xlink="http://www.w3.org/1999/xlink">' | 462 'xmlns:xlink="http://www.w3.org/1999/xlink">' |
450 '<image xlink:href="foo" data-foo="bar"/>' | 463 '<image xlink:href="foo" data-foo="bar"/>' |
451 '</svg>'; | 464 '</svg>'; |
452 | 465 |
453 var fragment = new DocumentFragment.svg(svgText); | 466 var fragment = new DocumentFragment.svg(svgText); |
454 var element = fragment.nodes.first; | 467 var element = fragment.nodes.first; |
455 expect(element is svg.SvgSvgElement, isTrue); | 468 expect(element is svg.SvgSvgElement, isTrue); |
456 expect(element.children[0] is svg.ImageElement, isTrue); | 469 expect(element.children[0] is svg.ImageElement, isTrue); |
457 }); | 470 }); |
458 }); | 471 }); |
| 472 |
| 473 group('dom_clobbering', () { |
| 474 var validator = new NodeValidatorBuilder.common(); |
| 475 |
| 476 testHtml('DOM clobbering of attributes with single node', |
| 477 validator, |
| 478 "<form onmouseover='alert(1)'><input name='attributes'>", |
| 479 ""); |
| 480 |
| 481 testHtml('DOM clobbering of attributes with multiple nodes', |
| 482 validator, |
| 483 "<form onmouseover='alert(1)'><input name='attributes'>" |
| 484 "<input name='attributes'>", |
| 485 ""); |
| 486 |
| 487 testHtml('DOM clobbering of lastChild', |
| 488 validator, |
| 489 "<form><input name='lastChild'><input onmouseover='alert(1)'>", |
| 490 ""); |
| 491 |
| 492 testHtml('DOM clobbering of both children and lastChild', |
| 493 validator, |
| 494 "<form><input name='lastChild'><input name='children'>" |
| 495 "<input id='children'><input onmouseover='alert(1)'>", |
| 496 ""); |
| 497 |
| 498 testHtml('DOM clobbering of both children and lastChild, different order', |
| 499 validator, |
| 500 "<form><input name='children'><input name='children'>" |
| 501 "<input id='children' name='lastChild'>" |
| 502 "<input id='bad' onmouseover='alert(1)'>", |
| 503 ""); |
| 504 |
| 505 testHtml('tagName makes containing form invalid', |
| 506 validator, |
| 507 "<form onmouseover='alert(2)'><input name='tagName'>", |
| 508 ""); |
| 509 |
| 510 testHtml('tagName without mouseover', |
| 511 validator, |
| 512 "<form><input name='tagName'>", |
| 513 ""); |
| 514 }); |
459 } | 515 } |
OLD | NEW |