Title: [124156] trunk
Revision
124156
Author
morr...@google.com
Date
2012-07-30 19:48:33 -0700 (Mon, 30 Jul 2012)

Log Message

Node::replaceChild() can create bad DOM topology with MutationEvent
https://bugs.webkit.org/show_bug.cgi?id=92619

Reviewed by Ryosuke Niwa.

Source/WebCore:

Node::replaceChild() calls insertBeforeCommon() after dispatching
a MutationEvent event for removeChild(). But insertBeforeCommon()
expects call sites to check the invariant and doesn't have
suffient check. So a MutationEvent handler can let some bad tree
topology to slip into insertBeforeCommon().

This change adds a guard for checking the invariant using
checkReplaceChild() between removeChild() and insertBeforeCommon().

Test: fast/events/mutation-during-replace-child.html

* dom/ContainerNode.cpp:
(WebCore::ContainerNode::replaceChild): Added a guard.

LayoutTests:

* fast/events/mutation-during-replace-child-expected.txt: Added.
* fast/events/mutation-during-replace-child.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (124155 => 124156)


--- trunk/LayoutTests/ChangeLog	2012-07-31 02:46:58 UTC (rev 124155)
+++ trunk/LayoutTests/ChangeLog	2012-07-31 02:48:33 UTC (rev 124156)
@@ -1,3 +1,13 @@
+2012-07-30  MORITA Hajime  <morr...@google.com>
+
+        Node::replaceChild() can create bad DOM topology with MutationEvent
+        https://bugs.webkit.org/show_bug.cgi?id=92619
+
+        Reviewed by Ryosuke Niwa.
+
+        * fast/events/mutation-during-replace-child-expected.txt: Added.
+        * fast/events/mutation-during-replace-child.html: Added.
+
 2012-07-30  Kent Tamura  <tk...@chromium.org>
 
         Fix a popup position issue of fast/forms/date/calendar-picker-appearance.html

Added: trunk/LayoutTests/fast/events/mutation-during-replace-child-expected.txt (0 => 124156)


--- trunk/LayoutTests/fast/events/mutation-during-replace-child-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/events/mutation-during-replace-child-expected.txt	2012-07-31 02:48:33 UTC (rev 124156)
@@ -0,0 +1,10 @@
+Ensures that replaceChild() throws an exception if mutation even handler does something wrong
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS target.replaceChild(newChild, oldChild); threw exception Error: HIERARCHY_REQUEST_ERR: DOM Exception 3.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Property changes on: trunk/LayoutTests/fast/events/mutation-during-replace-child-expected.txt
___________________________________________________________________

Added: svn:eol-style

Added: trunk/LayoutTests/fast/events/mutation-during-replace-child.html (0 => 124156)


--- trunk/LayoutTests/fast/events/mutation-during-replace-child.html	                        (rev 0)
+++ trunk/LayoutTests/fast/events/mutation-during-replace-child.html	2012-07-31 02:48:33 UTC (rev 124156)
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<div>
+  <div id="target">
+    <b></b><b id="oldChild"></b><b></b>
+  </div>
+  <div id="newChild"></div>
+</div>
+
+<script>
+description("Ensures that replaceChild() throws an exception if mutation even handler does something wrong");
+var target = document.getElementById('target');
+var oldChild = document.getElementById('oldChild');
+var newChild = document.getElementById('newChild');
+
+function handler(){
+    document.removeEventListener("DOMNodeRemoved", handler, false);
+    newChild.parentNode.removeChild(newChild);
+    target.parentNode.removeChild(target);
+    newChild.appendChild(target);
+}   
+document.addEventListener("DOMNodeRemoved", handler, false);
+shouldThrow("target.replaceChild(newChild, oldChild);",  "'Error: HIERARCHY_REQUEST_ERR: DOM Exception 3'");
+</script>
+<script src=""
+</body>
+</html>
+
Property changes on: trunk/LayoutTests/fast/events/mutation-during-replace-child.html
___________________________________________________________________

Added: svn:eol-style

Modified: trunk/Source/WebCore/ChangeLog (124155 => 124156)


--- trunk/Source/WebCore/ChangeLog	2012-07-31 02:46:58 UTC (rev 124155)
+++ trunk/Source/WebCore/ChangeLog	2012-07-31 02:48:33 UTC (rev 124156)
@@ -1,3 +1,24 @@
+2012-07-30  MORITA Hajime  <morr...@google.com>
+
+        Node::replaceChild() can create bad DOM topology with MutationEvent
+        https://bugs.webkit.org/show_bug.cgi?id=92619
+
+        Reviewed by Ryosuke Niwa.
+
+        Node::replaceChild() calls insertBeforeCommon() after dispatching
+        a MutationEvent event for removeChild(). But insertBeforeCommon()
+        expects call sites to check the invariant and doesn't have
+        suffient check. So a MutationEvent handler can let some bad tree
+        topology to slip into insertBeforeCommon().
+
+        This change adds a guard for checking the invariant using
+        checkReplaceChild() between removeChild() and insertBeforeCommon().
+
+        Test: fast/events/mutation-during-replace-child.html
+
+        * dom/ContainerNode.cpp:
+        (WebCore::ContainerNode::replaceChild): Added a guard.
+
 2012-07-30  Ryosuke Niwa  <rn...@webkit.org>
 
         Qt Windows build fix attempt after r124098.

Modified: trunk/Source/WebCore/dom/ContainerNode.cpp (124155 => 124156)


--- trunk/Source/WebCore/dom/ContainerNode.cpp	2012-07-31 02:46:58 UTC (rev 124155)
+++ trunk/Source/WebCore/dom/ContainerNode.cpp	2012-07-31 02:48:33 UTC (rev 124156)
@@ -271,6 +271,11 @@
     if (next && (next->previousSibling() == newChild || next == newChild)) // nothing to do
         return true;
 
+    // Does this one more time because removeChild() fires a MutationEvent.
+    checkReplaceChild(newChild.get(), oldChild, ec);
+    if (ec)
+        return false;
+
     NodeVector targets;
     collectChildrenAndRemoveFromOldParent(newChild.get(), targets, ec);
     if (ec)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to