OLD | NEW |
| (Empty) |
1 library safe_dom_test; | |
2 | |
3 import 'dart:async'; | |
4 import 'dart:html'; | |
5 import '../../pkg/unittest/lib/unittest.dart'; | |
6 import '../../pkg/unittest/lib/html_config.dart'; | |
7 | |
8 main() { | |
9 useHtmlConfiguration(); | |
10 | |
11 // Checks to see if any illegal properties were set via script. | |
12 var checkerScript = ''' | |
13 window.addEventListener('message', function(e) { | |
14 if (e.data == 'check_unsafe') { | |
15 if (window.unsafe_value) { | |
16 window.postMessage('unsafe_check_failed', '*'); | |
17 } else { | |
18 window.postMessage('unsafe_check_passed', '*'); | |
19 } | |
20 //window.alert('checking!'); | |
21 } | |
22 }, false); | |
23 '''; | |
24 | |
25 var script = new ScriptElement(); | |
26 script.text = checkerScript; | |
27 document.body.append(script); | |
28 | |
29 var unsafeString = | |
30 '<img src="_.png" onerror="javascript:window.unsafe_value=1;" crap="1"/>'; | |
31 | |
32 test('Safe DOM', () { | |
33 var fragment = createContextualFragment(unsafeString); | |
34 | |
35 expect(isSafe(), completion(true), | |
36 reason: 'Expected no unsafe code executed.'); | |
37 }); | |
38 | |
39 // Make sure that scripts did get executed, so we know our detection works. | |
40 test('Unsafe Execution', () { | |
41 var div = new DivElement(); | |
42 div.unsafeInnerHtml = unsafeString; | |
43 // Crashing DRT ?? | |
44 // var fragment = createContextualFragment(unsafeString); | |
45 // div.append(fragment); | |
46 // document.body.append(div) | |
47 | |
48 expect(isSafe(), completion(false), | |
49 reason: 'Expected unsafe code was executed.'); | |
50 }); | |
51 | |
52 test('Validity', () { | |
53 var fragment = createContextualFragment('<span>content</span>'); | |
54 var div = new DivElement(); | |
55 div.append(fragment); | |
56 | |
57 expect(div.nodes.length, 1); | |
58 expect(div.nodes[0] is SpanElement, isTrue); | |
59 }); | |
60 } | |
61 | |
62 DocumentFragment createContextualFragment(String html, [String contextTag]) { | |
63 var doc = document.implementation.createHtmlDocument(''); | |
64 | |
65 var contextElement; | |
66 if (contextTag != null) { | |
67 contextElement = doc.createElement(contextTag); | |
68 } else { | |
69 contextElement = doc.body; | |
70 } | |
71 | |
72 if (Range.supportsCreateContextualFragment) { | |
73 var range = doc.createRange(); | |
74 range.selectNode(contextElement); | |
75 return range.createContextualFragment(html); | |
76 } else { | |
77 contextElement.unsafeInnerHtml = html; | |
78 var fragment = new DocumentFragment();; | |
79 while (contextElement.firstChild != null) { | |
80 fragment.append(contextElement.firstChild); | |
81 } | |
82 return fragment; | |
83 } | |
84 } | |
85 | |
86 // Delay to wait for the image load to fail. | |
87 const Duration imageLoadDelay = const Duration(milliseconds: 500); | |
88 | |
89 Future<bool> isSafe() { | |
90 return new Future.delayed(imageLoadDelay).then((_) { | |
91 window.postMessage('check_unsafe', '*'); | |
92 }).then((_) { | |
93 return window.onMessage.where( | |
94 (e) => e.data.startsWith('unsafe_check')).first; | |
95 }).then((e) { | |
96 return e.data == 'unsafe_check_passed'; | |
97 }); | |
98 } | |
OLD | NEW |