summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dom/base/nsDocument.cpp3
-rw-r--r--dom/base/nsIDocument.h38
-rw-r--r--dom/html/nsHTMLDocument.cpp14
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