Bug 1450617: Only allow extending from / to XUL elements. r?bz draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Tue, 03 Apr 2018 08:37:16 +0200
changeset 776485 0cc08cd95ef5821d37768bd14567dfe67047bda0
parent 776484 944db0ad9b251c109966f1236e6603f92101a4c6
child 776486 cb6598552b9b0437858b695f93808d56b7cb53e6
push id104888
push userbmo:emilio@crisal.io
push dateTue, 03 Apr 2018 07:00:14 +0000
reviewersbz
bugs1450617
milestone61.0a1
Bug 1450617: Only allow extending from / to XUL elements. r?bz MozReview-Commit-ID: JaFKQDkLGgw
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsCSSFrameConstructor.h
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -1914,18 +1914,17 @@ nsCSSFrameConstructor::CreateGeneratedCo
       if (content->IsElement()) {
         // If we created any children elements, Servo needs to traverse them, but
         // the root is already set up.
         mPresShell->StyleSet()->StyleNewSubtree(content->AsElement());
       }
     }
   }
 
-  AddFrameConstructionItemsInternal(aState, container, aParentFrame, elemName,
-                                    kNameSpaceID_None, true,
+  AddFrameConstructionItemsInternal(aState, container, aParentFrame, true,
                                     pseudoComputedStyle,
                                     ITEM_IS_GENERATED_CONTENT, nullptr,
                                     aItems);
 }
 
 /****************************************************
  **  BEGIN TABLE SECTION
  ****************************************************/
