diff options
-rw-r--r-- | dom/base/nsDocument.cpp | 3 | ||||
-rw-r--r-- | dom/base/nsIDocument.h | 38 | ||||
-rw-r--r-- | dom/html/nsHTMLDocument.cpp | 14 |
3 files changed, 54 insertions, 1 deletions
diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 6c97750b9..9043e409a 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -1329,7 +1329,8 @@ nsIDocument::nsIDocument() mFrameRequestCallbacksScheduled(false), mBidiOptions(IBMBIDI_DEFAULT_BIDI_OPTIONS), mPartID(0), - mUserHasInteracted(false) + mUserHasInteracted(false), + mThrowOnDynamicMarkupInsertionCounter(0) { SetIsInDocument(); diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h index 66f30a6bc..364583c88 100644 --- a/dom/base/nsIDocument.h +++ b/dom/base/nsIDocument.h @@ -2879,6 +2879,22 @@ public: virtual void ScheduleIntersectionObserverNotification() = 0; virtual void NotifyIntersectionObservers() = 0; + bool ShouldThrowOnDynamicMarkupInsertion() + { + return mThrowOnDynamicMarkupInsertionCounter; + } + + void IncrementThrowOnDynamicMarkupInsertionCounter() + { + ++mThrowOnDynamicMarkupInsertionCounter; + } + + void DecrementThrowOnDynamicMarkupInsertionCounter() + { + MOZ_ASSERT(mThrowOnDynamicMarkupInsertionCounter); + --mThrowOnDynamicMarkupInsertionCounter; + } + protected: bool GetUseCounter(mozilla::UseCounter aUseCounter) { @@ -3326,6 +3342,11 @@ protected: uint32_t mBlockDOMContentLoaded; + // Used in conjunction with the create-an-element-for-the-token algorithm to + // prevent custom element constructors from being able to use document.open(), + // document.close(), and document.write() when they are invoked by the parser. + uint32_t mThrowOnDynamicMarkupInsertionCounter; + // Our live MediaQueryLists PRCList mDOMMediaQueryLists; @@ -3399,6 +3420,23 @@ private: uint32_t mMicroTaskLevel; }; +class MOZ_RAII AutoSetThrowOnDynamicMarkupInsertionCounter final { + public: + explicit AutoSetThrowOnDynamicMarkupInsertionCounter( + nsIDocument* aDocument) + : mDocument(aDocument) + { + mDocument->IncrementThrowOnDynamicMarkupInsertionCounter(); + } + + ~AutoSetThrowOnDynamicMarkupInsertionCounter() { + mDocument->DecrementThrowOnDynamicMarkupInsertionCounter(); + } + + private: + nsIDocument* mDocument; +}; + // XXX These belong somewhere else nsresult NS_NewHTMLDocument(nsIDocument** aInstancePtrResult, bool aLoadedAsData = false); diff --git a/dom/html/nsHTMLDocument.cpp b/dom/html/nsHTMLDocument.cpp index 1eeef737a..f530d75e1 100644 --- a/dom/html/nsHTMLDocument.cpp +++ b/dom/html/nsHTMLDocument.cpp @@ -1401,6 +1401,11 @@ nsHTMLDocument::Open(JSContext* cx, return nullptr; } + if (ShouldThrowOnDynamicMarkupInsertion()) { + aError.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return nullptr; + } + // Set up the content type for insertion nsAutoCString contentType; contentType.AssignLiteral("text/html"); @@ -1608,6 +1613,11 @@ nsHTMLDocument::Close(ErrorResult& rv) return; } + if (ShouldThrowOnDynamicMarkupInsertion()) { + rv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return; + } + if (!mParser || !mParser->IsScriptCreated()) { return; } @@ -1683,6 +1693,10 @@ nsHTMLDocument::WriteCommon(JSContext *cx, return NS_ERROR_DOM_INVALID_STATE_ERR; } + if (ShouldThrowOnDynamicMarkupInsertion()) { + return NS_ERROR_DOM_INVALID_STATE_ERR; + } + if (mParserAborted) { // Hixie says aborting the parser doesn't undefine the insertion point. // However, since we null out mParser in that case, we track the |