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 part of dart.dom.html; | 5 part of dart.dom.html; |
6 | 6 |
7 | 7 |
8 /** | 8 /** |
9 * Interface used to validate that only accepted elements and attributes are | 9 * Interface used to validate that only accepted elements and attributes are |
10 * allowed while parsing HTML strings into DOM nodes. | 10 * allowed while parsing HTML strings into DOM nodes. |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 */ | 160 */ |
161 class _ValidatingTreeSanitizer implements NodeTreeSanitizer { | 161 class _ValidatingTreeSanitizer implements NodeTreeSanitizer { |
162 NodeValidator validator; | 162 NodeValidator validator; |
163 _ValidatingTreeSanitizer(this.validator) {} | 163 _ValidatingTreeSanitizer(this.validator) {} |
164 | 164 |
165 void sanitizeTree(Node node) { | 165 void sanitizeTree(Node node) { |
166 void walk(Node node, Node parent) { | 166 void walk(Node node, Node parent) { |
167 sanitizeNode(node, parent); | 167 sanitizeNode(node, parent); |
168 | 168 |
169 var child = node.lastChild; | 169 var child = node.lastChild; |
170 while (child != null) { | 170 while (null != child) { |
171 // Child may be removed during the walk. | 171 var nextChild; |
172 var nextChild = child.previousNode; | 172 try { |
173 walk(child, node); | 173 // Child may be removed during the walk, and we may not |
| 174 // even be able to get its previousNode. |
| 175 nextChild = child.previousNode; |
| 176 } catch (e) { |
| 177 // Child appears bad, remove it. We want to check the rest of the |
| 178 // children of node and, but we have no way of getting to the next |
| 179 // child, so start again from the last child. |
| 180 _removeNode(child, node); |
| 181 child = null; |
| 182 nextChild = node.lastChild; |
| 183 } |
| 184 if (child != null) walk(child, node); |
174 child = nextChild; | 185 child = nextChild; |
175 } | 186 } |
176 } | 187 } |
177 walk(node, null); | 188 walk(node, null); |
178 } | 189 } |
179 | 190 |
180 /// Aggressively try to remove node. | 191 /// Aggressively try to remove node. |
181 void _removeNode(Node node, Node parent) { | 192 void _removeNode(Node node, Node parent) { |
182 // If we have the parent, it's presumably already passed more sanitization | 193 // If we have the parent, it's presumably already passed more sanitization |
183 // or is the fragment, so ask it to remove the child. And if that fails | 194 // or is the fragment, so ask it to remove the child. And if that fails |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 case Node.COMMENT_NODE: | 298 case Node.COMMENT_NODE: |
288 case Node.DOCUMENT_FRAGMENT_NODE: | 299 case Node.DOCUMENT_FRAGMENT_NODE: |
289 case Node.TEXT_NODE: | 300 case Node.TEXT_NODE: |
290 case Node.CDATA_SECTION_NODE: | 301 case Node.CDATA_SECTION_NODE: |
291 break; | 302 break; |
292 default: | 303 default: |
293 _removeNode(node, parent); | 304 _removeNode(node, parent); |
294 } | 305 } |
295 } | 306 } |
296 } | 307 } |
OLD | NEW |