Diff
Copied: branches/chromium/1229/LayoutTests/fast/frames/out-of-document-iframe-has-child-frame-expected.txt (from rev 127534, trunk/LayoutTests/fast/frames/out-of-document-iframe-has-child-frame-expected.txt) (0 => 128791)
--- branches/chromium/1229/LayoutTests/fast/frames/out-of-document-iframe-has-child-frame-expected.txt (rev 0)
+++ branches/chromium/1229/LayoutTests/fast/frames/out-of-document-iframe-has-child-frame-expected.txt 2012-09-17 19:08:30 UTC (rev 128791)
@@ -0,0 +1,13 @@
+CONSOLE MESSAGE: line 19: NO_MODIFICATION_ALLOWED_ERR: DOM Exception 7: An attempt was made to modify an object where modifications are not allowed.
+This tests that several ways of making an iframe that isn't inserted into a document tree but has a child frame will fail.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS targetFrame1.contentWindow == undefined is true
+PASS targetFrame2.contentWindow == undefined is true
+PASS targetFrame3.contentWindow == undefined is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Copied: branches/chromium/1229/LayoutTests/fast/frames/out-of-document-iframe-has-child-frame.html (from rev 127534, trunk/LayoutTests/fast/frames/out-of-document-iframe-has-child-frame.html) (0 => 128791)
--- branches/chromium/1229/LayoutTests/fast/frames/out-of-document-iframe-has-child-frame.html (rev 0)
+++ branches/chromium/1229/LayoutTests/fast/frames/out-of-document-iframe-has-child-frame.html 2012-09-17 19:08:30 UTC (rev 128791)
@@ -0,0 +1,52 @@
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<div id="main"/>
+<script>
+description("This tests that several ways of making an iframe that isn't inserted into a document tree"
+ + " but has a child frame will fail.");
+
+main = document.getElementById("main");
+
+try {
+ container = main.appendChild(document.createElement("div"));
+ helperFrame = container.appendChild(document.createElement("iframe"));
+ targetFrame1 = document.createElement("iframe");
+
+ helperFrame.contentWindow._onunload_ = function() {
+ container.insertBefore(targetFrame1, helperFrame);
+ }
+
+ main.removeChild(container);
+} catch (e) { }
+shouldBeTrue("targetFrame1.contentWindow == undefined");
+
+try {
+ container = main.appendChild(document.createElement("div"));
+ helperElement = container.appendChild(document.createElement("input"));
+ helperElement.focus();
+ targetFrame2 = document.createElement("iframe");
+
+ helperElement._onblur_ = function() {
+ container.appendChild(targetFrame2);
+ }
+
+ main.removeChild(container);
+} catch (e) { }
+shouldBeTrue("targetFrame2.contentWindow == undefined");
+
+try {
+ container = document.createElement("div");
+ targetFrame3 = container.appendChild(document.createElement("iframe"));
+ helperFrame = targetFrame3.appendChild(document.createElement("iframe"));
+ helperFrame.src = ""
+ document.body.appendChild(container);
+} catch (e) { }
+shouldBeTrue("targetFrame3.contentWindow == undefined");
+
+isSuccessfullyParsed();
+</script>
+</body>
+</html>
Modified: branches/chromium/1229/LayoutTests/fast/innerHTML/innerHTML-iframe-expected.txt (128790 => 128791)
--- branches/chromium/1229/LayoutTests/fast/innerHTML/innerHTML-iframe-expected.txt 2012-09-17 19:07:32 UTC (rev 128790)
+++ branches/chromium/1229/LayoutTests/fast/innerHTML/innerHTML-iframe-expected.txt 2012-09-17 19:08:30 UTC (rev 128791)
@@ -1 +1,2 @@
+CONSOLE MESSAGE: line 12: NO_MODIFICATION_ALLOWED_ERR: DOM Exception 7: An attempt was made to modify an object where modifications are not allowed.
PASS: body and iframe cleared without crashing.
Copied: branches/chromium/1229/LayoutTests/platform/chromium/fast/frames/out-of-document-iframe-has-child-frame-expected.txt (from rev 127534, trunk/LayoutTests/platform/chromium/fast/frames/out-of-document-iframe-has-child-frame-expected.txt) (0 => 128791)
--- branches/chromium/1229/LayoutTests/platform/chromium/fast/frames/out-of-document-iframe-has-child-frame-expected.txt (rev 0)
+++ branches/chromium/1229/LayoutTests/platform/chromium/fast/frames/out-of-document-iframe-has-child-frame-expected.txt 2012-09-17 19:08:30 UTC (rev 128791)
@@ -0,0 +1,13 @@
+CONSOLE MESSAGE: line 19: Uncaught Error: NO_MODIFICATION_ALLOWED_ERR: DOM Exception 7
+This tests that several ways of making an iframe that isn't inserted into a document tree but has a child frame will fail.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS targetFrame1.contentWindow == undefined is true
+PASS targetFrame2.contentWindow == undefined is true
+PASS targetFrame3.contentWindow == undefined is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Modified: branches/chromium/1229/Source/WebCore/dom/ContainerNode.cpp (128790 => 128791)
--- branches/chromium/1229/Source/WebCore/dom/ContainerNode.cpp 2012-09-17 19:07:32 UTC (rev 128790)
+++ branches/chromium/1229/Source/WebCore/dom/ContainerNode.cpp 2012-09-17 19:08:30 UTC (rev 128791)
@@ -352,8 +352,9 @@
// fire removed from document mutation events.
dispatchChildRemovalEvents(child);
- ChildFrameDisconnector(child).disconnect();
}
+
+ ChildFrameDisconnector(container, ChildFrameDisconnector::DoNotIncludeRoot).disconnect();
}
void ContainerNode::disconnectDescendantFrames()
@@ -384,14 +385,7 @@
}
RefPtr<Node> child = oldChild;
- willRemoveChild(child.get());
- // Mutation events might have moved this child into a different parent.
- if (child->parentNode() != this) {
- ec = NOT_FOUND_ERR;
- return false;
- }
-
document()->removeFocusedNodeOfSubtree(child.get());
#if ENABLE(FULLSCREEN_API)
@@ -405,6 +399,14 @@
return false;
}
+ willRemoveChild(child.get());
+
+ // Mutation events might have moved this child into a different parent.
+ if (child->parentNode() != this) {
+ ec = NOT_FOUND_ERR;
+ return false;
+ }
+
Node* prev = child->previousSibling();
Node* next = child->nextSibling();
removeBetween(prev, next, child.get());
@@ -470,10 +472,6 @@
// The container node can be removed from event handlers.
RefPtr<ContainerNode> protect(this);
- // Do any prep work needed before actually starting to detach
- // and remove... e.g. stop loading frames, fire unload events.
- willRemoveChildren(protect.get());
-
// exclude this node when looking for removed focusedNode since only children will be removed
document()->removeFocusedNodeOfSubtree(this, true);
@@ -481,6 +479,10 @@
document()->removeFullScreenElementOfSubtree(this, true);
#endif
+ // Do any prep work needed before actually starting to detach
+ // and remove... e.g. stop loading frames, fire unload events.
+ willRemoveChildren(protect.get());
+
forbidEventDispatch();
Vector<RefPtr<Node>, 10> removedChildren;
removedChildren.reserveInitialCapacity(childNodeCount());
Modified: branches/chromium/1229/Source/WebCore/dom/ContainerNodeAlgorithms.cpp (128790 => 128791)
--- branches/chromium/1229/Source/WebCore/dom/ContainerNodeAlgorithms.cpp 2012-09-17 19:07:32 UTC (rev 128790)
+++ branches/chromium/1229/Source/WebCore/dom/ContainerNodeAlgorithms.cpp 2012-09-17 19:08:30 UTC (rev 128791)
@@ -110,7 +110,7 @@
void ChildFrameDisconnector::collectDescendant(ElementShadow* shadow)
{
for (ShadowRoot* root = shadow->youngestShadowRoot(); root; root = root->olderShadowRoot())
- collectDescendant(root);
+ collectDescendant(root, IncludeRoot);
}
void ChildFrameDisconnector::Target::disconnect()
Modified: branches/chromium/1229/Source/WebCore/dom/ContainerNodeAlgorithms.h (128790 => 128791)
--- branches/chromium/1229/Source/WebCore/dom/ContainerNodeAlgorithms.h 2012-09-17 19:07:32 UTC (rev 128790)
+++ branches/chromium/1229/Source/WebCore/dom/ContainerNodeAlgorithms.h 2012-09-17 19:08:30 UTC (rev 128791)
@@ -281,13 +281,37 @@
class ChildFrameDisconnector {
public:
- explicit ChildFrameDisconnector(Node* root);
+ enum ShouldIncludeRoot {
+ DoNotIncludeRoot,
+ IncludeRoot
+ };
+
+ explicit ChildFrameDisconnector(Node* root, ShouldIncludeRoot shouldIncludeRoot = IncludeRoot)
+ : m_root(root)
+ {
+ collectDescendant(m_root, shouldIncludeRoot);
+ rootNodes().add(m_root);
+ }
+
+ ~ChildFrameDisconnector()
+ {
+ rootNodes().remove(m_root);
+ }
+
void disconnect();
+ static bool nodeHasDisconnector(Node*);
+
private:
- void collectDescendant(Node* root);
+ void collectDescendant(Node* root, ShouldIncludeRoot);
void collectDescendant(ElementShadow*);
+ static HashSet<Node*>& rootNodes()
+ {
+ DEFINE_STATIC_LOCAL(HashSet<Node*>, nodes, ());
+ return nodes;
+ }
+
class Target {
public:
Target(HTMLFrameOwnerElement* element)
@@ -305,16 +329,13 @@
};
Vector<Target, 10> m_list;
+ Node* m_root;
};
-inline ChildFrameDisconnector::ChildFrameDisconnector(Node* root)
+inline void ChildFrameDisconnector::collectDescendant(Node* root, ShouldIncludeRoot shouldIncludeRoot)
{
- collectDescendant(root);
-}
-
-inline void ChildFrameDisconnector::collectDescendant(Node* root)
-{
- for (Node* node = root; node; node = node->traverseNextNode(root)) {
+ for (Node* node = shouldIncludeRoot == IncludeRoot ? root : root->firstChild(); node;
+ node = node->traverseNextNode(root)) {
if (!node->isElementNode())
continue;
Element* element = toElement(node);
@@ -335,6 +356,20 @@
}
}
+inline bool ChildFrameDisconnector::nodeHasDisconnector(Node* node)
+{
+ HashSet<Node*>& nodes = rootNodes();
+
+ if (nodes.isEmpty())
+ return false;
+
+ for (; node; node = node->parentNode())
+ if (nodes.contains(node))
+ return true;
+
+ return false;
+}
+
} // namespace WebCore
#endif // ContainerNodeAlgorithms_h
Modified: branches/chromium/1229/Source/WebCore/dom/Node.cpp (128790 => 128791)
--- branches/chromium/1229/Source/WebCore/dom/Node.cpp 2012-09-17 19:07:32 UTC (rev 128790)
+++ branches/chromium/1229/Source/WebCore/dom/Node.cpp 2012-09-17 19:08:30 UTC (rev 128791)
@@ -40,6 +40,7 @@
#include "CSSStyleSheet.h"
#include "ChildNodeList.h"
#include "ClassNodeList.h"
+#include "ContainerNodeAlgorithms.h"
#include "ContextMenuController.h"
#include "DOMImplementation.h"
#include "DOMSettableTokenList.h"
@@ -1199,6 +1200,11 @@
ec = HIERARCHY_REQUEST_ERR;
return;
}
+
+ if (newParent->inDocument() && ChildFrameDisconnector::nodeHasDisconnector(newParent)) {
+ ec = NO_MODIFICATION_ALLOWED_ERR;
+ return;
+ }
}
void Node::checkReplaceChild(Node* newChild, Node* oldChild, ExceptionCode& ec)
Modified: branches/chromium/1229/Source/WebCore/html/HTMLFrameElementBase.cpp (128790 => 128791)
--- branches/chromium/1229/Source/WebCore/html/HTMLFrameElementBase.cpp 2012-09-17 19:07:32 UTC (rev 128790)
+++ branches/chromium/1229/Source/WebCore/html/HTMLFrameElementBase.cpp 2012-09-17 19:08:30 UTC (rev 128791)
@@ -161,9 +161,10 @@
return InsertionDone;
}
-void HTMLFrameElementBase::didNotifySubtreeInsertions(ContainerNode* insertionPoint)
+void HTMLFrameElementBase::didNotifySubtreeInsertions(ContainerNode*)
{
- ASSERT_UNUSED(insertionPoint, insertionPoint->inDocument());
+ if (!inDocument())
+ return;
// DocumentFragments don't kick of any loads.
if (!document()->frame())