2010-12-08 Abhishek Arya <inferno@chromium.org>
authorinferno@chromium.org <inferno@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Dec 2010 23:31:04 +0000 (23:31 +0000)
committerinferno@chromium.org <inferno@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Dec 2010 23:31:04 +0000 (23:31 +0000)
        Reviewed by Dimitri Glazkov.

        Detach node iterator and move to new document when node gets moved.
        https://bugs.webkit.org/show_bug.cgi?id=50697

        Test: fast/dom/node-iterator-document-moved-crash.html

        * dom/Document.cpp: Method that takes a node and new document as argument.
        It detaches the node iterators belonging to the current document and attaches
        them to the new document.
        (WebCore::Document::moveNodeIteratorsToNewDocument):
        * dom/Document.h: Function definition.
        * dom/Node.cpp: When node is moved to another document, call the function to move
        the iterators appropriately.
        (WebCore::Node::setDocument):
2010-12-08  Abhishek Arya  <inferno@chromium.org>

        Reviewed by Dimitri Glazkov.

        Tests that we do not crash when node iterator gets moved across documents.
        https://bugs.webkit.org/show_bug.cgi?id=50697

        * fast/dom/node-iterator-document-moved-crash-expected.txt: Added.
        * fast/dom/node-iterator-document-moved-crash.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@73559 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/dom/node-iterator-document-moved-crash-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/node-iterator-document-moved-crash.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/dom/Document.cpp
WebCore/dom/Document.h
WebCore/dom/Node.cpp

index 7829f55..3798403 100644 (file)
@@ -1,3 +1,13 @@
+2010-12-08  Abhishek Arya  <inferno@chromium.org>
+
+        Reviewed by Dimitri Glazkov.
+
+        Tests that we do not crash when node iterator gets moved across documents.
+        https://bugs.webkit.org/show_bug.cgi?id=50697
+
+        * fast/dom/node-iterator-document-moved-crash-expected.txt: Added.
+        * fast/dom/node-iterator-document-moved-crash.html: Added.
+
 2010-12-08  Ryosuke Niwa  <rniwa@webkit.org>
 
         Unreviewed Chromium rebaseline for r73548.
diff --git a/LayoutTests/fast/dom/node-iterator-document-moved-crash-expected.txt b/LayoutTests/fast/dom/node-iterator-document-moved-crash-expected.txt
new file mode 100644 (file)
index 0000000..a5960f0
--- /dev/null
@@ -0,0 +1 @@
+ Test passes if it does not crash.
diff --git a/LayoutTests/fast/dom/node-iterator-document-moved-crash.html b/LayoutTests/fast/dom/node-iterator-document-moved-crash.html
new file mode 100644 (file)
index 0000000..c9333da
--- /dev/null
@@ -0,0 +1,42 @@
+<html>\r
+    <head>\r
+        <script>\r
+            if (window.layoutTestController) {\r
+                layoutTestController.dumpAsText();\r
+                layoutTestController.waitUntilDone();\r
+            }\r
+            \r
+            function gc()\r
+            {\r
+                if (window.GCController)\r
+                    return GCController.collect();\r
+\r
+                for (var i = 0; i < 10000; i++) { // force garbage collection (FF requires about 9K allocations before a collect).\r
+                    var s = new String("abc");\r
+                }\r
+            }\r
+            \r
+            function runTest()\r
+            {\r
+                aElement = document.createElement('a');\r
+                divElement = document.createElement('div');\r
+                document.body.appendChild(divElement);\r
+                nodeIterator = win.document.createNodeIterator(aElement);\r
+                win.document.body.appendChild(aElement);\r
+\r
+                delete nodeIterator;\r
+                gc();\r
+                document.body.removeChild(divElement);\r
+                gc();\r
+                \r
+                if (window.layoutTestController)\r
+                    layoutTestController.notifyDone();\r
+            }\r
+        </script>\r
+    </head>\r
+    <body>\r
+        <iframe onload="this.onload = null; win = this.contentWindow; runTest();"></iframe>\r
+        Test passes if it does not crash.\r
+    </body>\r
+</html>\r
+\r
index 950fe82..1790261 100644 (file)
@@ -1,3 +1,21 @@
+2010-12-08  Abhishek Arya  <inferno@chromium.org>
+
+        Reviewed by Dimitri Glazkov.
+
+        Detach node iterator and move to new document when node gets moved.
+        https://bugs.webkit.org/show_bug.cgi?id=50697
+
+        Test: fast/dom/node-iterator-document-moved-crash.html
+
+        * dom/Document.cpp: Method that takes a node and new document as argument.
+        It detaches the node iterators belonging to the current document and attaches
+        them to the new document.
+        (WebCore::Document::moveNodeIteratorsToNewDocument):
+        * dom/Document.h: Function definition.
+        * dom/Node.cpp: When node is moved to another document, call the function to move
+        the iterators appropriately.
+        (WebCore::Node::setDocument):
+
 2010-12-08  James Robinson  <jamesr@chromium.org>
 
         Reviewed by Kenneth Russell.
index 00d32a6..155546a 100644 (file)
@@ -3303,6 +3303,18 @@ void Document::detachNodeIterator(NodeIterator* ni)
     m_nodeIterators.remove(ni);
 }
 
+void Document::moveNodeIteratorsToNewDocument(Node* node, Document* newDocument)
+{
+    HashSet<NodeIterator*> nodeIteratorsList = m_nodeIterators;
+    HashSet<NodeIterator*>::const_iterator nodeIteratorsEnd = nodeIteratorsList.end();
+    for (HashSet<NodeIterator*>::const_iterator it = nodeIteratorsList.begin(); it != nodeIteratorsEnd; ++it) {
+        if ((*it)->referenceNode() == node) {
+            detachNodeIterator(*it);
+            newDocument->attachNodeIterator(*it);
+        }
+    }
+}
+
 void Document::nodeChildrenChanged(ContainerNode* container)
 {
     if (!disableRangeMutation(page())) {
index 2d607c9..f1fe44c 100644 (file)
@@ -684,6 +684,7 @@ public:
 
     void attachNodeIterator(NodeIterator*);
     void detachNodeIterator(NodeIterator*);
+    void moveNodeIteratorsToNewDocument(Node*, Document*);
 
     void attachRange(Range*);
     void detachRange(Range*);
index d6ffc68..216d119 100644 (file)
@@ -446,8 +446,10 @@ void Node::setDocument(Document* document)
         document->addNodeListCache();
     }
 
-    if (m_document)
+    if (m_document) {
+        m_document->moveNodeIteratorsToNewDocument(this, document);
         m_document->selfOnlyDeref();
+    }
 
     m_document = document;