From fd7a325bc08f1f027b692181b6c7ab5efaf619aa Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 17 Apr 2020 07:25:14 -0400 Subject: Bug 1422931 - Fix crash with slot element and make webcomponents preference per-doc Tag #1375 --- dom/base/ChildIterator.cpp | 4 +++- dom/base/crashtests/1422931.html | 6 ++++++ dom/base/crashtests/crashtests.list | 1 + dom/base/nsContentUtils.cpp | 2 +- dom/base/nsDocument.cpp | 10 ++++++++++ dom/base/nsDocument.h | 4 +++- dom/base/nsIDocument.h | 8 ++++++++ dom/base/nsTextNode.cpp | 7 +++++++ dom/base/nsTextNode.h | 4 ++++ dom/html/HTMLSlotElement.cpp | 2 +- dom/webidl/Text.webidl | 2 +- 11 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 dom/base/crashtests/1422931.html (limited to 'dom') diff --git a/dom/base/ChildIterator.cpp b/dom/base/ChildIterator.cpp index 7a0a705da..7d3375fef 100644 --- a/dom/base/ChildIterator.cpp +++ b/dom/base/ChildIterator.cpp @@ -12,6 +12,7 @@ #include "nsIAnonymousContentCreator.h" #include "nsIFrame.h" #include "nsCSSAnonBoxes.h" +#include "nsDocument.h" namespace mozilla { namespace dom { @@ -66,7 +67,8 @@ ExplicitChildIterator::ExplicitChildIterator(const nsIContent* aParent, mIsFirst(aStartAtBeginning), mIndexInInserted(0) { - mParentAsSlot = HTMLSlotElement::FromContent(mParent); + mParentAsSlot = nsDocument::IsWebComponentsEnabled(mParent) ? + HTMLSlotElement::FromContent(mParent) : nullptr; } nsIContent* diff --git a/dom/base/crashtests/1422931.html b/dom/base/crashtests/1422931.html new file mode 100644 index 000000000..9f09f41ef --- /dev/null +++ b/dom/base/crashtests/1422931.html @@ -0,0 +1,6 @@ + + + + +
+ diff --git a/dom/base/crashtests/crashtests.list b/dom/base/crashtests/crashtests.list index 8b115fd4d..d451d9384 100644 --- a/dom/base/crashtests/crashtests.list +++ b/dom/base/crashtests/crashtests.list @@ -211,3 +211,4 @@ load 1304437.html pref(clipboard.autocopy,true) load 1385272-1.html pref(dom.webcomponents.customelements.enabled,true) load 1341693.html pref(dom.webcomponents.enabled,true) load 1419799.html +pref(dom.webcomponents.enabled,false) load 1422931.html diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 502c40977..fa34063df 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -7034,7 +7034,7 @@ nsContentUtils::IsContentInsertionPoint(nsIContent* aContent) bool nsContentUtils::HasDistributedChildren(nsIContent* aContent) { - if (!aContent) { + if (!aContent || !nsDocument::IsWebComponentsEnabled(aContent)) { return false; } diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index d69fff863..459ad6bdd 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -1332,6 +1332,10 @@ nsIDocument::nsIDocument() { SetIsInDocument(); + // Set this when document is created and value stays the same for the lifetime + // of the document. + mIsWebComponentsEnabled = nsContentUtils::IsWebComponentsEnabled(); + PR_INIT_CLIST(&mDOMMediaQueryLists); } @@ -5685,6 +5689,12 @@ nsDocument::IsWebComponentsEnabled(JSContext* aCx, JSObject* aObject) return IsWebComponentsEnabled(window); } +bool +nsDocument::IsWebComponentsEnabled(const nsINode* aNode) +{ + return aNode->OwnerDoc()->IsWebComponentsEnabled(); +} + bool nsDocument::IsWebComponentsEnabled(dom::NodeInfo* aNodeInfo) { diff --git a/dom/base/nsDocument.h b/dom/base/nsDocument.h index de2d19cdf..931bdd89d 100644 --- a/dom/base/nsDocument.h +++ b/dom/base/nsDocument.h @@ -793,7 +793,6 @@ public: virtual void NotifyLayerManagerRecreated() override; - private: void AddOnDemandBuiltInUASheet(mozilla::StyleSheet* aSheet); nsRadioGroupStruct* GetRadioGroupInternal(const nsAString& aName) const; @@ -1383,6 +1382,9 @@ protected: public: // Check whether web components are enabled for the global of aObject. static bool IsWebComponentsEnabled(JSContext* aCx, JSObject* aObject); + // Check whether web components are enabled for the document this node belongs + // to. + static bool IsWebComponentsEnabled(const nsINode* aNode); // Check whether web components are enabled for the global of the document // this nodeinfo comes from. static bool IsWebComponentsEnabled(mozilla::dom::NodeInfo* aNodeInfo); diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h index 3088736bd..297a207fc 100644 --- a/dom/base/nsIDocument.h +++ b/dom/base/nsIDocument.h @@ -2885,6 +2885,11 @@ public: --mThrowOnDynamicMarkupInsertionCounter; } + bool IsWebComponentsEnabled() const + { + return mIsWebComponentsEnabled; + } + protected: bool GetUseCounter(mozilla::UseCounter aUseCounter) { @@ -3028,6 +3033,9 @@ protected: // container for per-context fonts (downloadable, SVG, etc.) RefPtr mFontFaceSet; + // True if dom.webcomponents.enabled pref is set when document is created. + bool mIsWebComponentsEnabled : 1; + // Compatibility mode nsCompatibility mCompatMode; diff --git a/dom/base/nsTextNode.cpp b/dom/base/nsTextNode.cpp index 25c2d3525..b488c85b7 100644 --- a/dom/base/nsTextNode.cpp +++ b/dom/base/nsTextNode.cpp @@ -21,6 +21,7 @@ #ifdef DEBUG #include "nsRange.h" #endif +#include "nsDocument.h" using namespace mozilla; using namespace mozilla::dom; @@ -155,6 +156,12 @@ void nsTextNode::UnbindFromTree(bool aDeep, bool aNullParent) nsGenericDOMDataNode::UnbindFromTree(aDeep, aNullParent); } +bool +nsTextNode::IsWebComponentsEnabled(JSContext* aCx, JSObject* aObject) +{ + return nsDocument::IsWebComponentsEnabled(aCx, aObject); +} + #ifdef DEBUG void nsTextNode::List(FILE* out, int32_t aIndent) const diff --git a/dom/base/nsTextNode.h b/dom/base/nsTextNode.h index 488540a82..94b8dbd1d 100644 --- a/dom/base/nsTextNode.h +++ b/dom/base/nsTextNode.h @@ -75,6 +75,10 @@ public: virtual nsIDOMNode* AsDOMNode() override { return this; } + // Need to have a copy here because including nsDocument.h in this file will + // fail to build on Windows. + static bool IsWebComponentsEnabled(JSContext* aCx, JSObject* aObject); + #ifdef DEBUG virtual void List(FILE* out, int32_t aIndent) const override; virtual void DumpContent(FILE* out, int32_t aIndent, bool aDumpAll) const override; diff --git a/dom/html/HTMLSlotElement.cpp b/dom/html/HTMLSlotElement.cpp index 1ffde7274..b13729a09 100644 --- a/dom/html/HTMLSlotElement.cpp +++ b/dom/html/HTMLSlotElement.cpp @@ -16,7 +16,7 @@ NS_NewHTMLSlotElement(already_AddRefed&& aNodeInfo, mozilla::dom::FromParser aFromParser) { RefPtr nodeInfo(aNodeInfo); - if (nsDocument::IsWebComponentsEnabled(nodeInfo)) { + if (nsDocument::IsWebComponentsEnabled(nodeInfo->GetDocument())) { already_AddRefed nodeInfoArg(nodeInfo.forget()); return new mozilla::dom::HTMLSlotElement(nodeInfoArg); } diff --git a/dom/webidl/Text.webidl b/dom/webidl/Text.webidl index c40b71cc5..fb7b5d685 100644 --- a/dom/webidl/Text.webidl +++ b/dom/webidl/Text.webidl @@ -19,7 +19,7 @@ interface Text : CharacterData { }; partial interface Text { - [BinaryName="assignedSlotByMode", Pref="dom.webcomponents.enabled"] + [BinaryName="assignedSlotByMode", Func="nsTextNode::IsWebComponentsEnabled"] readonly attribute HTMLSlotElement? assignedSlot; }; -- cgit v1.2.3