Add a "safe" way to unblock the parser, to protect against CSSLoader

stupidity.  Bug 220542, patch by Blake Kaplan <mrbkap@gmail.com>, r=jst,
sr=bzbarsky
This commit is contained in:
bzbarsky%mit.edu 2005-01-27 19:28:22 +00:00
parent 87576aebdd
commit e9647ed503
4 changed files with 44 additions and 14 deletions

View File

@ -246,7 +246,7 @@ nsContentSink::ScriptAvailable(nsresult aResult,
// script load, assuming that that error code means that the user
// stopped the load through some action (like clicking a link). See
// http://bugzilla.mozilla.org/show_bug.cgi?id=243392.
mParser->ContinueParsing();
mParser->ContinueInterruptedParsing();
}
}
@ -277,7 +277,7 @@ nsContentSink::ScriptEvaluated(nsresult aResult,
}
if (mParser && mParser->IsParserEnabled() && aWasPending) {
mParser->ContinueParsing();
mParser->ContinueInterruptedParsing();
}
return NS_OK;

View File

@ -54,13 +54,15 @@
#include "nsHashtable.h"
#include "nsVoidArray.h"
// {22039D29-2798-4412-9EA6-A11B41BA27D0}
#define NS_IPARSER_IID \
{0x355cbba0, 0xbf7d, 0x11d1, \
{0xaa, 0xd9, 0x00, 0x80, 0x5f, 0x8a, 0x3e, 0x14}}
{ 0x22039d29, 0x2798, 0x4412, \
{ 0x9e, 0xa6, 0xa1, 0x1b, 0x41, 0xba, 0x27, 0xd0 } };
// {41421C60-310A-11d4-816F-000064657374}
#define NS_IDEBUG_DUMP_CONTENT_IID \
{ 0x41421c60, 0x310a, 0x11d4, { 0x81, 0x6f, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } };
{ 0x41421c60, 0x310a, 0x11d4, \
{ 0x81, 0x6f, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } };
class nsIContentSink;
class nsIRequestObserver;
@ -211,11 +213,19 @@ class nsIParser : public nsISupports {
/******************************************************************************************
* Parse methods always begin with an input source, and perform conversions
* until you wind up being emitted to the given contentsink (which may or may not
* be a proxy for the NGLayout content model).
* be a proxy for the NGLayout content model).
******************************************************************************************/
// Call this method to resume the parser from the blocked state..
// Call this method to resume the parser from the blocked state.
NS_IMETHOD ContinueParsing() = 0;
// Call this method to resume the parser from an unblocked state.
// This can happen, for example, if parsing was interrupted and then the
// consumer needed to restart the parser without waiting for more data.
// This also happens after loading scripts, which unblock the parser in
// order to process the output of document.write() and then need to
// continue on with the page load on an enabled parser.
NS_IMETHOD ContinueInterruptedParsing() = 0;
// Stops parsing temporarily.
NS_IMETHOD_(void) BlockParser() = 0;

View File

@ -480,8 +480,9 @@ nsParser::PostContinueEvent()
NS_ERROR("failed to post parser continuation event");
PL_DestroyEvent(ev);
}
else
else {
mFlags |= NS_PARSER_FLAG_PENDING_CONTINUE_EVENT;
}
}
return NS_OK;
}
@ -1412,14 +1413,28 @@ NS_IMETHODIMP nsParser::Terminate(void)
*/
NS_IMETHODIMP nsParser::ContinueParsing()
{
NS_ASSERTION(!(mFlags & NS_PARSER_FLAG_PARSER_ENABLED),
"Trying to continue parsing on a unblocked parser.");
if (mFlags & NS_PARSER_FLAG_PARSER_ENABLED) {
return NS_OK;
}
mFlags |= NS_PARSER_FLAG_PARSER_ENABLED;
return ContinueInterruptedParsing();
}
NS_IMETHODIMP nsParser::ContinueInterruptedParsing()
{
// If the stream has already finished, there's a good chance
// that we might start closing things down when the parser
// is reenabled. To make sure that we're not deleted across
// the reenabling process, hold a reference to ourselves.
nsresult result=NS_OK;
nsCOMPtr<nsIParser> kungFuDeathGrip(this);
nsCOMPtr<nsIParser> kungFuDeathGrip(this);
mFlags |= NS_PARSER_FLAG_PARSER_ENABLED;
NS_ASSERTION(mFlags & NS_PARSER_FLAG_PARSER_ENABLED,
"Don't call ContinueInterruptedParsing on a blocked parser.");
PRBool isFinalChunk=(mParserContext && mParserContext->mStreamListenerState==eOnStop)? PR_TRUE:PR_FALSE;
@ -1456,9 +1471,13 @@ NS_IMETHODIMP_(void) nsParser::BlockParser()
*/
NS_IMETHODIMP_(void) nsParser::UnblockParser()
{
mFlags |= NS_PARSER_FLAG_PARSER_ENABLED;
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: nsParser::UnblockParser(), this=%p\n", this));
MOZ_TIMER_START(mParseTime);
NS_ASSERTION(!(mFlags & NS_PARSER_FLAG_PARSER_ENABLED),
"Trying to unblock an unblocked parser.");
if (!(mFlags & NS_PARSER_FLAG_PARSER_ENABLED)) {
mFlags |= NS_PARSER_FLAG_PARSER_ENABLED;
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: nsParser::UnblockParser(), this=%p\n", this));
MOZ_TIMER_START(mParseTime);
}
}
/**
@ -1486,7 +1505,7 @@ NS_IMETHODIMP_(PRBool) nsParser::IsComplete()
void nsParser::HandleParserContinueEvent() {
mFlags &= ~NS_PARSER_FLAG_PENDING_CONTINUE_EVENT;
ContinueParsing();
ContinueInterruptedParsing();
}
nsresult nsParser::DataAdded(const nsSubstring& aData, nsIRequest *aRequest)

View File

@ -257,6 +257,7 @@ class nsParser : public nsIParser,
* @return current state
*/
NS_IMETHOD ContinueParsing();
NS_IMETHOD ContinueInterruptedParsing();
NS_IMETHOD_(void) BlockParser();
NS_IMETHOD_(void) UnblockParser();
NS_IMETHOD Terminate(void);