Bug 1118764 - Don't distribute anonymous root content in shadow DOM. r=bz
authorWilliam Chen <wchen@mozilla.com>
Thu, 08 Jan 2015 13:49:51 -0800
changeset 223143 eb4ffa05e89c100b85459f149264b3c2cd9b0461
parent 223142 367eacf58b48ccbee563964a111086fcbc46b6ff
child 223144 17fc30214d848a64c87e87b043566d3499dd1c03
push id10769
push usercbook@mozilla.com
push dateMon, 12 Jan 2015 14:15:52 +0000
treeherderfx-team@0e9765732906 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1118764
milestone37.0a1
Bug 1118764 - Don't distribute anonymous root content in shadow DOM. r=bz
dom/base/FragmentOrElement.cpp
dom/base/ShadowRoot.cpp
dom/base/crashtests/1118764.html
layout/generic/nsPlaceholderFrame.cpp
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -149,17 +149,18 @@ nsIContent::FindFirstNonChromeOnlyAccess
   return nullptr;
 }
 
 nsIContent*
 nsIContent::GetFlattenedTreeParent() const
 {
   nsIContent* parent = GetParent();
 
-  if (nsContentUtils::HasDistributedChildren(parent)) {
+  if (parent && nsContentUtils::HasDistributedChildren(parent) &&
+      nsContentUtils::IsInSameAnonymousTree(parent, this)) {
     // This node is distributed to insertion points, thus we
     // need to consult the destination insertion points list to
     // figure out where this node was inserted in the flattened tree.
     // It may be the case that |parent| distributes its children
     // but the child does not match any insertion points, thus
     // the flattened tree parent is nullptr.
     nsTArray<nsIContent*>* destInsertionPoints = GetExistingDestInsertionPoints();
     parent = destInsertionPoints && !destInsertionPoints->IsEmpty() ?
--- a/dom/base/ShadowRoot.cpp
+++ b/dom/base/ShadowRoot.cpp
@@ -583,18 +583,22 @@ ShadowRoot::IsPooledNode(nsIContent* aCo
                          nsIContent* aHost)
 {
   if (nsContentUtils::IsContentInsertionPoint(aContent) ||
       IsShadowInsertionPoint(aContent)) {
     // Insertion points never end up in the pool.
     return false;
   }
 
-  if (aContainer == aHost) {
-    // Any other child nodes of the host will end up in the pool.
+  if (aContainer == aHost &&
+      nsContentUtils::IsInSameAnonymousTree(aContainer, aContent)) {
+    // Children of the host will end up in the pool. We check to ensure
+    // that the content is in the same anonymous tree as the container
+    // because anonymous content may report its container as the host
+    // but it may not be in the host's child list.
     return true;
   }
 
   if (aContainer && aContainer->IsHTML(nsGkAtoms::content)) {
     // Fallback content will end up in pool if its parent is a child of the host.
     HTMLContentElement* content = static_cast<HTMLContentElement*>(aContainer);
     return content->IsInsertionPoint() && content->MatchedNodes().IsEmpty() &&
            aContainer->GetParentNode() == aHost;
new file mode 100644
--- /dev/null
+++ b/dom/base/crashtests/1118764.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<body>
+<style>
+#foo {
+  overflow: scroll;
+  height: 100px;
+}
+</style>
+<div id="foo">
+Mozilla Firefox<br>
+Mozilla Firefox<br>
+Mozilla Firefox<br>
+Mozilla Firefox<br>
+Mozilla Firefox<br>
+Mozilla Firefox<br>
+Mozilla Firefox<br>
+Mozilla Firefox<br>
+Mozilla Firefox<br>
+Mozilla Firefox<br>
+Mozilla Firefox<br>
+Mozilla Firefox<br>
+Mozilla Firefox<br>
+Mozilla Firefox<br>
+Mozilla Firefox<br>
+Mozilla Firefox<br>
+Mozilla Firefox<br>
+Mozilla Firefox<br>
+<script>
+foo.createShadowRoot().innerHTML = "<content></content>";
+</script>
+</body>
+</html>
--- a/layout/generic/nsPlaceholderFrame.cpp
+++ b/layout/generic/nsPlaceholderFrame.cpp
@@ -189,17 +189,17 @@ nsPlaceholderFrame::CanContinueTextRun()
   return mOutOfFlowFrame->CanContinueTextRun();
 }
 
 nsStyleContext*
 nsPlaceholderFrame::GetParentStyleContext(nsIFrame** aProviderFrame) const
 {
   NS_PRECONDITION(GetParent(), "How can we not have a parent here?");
 
-  nsIContent* parentContent = mContent ? mContent->GetParent() : nullptr;
+  nsIContent* parentContent = mContent ? mContent->GetFlattenedTreeParent() : nullptr;
   if (parentContent) {
     nsStyleContext* sc =
       PresContext()->FrameManager()->GetDisplayContentsStyleFor(parentContent);
     if (sc) {
       *aProviderFrame = nullptr;
       return sc;
     }
   }