@@ -5597,18 +5596,16 @@ nsCSSFrameConstructor::DoAddFrameConstru
       flags |= ITEM_IS_WITHIN_SVG_TEXT;
     }
     if (aParentFrame->IsBlockFrame() && aParentFrame->GetParent() &&
         aParentFrame->GetParent()->IsSVGTextFrame()) {
       flags |= ITEM_ALLOWS_TEXT_PATH_CHILD;
     }
   }
   AddFrameConstructionItemsInternal(aState, aContent, aParentFrame,
-                                    aContent->NodeInfo()->NameAtom(),
-                                    aContent->GetNameSpaceID(),
                                     aSuppressWhiteSpaceOptimizations,
                                     aComputedStyle,
                                     flags, aAnonChildren,
                                     aItems);
 }
 
 void
 nsCSSFrameConstructor::AddFrameConstructionItems(nsFrameConstructorState& aState,
@@ -5642,18 +5639,16 @@ nsCSSFrameConstructor::SetAsUndisplayedC
   }
   MOZ_ASSERT(!aIsGeneratedContent, "Should have had pseudo type");
 }
 
 void
 nsCSSFrameConstructor::AddFrameConstructionItemsInternal(nsFrameConstructorState& aState,
                                                          nsIContent* aContent,
                                                          nsContainerFrame* aParentFrame,
-                                                         nsAtom* aTag,
-                                                         int32_t aNameSpaceID,
                                                          bool aSuppressWhiteSpaceOptimizations,
                                                          ComputedStyle* aComputedStyle,
                                                          uint32_t aFlags,
                                                          nsTArray<nsIAnonymousContentCreator::ContentInfo>* aAnonChildren,
                                                          FrameConstructionItemList& aItems)
 {
   NS_PRECONDITION(aContent->IsNodeOfType(nsINode::eTEXT) ||
                   aContent->IsElement(),
@@ -5663,16 +5658,18 @@ nsCSSFrameConstructor::AddFrameConstruct
              aContent->NodeInfo()->NameAtom() == nsGkAtoms::area);
 
   // The following code allows the user to specify the base tag
   // of an element using XBL.  XUL and HTML objects (like boxes, menus, etc.)
   // can then be extended arbitrarily.
   const nsStyleDisplay* display = aComputedStyle->StyleDisplay();
   RefPtr<ComputedStyle> computedStyle(aComputedStyle);
   PendingBinding* pendingBinding = nullptr;
+  nsAtom* tag = aContent->NodeInfo()->NameAtom();
+  int32_t namespaceId = aContent->GetNameSpaceID();
   if (aFlags & ITEM_ALLOW_XBL_BASE) {
     if (display->mBinding) {
       // Ensure that our XBL bindings are installed.
 
       nsXBLService* xblService = nsXBLService::GetInstance();
       if (!xblService)
         return;
 
@@ -5695,17 +5692,25 @@ nsCSSFrameConstructor::AddFrameConstruct
 
       if (resolveStyle) {
         computedStyle =
           mPresShell->StyleSet()->ResolveServoStyle(aContent->AsElement());
       }
 
       display = computedStyle->StyleDisplay();
       aComputedStyle = computedStyle;
-      aTag = mDocument->BindingManager()->ResolveTag(aContent, &aNameSpaceID);
+      if (namespaceId == kNameSpaceID_XUL) {
+        // Only allow overriding from & to XUL.
+        int32_t overridenNamespace;
+        nsAtom* overwrittenTag =
+          mDocument->BindingManager()->ResolveTag(aContent, &overridenNamespace);
+        if (overridenNamespace == kNameSpaceID_XUL) {
+          tag = overwrittenTag;
+        }
+      }
     }
   }
 
   const bool isGeneratedContent = !!(aFlags & ITEM_IS_GENERATED_CONTENT);
 
   // Pre-check for display "none" - if we find that, don't create
   // any frame at all
   if (StyleDisplay::None == display->mDisplay) {
@@ -5766,37 +5771,37 @@ nsCSSFrameConstructor::AddFrameConstruct
     if (!data) {
       // Nothing to do here; suppressed text inside SVG
       return;
     }
   } else {
     Element* element = aContent->AsElement();
 
     // Don't create frames for non-SVG element children of SVG elements.
-    if (aNameSpaceID != kNameSpaceID_SVG &&
+    if (namespaceId != kNameSpaceID_SVG &&
         ((aParentFrame &&
           IsFrameForSVG(aParentFrame) &&
           !aParentFrame->IsFrameOfType(nsIFrame::eSVGForeignObject)) ||
          (aFlags & ITEM_IS_WITHIN_SVG_TEXT))) {
       SetAsUndisplayedContent(aState, aItems, element, computedStyle,
                               isGeneratedContent);
       return;
     }
 
-    data = FindHTMLData(element, aTag, aNameSpaceID, aParentFrame,
+    data = FindHTMLData(element, tag, namespaceId, aParentFrame,
                         computedStyle);
     if (!data) {
-      data = FindXULTagData(element, aTag, aNameSpaceID, computedStyle);
+      data = FindXULTagData(element, tag, namespaceId, computedStyle);
     }
     if (!data) {
-      data = FindMathMLData(element, aTag, aNameSpaceID, computedStyle);
+      data = FindMathMLData(element, tag, namespaceId, computedStyle);
       foundMathMLData = !!data;
     }
     if (!data) {
-      data = FindSVGData(element, aTag, aNameSpaceID, aParentFrame,
+      data = FindSVGData(element, tag, namespaceId, aParentFrame,
                          aFlags & ITEM_IS_WITHIN_SVG_TEXT,
                          aFlags & ITEM_ALLOWS_TEXT_PATH_CHILD,
                          computedStyle);
     }
 
     // Now check for XUL display types
     if (!data) {
       data = FindXULDisplayData(display, element, computedStyle);
@@ -5885,45 +5890,45 @@ nsCSSFrameConstructor::AddFrameConstruct
   }
 
   FrameConstructionItem* item = nullptr;
   if (details && details->Open()) {
     auto* summary = HTMLSummaryElement::FromNodeOrNull(aContent);
     if (summary && summary->IsMainSummary()) {
       // If details is open, the main summary needs to be rendered as if it is
       // the first child, so add the item to the front of the item list.
-      item = aItems.PrependItem(this, data, aContent, aTag, aNameSpaceID,
+      item = aItems.PrependItem(this, data, aContent, tag, namespaceId,
                                 pendingBinding, computedStyle.forget(),
                                 aSuppressWhiteSpaceOptimizations, aAnonChildren);
     }
   }
 
   if (!item) {
-    item = aItems.AppendItem(this, data, aContent, aTag, aNameSpaceID,
+    item = aItems.AppendItem(this, data, aContent, tag, namespaceId,
                              pendingBinding, computedStyle.forget(),
                              aSuppressWhiteSpaceOptimizations, aAnonChildren);
   }
   item->mIsText = isText;
   item->mIsGeneratedContent = isGeneratedContent;
   item->mIsAnonymousContentCreatorContent =
     aFlags & ITEM_IS_ANONYMOUSCONTENTCREATOR_CONTENT;
   if (isGeneratedContent) {
     // We need to keep this alive until the frame takes ownership.
     // This corresponds to the Release in ConstructFramesFromItem.
     item->mContent->AddRef();
   }
   item->mIsRootPopupgroup =
-    aNameSpaceID == kNameSpaceID_XUL && aTag == nsGkAtoms::popupgroup &&
+    namespaceId == kNameSpaceID_XUL && tag == nsGkAtoms::popupgroup &&
     aContent->IsRootOfNativeAnonymousSubtree();
   if (item->mIsRootPopupgroup) {
     aState.mHavePendingPopupgroup = true;
   }
   item->mIsPopup = isPopup;
-  item->mIsForSVGAElement = aNameSpaceID == kNameSpaceID_SVG &&
-                            aTag == nsGkAtoms::a;
+  item->mIsForSVGAElement = namespaceId == kNameSpaceID_SVG &&
+                            tag == nsGkAtoms::a;
 
   if (canHavePageBreak && display->mBreakAfter) {
     AddPageBreakItem(aContent, aItems);
   }
 
   if (bits & FCDATA_IS_INLINE) {
     // To correctly set item->mIsAllInline we need to build up our child items
     // right now.
@@ -8824,18 +8829,16 @@ nsCSSFrameConstructor::ReplicateFixedFra
         nsLayoutUtils::IsProperAncestorFrame(prevCanvasFrame, prevPlaceholder)) {
       // We want to use the same style as the primary style frame for
       // our content
       nsIContent* content = fixed->GetContent();
       ComputedStyle* computedStyle =
         nsLayoutUtils::GetStyleFrame(content)->Style();
       AutoFrameConstructionItemList items(this);
       AddFrameConstructionItemsInternal(state, content, canvasFrame,
-                                        content->NodeInfo()->NameAtom(),
-                                        content->GetNameSpaceID(),
                                         true,
                                         computedStyle,
                                         ITEM_ALLOW_XBL_BASE |
                                           ITEM_ALLOW_PAGE_BREAK,
                                         nullptr, items);
       ConstructFramesFromItemList(state, items, canvasFrame,
                                   /* aParentIsWrapperAnonBox = */ false,
                                   fixedPlaceholders);
@@ -10273,18 +10276,16 @@ nsCSSFrameConstructor::AddFCItemsForAnon
     if (!aAnonymousItems[i].mChildren.IsEmpty()) {
       anonChildren = &aAnonymousItems[i].mChildren;
     }
 
     uint32_t flags = ITEM_ALLOW_XBL_BASE | ITEM_ALLOW_PAGE_BREAK |
                      ITEM_IS_ANONYMOUSCONTENTCREATOR_CONTENT | aExtraFlags;
 
     AddFrameConstructionItemsInternal(aState, content, aFrame,
-                                      content->NodeInfo()->NameAtom(),
-                                      content->GetNameSpaceID(),
                                       true, computedStyle, flags,
                                       anonChildren, aItemsToConstruct);
   }
 }
 
 void
 nsCSSFrameConstructor::ProcessChildren(nsFrameConstructorState& aState,
                                        nsIContent*              aContent,
@@ -11245,18 +11246,16 @@ nsCSSFrameConstructor::CreateListBoxCont
 
     if (StyleDisplay::None == display->mDisplay) {
       *aNewFrame = nullptr;
       return;
     }
 
     AutoFrameConstructionItemList items(this);
     AddFrameConstructionItemsInternal(state, aChild, aParentFrame,
-                                      aChild->NodeInfo()->NameAtom(),
-                                      aChild->GetNameSpaceID(),
                                       true, computedStyle,
                                       ITEM_ALLOW_XBL_BASE, nullptr, items);
     ConstructFramesFromItemList(state, items, aParentFrame,
                                 /* aParentIsWrapperAnonBox = */ false,
                                 frameItems);
 
     nsIFrame* newFrame = frameItems.FirstChild();
     *aNewFrame = newFrame;
@@ -11608,18 +11607,16 @@ nsCSSFrameConstructor::BuildInlineChildI
       content->UnsetFlags(NODE_DESCENDANTS_NEED_FRAMES | NODE_NEEDS_FRAME);
       if (content->IsNodeOfType(nsINode::eCOMMENT) ||
           content->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION)) {
         continue;
       }
 
       RefPtr<ComputedStyle> childContext = ResolveComputedStyle(content);
       AddFrameConstructionItemsInternal(aState, content, nullptr,
-                                        content->NodeInfo()->NameAtom(),
-                                        content->GetNameSpaceID(),
                                         iter.XBLInvolved(), childContext,
                                         flags, nullptr,
                                         aParentItem.mChildItems);
     }
   }
 
   if (!aItemIsWithinSVGText) {
     // Probe for generated content after
--- a/layout/base/nsCSSFrameConstructor.h
+++ b/layout/base/nsCSSFrameConstructor.h
@@ -1520,20 +1520,18 @@ private:
   /* The item is content created by an nsIAnonymousContentCreator frame */
 #define ITEM_IS_ANONYMOUSCONTENTCREATOR_CONTENT 0x20
   // The guts of AddFrameConstructionItems
   // aParentFrame might be null.  If it is, that means it was an
   // inline frame.
   void AddFrameConstructionItemsInternal(nsFrameConstructorState& aState,
                                          nsIContent*              aContent,
                                          nsContainerFrame*        aParentFrame,
-                                         nsAtom*                 aTag,
-                                         int32_t                  aNameSpaceID,
                                          bool                     aSuppressWhiteSpaceOptimizations,
-                                         ComputedStyle*          aComputedStyle,
+                                         ComputedStyle*           aComputedStyle,
                                          uint32_t                 aFlags,
                                          nsTArray<nsIAnonymousContentCreator::ContentInfo>* aAnonChildren,
                                          FrameConstructionItemList& aItems);
 
   /**
    * Construct frames for the given item list and parent frame, and put the
    * resulting frames in aFrameItems.
    */