summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGaming4JC <g4jc@hyperbola.info>2020-01-18 20:26:28 -0500
committerGaming4JC <g4jc@hyperbola.info>2020-01-26 15:50:40 -0500
commit0b6548613a4126193034d38242fb58a231e2c435 (patch)
treeb5e9b790d50f537bb52202c35d3438d4a17751f1
parent004b231d037f08ba1160149b9c2f8cd25b58b396 (diff)
downloaduxp-0b6548613a4126193034d38242fb58a231e2c435.tar.gz
Bug 1378079 - Part 2: Introduce throw-on-dynamic-markup-insertion counter.
Per spec, document objects have a throw-on-dynamic-markup-insertion counter, which is 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. Tag UXP Issue #1344
-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 6c97750b9a..9043e409ae 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 66f30a6bc7..364583c887 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 1eeef737af..f530d75e1e 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