From 7431beaec262d502911dc4492f8bcdd3c44c257b Mon Sep 17 00:00:00 2001 From: "alanknight@google.com" Date: Wed, 22 Apr 2015 17:16:01 +0000 Subject: [PATCH] appendHtml and insertAdjacentHtml should be consistently sanitized BUG= R=terry@google.com Review URL: https://codereview.chromium.org//1081973003 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@45351 260f80e4-7a28-3924-810f-c04153c831b5 --- CHANGELOG.md | 8 ++++++- sdk/lib/html/dart2js/html_dart2js.dart | 22 ++++++++++--------- sdk/lib/html/dartium/html_dartium.dart | 12 ++++++---- ...u_suppress_make_the_bug_critical_test.dart | 18 +++++++++++++++ .../impl/impl_DocumentFragment.darttemplate | 6 +++-- .../html/impl/impl_Element.darttemplate | 16 +++++++------- 6 files changed, 57 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d9b4b3b9272..d64bdbdd1c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,14 @@ ### Core library changes +* In dart:html, appendHtml and insertAdjacentHtml now take validator + and treeSanitizer parameters, and the inputs are consistently sanitized. +* List iterators may not throw ConcurrentModificationError as eagerly in + release mode. In checked mode, the modification check is still as eager + as possible. + [r45198](https://code.google.com/p/dart/source/detail?r=45198), * Update experimental Isolate API: - - Make priorty parameters of `Isolate.ping` and `Isolate.kill` methods + - Make priority parameters of `Isolate.ping` and `Isolate.kill` methods a named parameter. - Remove the `Isolate.AS_EVENT` priority. - Add extra `response` parameter to `Isolate.ping` and diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart index 898af6c5484..0e1cf354904 100644 --- a/sdk/lib/html/dart2js/html_dart2js.dart +++ b/sdk/lib/html/dart2js/html_dart2js.dart @@ -9932,8 +9932,10 @@ class DocumentFragment extends Node implements ParentNode { * Parses the specified text as HTML and adds the resulting node after the * last child of this document fragment. */ - void appendHtml(String text) { - this.append(new DocumentFragment.html(text)); + void appendHtml(String text, {NodeValidator validator, + NodeTreeSanitizer, treeSanitizer}) { + this.append(new DocumentFragment.html(text, validator: validator, + treeSanitizer: treeSanitizer)); } /** @@ -12610,8 +12612,10 @@ abstract class Element extends Node implements GlobalEventHandlers, ParentNode, * Parses the specified text as HTML and adds the resulting node after the * last child of this element. */ - void appendHtml(String text) { - this.insertAdjacentHtml('beforeend', text); + void appendHtml(String text, {NodeValidator validator, + NodeTreeSanitizer treeSanitizer}) { + this.insertAdjacentHtml('beforeend', text, validator: validator, + treeSanitizer: treeSanitizer); } /** @@ -12890,12 +12894,10 @@ abstract class Element extends Node implements GlobalEventHandlers, ParentNode, * * [insertAdjacentText] * * [insertAdjacentElement] */ - void insertAdjacentHtml(String where, String html) { - if (JS('bool', '!!#.insertAdjacentHTML', this)) { - _insertAdjacentHtml(where, html); - } else { - _insertAdjacentNode(where, new DocumentFragment.html(html)); - } + void insertAdjacentHtml(String where, String html, {NodeValidator validator, + NodeTreeSanitizer treeSanitizer}) { + _insertAdjacentNode(where, new DocumentFragment.html(html, + validator: validator, treeSanitizer: treeSanitizer)); } @JSName('insertAdjacentHTML') diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart index 50ce4bb19d0..93033247a4a 100644 --- a/sdk/lib/html/dartium/html_dartium.dart +++ b/sdk/lib/html/dartium/html_dartium.dart @@ -9409,8 +9409,10 @@ class DocumentFragment extends Node implements ParentNode { * Parses the specified text as HTML and adds the resulting node after the * last child of this document fragment. */ - void appendHtml(String text) { - this.append(new DocumentFragment.html(text)); + void appendHtml(String text, {NodeValidator validator, + NodeTreeSanitizer, treeSanitizer}) { + this.append(new DocumentFragment.html(text, validator: validator, + treeSanitizer: treeSanitizer)); } /** @@ -12252,8 +12254,10 @@ abstract class Element extends Node implements GlobalEventHandlers, ParentNode, * Parses the specified text as HTML and adds the resulting node after the * last child of this element. */ - void appendHtml(String text) { - this.insertAdjacentHtml('beforeend', text); + void appendHtml(String text, {NodeValidator validator, + NodeTreeSanitizer treeSanitizer}) { + this.insertAdjacentHtml('beforeend', text, validator: validator, + treeSanitizer: treeSanitizer); } /** diff --git a/tests/html/node_validator_important_if_you_suppress_make_the_bug_critical_test.dart b/tests/html/node_validator_important_if_you_suppress_make_the_bug_critical_test.dart index cb0196d7393..4a5fe71550f 100644 --- a/tests/html/node_validator_important_if_you_suppress_make_the_bug_critical_test.dart +++ b/tests/html/node_validator_important_if_you_suppress_make_the_bug_critical_test.dart @@ -137,6 +137,24 @@ main() { validateNodeTree(template.content, expectedContent); }); + + test("appendHtml is sanitized", () { + var html = '
'; + document.body.appendHtml('
'); + var stuff = document.querySelector("#stuff"); + stuff.appendHtml(html); + expect(stuff.childNodes.length, 1); + stuff.remove(); + }); + + test("documentFragment.appendHtml is sanitized", () { + var html = '
'); + expect(fragment.childNodes.length, 1); + expect(fragment.childNodes[0].id, "bad"); + expect(fragment.childNodes[0].childNodes.length, 0); + }); }); group('URI_sanitization', () { diff --git a/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate b/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate index e401956c9ee..d533e49c52d 100644 --- a/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate +++ b/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate @@ -93,8 +93,10 @@ $endif * Parses the specified text as HTML and adds the resulting node after the * last child of this document fragment. */ - void appendHtml(String text) { - this.append(new DocumentFragment.html(text)); + void appendHtml(String text, {NodeValidator validator, + NodeTreeSanitizer, treeSanitizer}) { + this.append(new DocumentFragment.html(text, validator: validator, + treeSanitizer: treeSanitizer)); } /** diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate index 14d6abf14b7..816f2b00902 100644 --- a/tools/dom/templates/html/impl/impl_Element.darttemplate +++ b/tools/dom/templates/html/impl/impl_Element.darttemplate @@ -727,8 +727,10 @@ $(ANNOTATIONS)$(NATIVESPEC)abstract class $CLASSNAME$EXTENDS$IMPLEMENTS { * Parses the specified text as HTML and adds the resulting node after the * last child of this element. */ - void appendHtml(String text) { - this.insertAdjacentHtml('beforeend', text); + void appendHtml(String text, {NodeValidator validator, + NodeTreeSanitizer treeSanitizer}) { + this.insertAdjacentHtml('beforeend', text, validator: validator, + treeSanitizer: treeSanitizer); } /** @@ -1018,12 +1020,10 @@ $if DART2JS * * [insertAdjacentText] * * [insertAdjacentElement] */ - void insertAdjacentHtml(String where, String html) { - if (JS('bool', '!!#.insertAdjacentHTML', this)) { - _insertAdjacentHtml(where, html); - } else { - _insertAdjacentNode(where, new DocumentFragment.html(html)); - } + void insertAdjacentHtml(String where, String html, {NodeValidator validator, + NodeTreeSanitizer treeSanitizer}) { + _insertAdjacentNode(where, new DocumentFragment.html(html, + validator: validator, treeSanitizer: treeSanitizer)); } @JSName('insertAdjacentHTML')