2011-01-07 Ryosuke Niwa <rniwa@webkit.org>
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 8 Jan 2011 00:49:52 +0000 (00:49 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 8 Jan 2011 00:49:52 +0000 (00:49 +0000)
        Reviewed by Ojan Vafai.

        Adopting an iframe to a child frame results in stack overflow
        https://bugs.webkit.org/show_bug.cgi?id=52018

        Throws an exception when a document adopts an iframe that is an ancestor
        of the document in the frame hierarchy. New behavior matches that of Firefox.

        Test: fast/html/adopt-parent-frame.html

        * dom/Document.cpp:
        (WebCore::Document::adoptNode):
2011-01-07  Ryosuke Niwa  <rniwa@webkit.org>

        Reviewed by Ojan Vafai.

        Adopting an iframe to a child frame results in stack overflow
        https://bugs.webkit.org/show_bug.cgi?id=52018

        Added a test to ensure calling adoptNode with an iframe throws an exception
        if the adoptee is an ancestor of the document adopting the node in the frame hierarchy.

        * fast/html/adopt-parent-frame-expected.txt: Added.
        * fast/html/adopt-parent-frame.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/fast/html/adopt-parent-frame-expected.txt [new file with mode: 0644]
LayoutTests/fast/html/adopt-parent-frame.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/dom/Document.cpp

index 95f6c20..2356565 100644 (file)
@@ -1,3 +1,16 @@
+2011-01-07  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Reviewed by Ojan Vafai.
+
+        Adopting an iframe to a child frame results in stack overflow
+        https://bugs.webkit.org/show_bug.cgi?id=52018
+
+        Added a test to ensure calling adoptNode with an iframe throws an exception
+        if the adoptee is an ancestor of the document adopting the node in the frame hierarchy.
+
+        * fast/html/adopt-parent-frame-expected.txt: Added.
+        * fast/html/adopt-parent-frame.html: Added.
+
 2011-01-07  Martin Robinson  <mrobinson@igalia.com>
 
         Add a platform-specific baseline for GTK+ after r75257.
diff --git a/LayoutTests/fast/html/adopt-parent-frame-expected.txt b/LayoutTests/fast/html/adopt-parent-frame-expected.txt
new file mode 100644 (file)
index 0000000..3388867
--- /dev/null
@@ -0,0 +1,5 @@
+This tests adopting a parent iframe (i.e. the iframe contains the document into which iframe is adopted). WebKit should not hang and should throw a hierarchy request exception.
+
+Adopting parent frame: PASS
+Adopting grandparent frame: PASS
+
diff --git a/LayoutTests/fast/html/adopt-parent-frame.html b/LayoutTests/fast/html/adopt-parent-frame.html
new file mode 100644 (file)
index 0000000..c3550c0
--- /dev/null
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+<body onload="adopt()">
+<p>This tests adopting a parent iframe (i.e. the iframe contains the document into which iframe is adopted). WebKit should not hang and should throw a hierarchy request exception.</p>
+<div>Adopting parent frame: <span id="child"></span></div>
+<div>Adopting grandparent frame: <span id="grandchild"></span></div>
+<script>
+
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+function createFrame(id, parent) {
+    var iframe = document.createElement('iframe');
+    if (parent)
+        parent.contentDocument.body.appendChild(iframe);
+    else
+        document.body.appendChild(iframe);
+    iframe.contentDocument.body.appendChild(iframe.contentDocument.createTextNode(id));    
+    iframe.contentDocument.body.appendChild(iframe.contentDocument.createElement('br'));
+    iframe.style.width = '70%';
+    iframe.style.height = '40%';
+    return iframe;
+}
+
+var parent = createFrame('parent');
+var child = createFrame('child', parent);
+var grandchild = createFrame('grandchild', child);
+
+function log(id, message) {
+    document.getElementById(id).innerHTML = message;
+}
+
+function testChild(id, action) {
+    try {
+        action();
+    } catch(error) {
+        if (error.name == 'HIERARCHY_REQUEST_ERR')
+            log(id, 'PASS');
+        else
+            log(id, 'FAIL: got ' + error.name + ' but expected HIERARCHY_REQUEST_ERR');
+        return;
+    }
+    log(id, 'FAIL: no exceptions thrown but expected HIERARCHY_REQUEST_ERR');
+}
+
+function adopt() {
+    testChild('child', function () { child.contentDocument.adoptNode(parent); });
+    testChild('grandchild', function () { grandchild.contentDocument.adoptNode(parent); });
+}
+
+</script>
+</body>
+</html>
index 3daff76..2d59cee 100644 (file)
@@ -1,3 +1,18 @@
+2011-01-07  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Reviewed by Ojan Vafai.
+
+        Adopting an iframe to a child frame results in stack overflow
+        https://bugs.webkit.org/show_bug.cgi?id=52018
+
+        Throws an exception when a document adopts an iframe that is an ancestor
+        of the document in the frame hierarchy. New behavior matches that of Firefox.
+
+        Test: fast/html/adopt-parent-frame.html
+
+        * dom/Document.cpp:
+        (WebCore::Document::adoptNode):
+
 2011-01-07  Mihai Parparita  <mihaip@chromium.org>
 
         Reviewed by Darin Fisher.
index d76f7c0..53247f8 100644 (file)
@@ -897,8 +897,14 @@ PassRefPtr<Node> Document::adoptNode(PassRefPtr<Node> source, ExceptionCode& ec)
         break;
     }       
     default:
-        if (source->hasTagName(iframeTag))
-            static_cast<HTMLIFrameElement*>(source.get())->setRemainsAliveOnRemovalFromTree(attached() && source->attached());
+        if (source->hasTagName(iframeTag)) {
+            HTMLIFrameElement* iframe = static_cast<HTMLIFrameElement*>(source.get());
+            if (frame()->tree()->isDescendantOf(iframe->contentFrame())) {
+                ec = HIERARCHY_REQUEST_ERR;
+                return 0;
+            }
+            iframe->setRemainsAliveOnRemovalFromTree(attached() && source->attached());
+        }
 
         if (source->parentNode())
             source->parentNode()->removeChild(source.get(), ec);