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

Side by Side Diff: tools/dom/src/Validators.dart

Issue 2827793002: Format all files under tools and utils directory. (Closed)
Patch Set: Format all files under tools and utils directory. 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
« no previous file with comments | « tools/dom/src/NodeValidatorBuilder.dart ('k') | tools/dom/src/WebGLConstants.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 part of dart.dom.html; 5 part of dart.dom.html;
6 6
7
8 /** 7 /**
9 * Interface used to validate that only accepted elements and attributes are 8 * Interface used to validate that only accepted elements and attributes are
10 * allowed while parsing HTML strings into DOM nodes. 9 * allowed while parsing HTML strings into DOM nodes.
11 * 10 *
12 * In general, customization of validation behavior should be done via the 11 * In general, customization of validation behavior should be done via the
13 * [NodeValidatorBuilder] class to mitigate the chances of incorrectly 12 * [NodeValidatorBuilder] class to mitigate the chances of incorrectly
14 * implementing validation rules. 13 * implementing validation rules.
15 */ 14 */
16 abstract class NodeValidator { 15 abstract class NodeValidator {
17
18 /** 16 /**
19 * Construct a default NodeValidator which only accepts whitelisted HTML5 17 * Construct a default NodeValidator which only accepts whitelisted HTML5
20 * elements and attributes. 18 * elements and attributes.
21 * 19 *
22 * If a uriPolicy is not specified then the default uriPolicy will be used. 20 * If a uriPolicy is not specified then the default uriPolicy will be used.
23 */ 21 */
24 factory NodeValidator({UriPolicy uriPolicy}) => 22 factory NodeValidator({UriPolicy uriPolicy}) =>
25 new _Html5NodeValidator(uriPolicy: uriPolicy); 23 new _Html5NodeValidator(uriPolicy: uriPolicy);
26 24
27 factory NodeValidator.throws(NodeValidator base) => 25 factory NodeValidator.throws(NodeValidator base) =>
(...skipping 17 matching lines...) Expand all
45 /** 43 /**
46 * Performs sanitization of a node tree after construction to ensure that it 44 * Performs sanitization of a node tree after construction to ensure that it
47 * does not contain any disallowed elements or attributes. 45 * does not contain any disallowed elements or attributes.
48 * 46 *
49 * In general custom implementations of this class should not be necessary and 47 * In general custom implementations of this class should not be necessary and
50 * all validation customization should be done in custom NodeValidators, but 48 * all validation customization should be done in custom NodeValidators, but
51 * custom implementations of this class can be created to perform more complex 49 * custom implementations of this class can be created to perform more complex
52 * tree sanitization. 50 * tree sanitization.
53 */ 51 */
54 abstract class NodeTreeSanitizer { 52 abstract class NodeTreeSanitizer {
55
56 /** 53 /**
57 * Constructs a default tree sanitizer which will remove all elements and 54 * Constructs a default tree sanitizer which will remove all elements and
58 * attributes which are not allowed by the provided validator. 55 * attributes which are not allowed by the provided validator.
59 */ 56 */
60 factory NodeTreeSanitizer(NodeValidator validator) => 57 factory NodeTreeSanitizer(NodeValidator validator) =>
61 new _ValidatingTreeSanitizer(validator); 58 new _ValidatingTreeSanitizer(validator);
62 59
63 /** 60 /**
64 * Called with the root of the tree which is to be sanitized. 61 * Called with the root of the tree which is to be sanitized.
65 * 62 *
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 * (such as https://example.com:80). 115 * (such as https://example.com:80).
119 */ 116 */
120 class _SameOriginUriPolicy implements UriPolicy { 117 class _SameOriginUriPolicy implements UriPolicy {
121 final AnchorElement _hiddenAnchor = new AnchorElement(); 118 final AnchorElement _hiddenAnchor = new AnchorElement();
122 final Location _loc = window.location; 119 final Location _loc = window.location;
123 120
124 bool allowsUri(String uri) { 121 bool allowsUri(String uri) {
125 _hiddenAnchor.href = uri; 122 _hiddenAnchor.href = uri;
126 // IE leaves an empty hostname for same-origin URIs. 123 // IE leaves an empty hostname for same-origin URIs.
127 return (_hiddenAnchor.hostname == _loc.hostname && 124 return (_hiddenAnchor.hostname == _loc.hostname &&
128 _hiddenAnchor.port == _loc.port && 125 _hiddenAnchor.port == _loc.port &&
129 _hiddenAnchor.protocol == _loc.protocol) || 126 _hiddenAnchor.protocol == _loc.protocol) ||
130 (_hiddenAnchor.hostname == '' && 127 (_hiddenAnchor.hostname == '' &&
131 _hiddenAnchor.port == '' && 128 _hiddenAnchor.port == '' &&
132 (_hiddenAnchor.protocol == ':' || _hiddenAnchor.protocol == '')); 129 (_hiddenAnchor.protocol == ':' || _hiddenAnchor.protocol == ''));
133 } 130 }
134 } 131 }
135 132
136
137 class _ThrowsNodeValidator implements NodeValidator { 133 class _ThrowsNodeValidator implements NodeValidator {
138 final NodeValidator validator; 134 final NodeValidator validator;
139 135
140 _ThrowsNodeValidator(this.validator) {} 136 _ThrowsNodeValidator(this.validator) {}
141 137
142 bool allowsElement(Element element) { 138 bool allowsElement(Element element) {
143 if (!validator.allowsElement(element)) { 139 if (!validator.allowsElement(element)) {
144 throw new ArgumentError(Element._safeTagName(element)); 140 throw new ArgumentError(Element._safeTagName(element));
145 } 141 }
146 return true; 142 return true;
147 } 143 }
148 144
149 bool allowsAttribute(Element element, String attributeName, String value) { 145 bool allowsAttribute(Element element, String attributeName, String value) {
150 if (!validator.allowsAttribute(element, attributeName, value)) { 146 if (!validator.allowsAttribute(element, attributeName, value)) {
151 throw new ArgumentError('${Element._safeTagName(element)}[$attributeName=" $value"]'); 147 throw new ArgumentError(
148 '${Element._safeTagName(element)}[$attributeName="$value"]');
152 } 149 }
153 } 150 }
154 } 151 }
155 152
156
157 /** 153 /**
158 * Standard tree sanitizer which validates a node tree against the provided 154 * Standard tree sanitizer which validates a node tree against the provided
159 * validator and removes any nodes or attributes which are not allowed. 155 * validator and removes any nodes or attributes which are not allowed.
160 */ 156 */
161 class _ValidatingTreeSanitizer implements NodeTreeSanitizer { 157 class _ValidatingTreeSanitizer implements NodeTreeSanitizer {
162 NodeValidator validator; 158 NodeValidator validator;
163 _ValidatingTreeSanitizer(this.validator) {} 159 _ValidatingTreeSanitizer(this.validator) {}
164 160
165 void sanitizeTree(Node node) { 161 void sanitizeTree(Node node) {
166 void walk(Node node, Node parent) { 162 void walk(Node node, Node parent) {
(...skipping 11 matching lines...) Expand all
178 // children of node and, but we have no way of getting to the next 174 // children of node and, but we have no way of getting to the next
179 // child, so start again from the last child. 175 // child, so start again from the last child.
180 _removeNode(child, node); 176 _removeNode(child, node);
181 child = null; 177 child = null;
182 nextChild = node.lastChild; 178 nextChild = node.lastChild;
183 } 179 }
184 if (child != null) walk(child, node); 180 if (child != null) walk(child, node);
185 child = nextChild; 181 child = nextChild;
186 } 182 }
187 } 183 }
184
188 walk(node, null); 185 walk(node, null);
189 } 186 }
190 187
191 /// Aggressively try to remove node. 188 /// Aggressively try to remove node.
192 void _removeNode(Node node, Node parent) { 189 void _removeNode(Node node, Node parent) {
193 // If we have the parent, it's presumably already passed more sanitization 190 // If we have the parent, it's presumably already passed more sanitization
194 // or is the fragment, so ask it to remove the child. And if that fails 191 // or is the fragment, so ask it to remove the child. And if that fails
195 // try to set the outer html. 192 // try to set the outer html.
196 if (parent == null) { 193 if (parent == null) {
197 node.remove(); 194 node.remove();
(...skipping 20 matching lines...) Expand all
218 var isAttr; 215 var isAttr;
219 try { 216 try {
220 // If getting/indexing attributes throws, count that as corrupt. 217 // If getting/indexing attributes throws, count that as corrupt.
221 attrs = element.attributes; 218 attrs = element.attributes;
222 isAttr = attrs['is']; 219 isAttr = attrs['is'];
223 var corruptedTest1 = Element._hasCorruptedAttributes(element); 220 var corruptedTest1 = Element._hasCorruptedAttributes(element);
224 221
225 // On IE, erratically, the hasCorruptedAttributes test can return false, 222 // On IE, erratically, the hasCorruptedAttributes test can return false,
226 // even though it clearly is corrupted. A separate copy of the test 223 // even though it clearly is corrupted. A separate copy of the test
227 // inlining just the basic check seems to help. 224 // inlining just the basic check seems to help.
228 corrupted = corruptedTest1 ? true : Element._hasCorruptedAttributesAdditio nalCheck(element); 225 corrupted = corruptedTest1
229 } catch(e) {} 226 ? true
227 : Element._hasCorruptedAttributesAdditionalCheck(element);
228 } catch (e) {}
230 var elementText = 'element unprintable'; 229 var elementText = 'element unprintable';
231 try { 230 try {
232 elementText = element.toString(); 231 elementText = element.toString();
233 } catch(e) {} 232 } catch (e) {}
234 try { 233 try {
235 var elementTagName = Element._safeTagName(element); 234 var elementTagName = Element._safeTagName(element);
236 _sanitizeElement(element, parent, corrupted, elementText, elementTagName, 235 _sanitizeElement(element, parent, corrupted, elementText, elementTagName,
237 attrs, isAttr); 236 attrs, isAttr);
238 } on ArgumentError { // Thrown by _ThrowsNodeValidator 237 } on ArgumentError {
238 // Thrown by _ThrowsNodeValidator
239 rethrow; 239 rethrow;
240 } catch(e) { // Unexpected exception sanitizing -> remove 240 } catch (e) {
241 // Unexpected exception sanitizing -> remove
241 _removeNode(element, parent); 242 _removeNode(element, parent);
242 window.console.warn('Removing corrupted element $elementText'); 243 window.console.warn('Removing corrupted element $elementText');
243 } 244 }
244 } 245 }
245 246
246 /// Having done basic sanity checking on the element, and computed the 247 /// Having done basic sanity checking on the element, and computed the
247 /// important attributes we want to check, remove it if it's not valid 248 /// important attributes we want to check, remove it if it's not valid
248 /// or not allowed, either as a whole or particular attributes. 249 /// or not allowed, either as a whole or particular attributes.
249 void _sanitizeElement(Element element, Node parent, bool corrupted, 250 void _sanitizeElement(Element element, Node parent, bool corrupted,
250 String text, String tag, Map attrs, String isAttr) { 251 String text, String tag, Map attrs, String isAttr) {
251 if (false != corrupted) { 252 if (false != corrupted) {
252 _removeNode(element, parent); 253 _removeNode(element, parent);
253 window.console.warn( 254 window.console
254 'Removing element due to corrupted attributes on <$text>'); 255 .warn('Removing element due to corrupted attributes on <$text>');
255 return; 256 return;
256 } 257 }
257 if (!validator.allowsElement(element)) { 258 if (!validator.allowsElement(element)) {
258 _removeNode(element, parent); 259 _removeNode(element, parent);
259 window.console.warn( 260 window.console.warn('Removing disallowed element <$tag> from $parent');
260 'Removing disallowed element <$tag> from $parent');
261 return; 261 return;
262 } 262 }
263 263
264 if (isAttr != null) { 264 if (isAttr != null) {
265 if (!validator.allowsAttribute(element, 'is', isAttr)) { 265 if (!validator.allowsAttribute(element, 'is', isAttr)) {
266 _removeNode(element, parent); 266 _removeNode(element, parent);
267 window.console.warn('Removing disallowed type extension ' 267 window.console.warn('Removing disallowed type extension '
268 '<$tag is="$isAttr">'); 268 '<$tag is="$isAttr">');
269 return; 269 return;
270 } 270 }
271 } 271 }
272 272
273 // TODO(blois): Need to be able to get all attributes, irrespective of 273 // TODO(blois): Need to be able to get all attributes, irrespective of
274 // XMLNS. 274 // XMLNS.
275 var keys = attrs.keys.toList(); 275 var keys = attrs.keys.toList();
276 for (var i = attrs.length - 1; i >= 0; --i) { 276 for (var i = attrs.length - 1; i >= 0; --i) {
277 var name = keys[i]; 277 var name = keys[i];
278 if (!validator.allowsAttribute(element, name.toLowerCase(), 278 if (!validator.allowsAttribute(
279 attrs[name])) { 279 element, name.toLowerCase(), attrs[name])) {
280 window.console.warn('Removing disallowed attribute ' 280 window.console.warn('Removing disallowed attribute '
281 '<$tag $name="${attrs[name]}">'); 281 '<$tag $name="${attrs[name]}">');
282 attrs.remove(name); 282 attrs.remove(name);
283 } 283 }
284 } 284 }
285 285
286 if (element is TemplateElement) { 286 if (element is TemplateElement) {
287 TemplateElement template = element; 287 TemplateElement template = element;
288 sanitizeTree(template.content); 288 sanitizeTree(template.content);
289 } 289 }
290 } 290 }
291 291
292 /// Sanitize the node and its children recursively. 292 /// Sanitize the node and its children recursively.
293 void sanitizeNode(Node node, Node parent) { 293 void sanitizeNode(Node node, Node parent) {
294 switch (node.nodeType) { 294 switch (node.nodeType) {
295 case Node.ELEMENT_NODE: 295 case Node.ELEMENT_NODE:
296 _sanitizeUntrustedElement(node, parent); 296 _sanitizeUntrustedElement(node, parent);
297 break; 297 break;
298 case Node.COMMENT_NODE: 298 case Node.COMMENT_NODE:
299 case Node.DOCUMENT_FRAGMENT_NODE: 299 case Node.DOCUMENT_FRAGMENT_NODE:
300 case Node.TEXT_NODE: 300 case Node.TEXT_NODE:
301 case Node.CDATA_SECTION_NODE: 301 case Node.CDATA_SECTION_NODE:
302 break; 302 break;
303 default: 303 default:
304 _removeNode(node, parent); 304 _removeNode(node, parent);
305 } 305 }
306 } 306 }
307 } 307 }
OLDNEW
« no previous file with comments | « tools/dom/src/NodeValidatorBuilder.dart ('k') | tools/dom/src/WebGLConstants.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698