From a0ffb6e2b2b42e8d6ede780ed34dbafdeda3a2d6 Mon Sep 17 00:00:00 2001 From: Henri Sivonen Date: Sat, 29 Oct 2011 23:14:31 +0300 Subject: [PATCH] Bug 696651 part 1 - Deal more gracefully with the parser getting terminated during document.write() and with document.close() getting called while document.write() is on the call stack. r=Olli.Pettay. --- parser/html/nsHtml5Parser.cpp | 14 +++++++++++++- parser/html/nsHtml5Parser.h | 2 ++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/parser/html/nsHtml5Parser.cpp b/parser/html/nsHtml5Parser.cpp index aeddd48fc539..992c6aa58c0e 100644 --- a/parser/html/nsHtml5Parser.cpp +++ b/parser/html/nsHtml5Parser.cpp @@ -303,6 +303,9 @@ nsHtml5Parser::Parse(const nsAString& aSourceBuffer, return NS_OK; } + mozilla::AutoRestore guard(mInDocumentWrite); + mInDocumentWrite = true; + nsHtml5DependentUTF16Buffer stackBuffer(aSourceBuffer); while (!mBlocked && stackBuffer.hasMore()) { @@ -330,6 +333,11 @@ nsHtml5Parser::Parse(const nsAString& aSourceBuffer, if (mTreeBuilder->HasScript()) { mTreeBuilder->Flush(); // Move ops to the executor mExecutor->FlushDocumentWrite(); // run the ops + // Flushing tree ops can cause all sorts of things. + // Return early if the parser got terminated. + if (mExecutor->IsComplete()) { + return NS_OK; + } } // Ignore suspension requests } @@ -649,9 +657,13 @@ nsHtml5Parser::ParseUntilBlocked() NS_PRECONDITION(!mExecutor->IsFragmentMode(), "ParseUntilBlocked called in fragment mode."); - if (mBlocked || mExecutor->IsComplete() || mExecutor->IsBroken()) { + if (mBlocked || + mExecutor->IsComplete() || + mExecutor->IsBroken() || + mInDocumentWrite) { return; } + NS_ASSERTION(mExecutor->HasStarted(), "Bad life cycle."); mDocWriteSpeculatorActive = false; diff --git a/parser/html/nsHtml5Parser.h b/parser/html/nsHtml5Parser.h index b538f1823f7f..f1cda84be764 100644 --- a/parser/html/nsHtml5Parser.h +++ b/parser/html/nsHtml5Parser.h @@ -354,6 +354,8 @@ class nsHtml5Parser : public nsIParser, */ bool mDocumentClosed; + bool mInDocumentWrite; + // Gecko integration void* mRootContextKey;