Fix for bug 401613 (Intermittent XML parsing errors with this valid SVG file). r/sr=bz.

git-svn-id: svn://10.0.0.236/trunk@239643 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
peterv%propagandism.org 2007-11-19 10:57:29 +00:00
parent 7ee1c0f9a5
commit 68711c66b9
3 changed files with 68 additions and 46 deletions

View File

@ -315,9 +315,9 @@ nsCrossSiteListenerProxy::HandleStartElement(const PRUnichar *aName,
// We're done processing the prolog.
ForwardRequest(PR_FALSE);
// Block the parser since we don't want to spend more cycles on parsing
// Stop the parser since we don't want to spend more cycles on parsing
// stuff.
return NS_ERROR_HTMLPARSER_BLOCK;
return NS_ERROR_HTMLPARSER_STOPPARSING;
}
NS_IMETHODIMP
@ -480,9 +480,9 @@ nsCrossSiteListenerProxy::WillBuildModel()
if (dtd && !(dtd->GetType() & NS_IPARSER_FLAG_XML)) {
ForwardRequest(PR_FALSE);
// Block the parser since we don't want to spend more cycles on parsing
// Stop the parser since we don't want to spend more cycles on parsing
// stuff.
return NS_ERROR_HTMLPARSER_BLOCK;
return NS_ERROR_HTMLPARSER_STOPPARSING;
}
return NS_OK;

View File

@ -419,11 +419,11 @@ nsExpatDriver::HandleStartElement(const PRUnichar *aValue,
}
if (mSink) {
mInternalState = mSink->
nsresult rv = mSink->
HandleStartElement(aValue, aAtts, attrArrayLength,
XML_GetIdAttributeIndex(mExpatParser),
XML_GetCurrentLineNumber(mExpatParser));
MaybeStopParser();
MaybeStopParser(rv);
}
return NS_OK;
@ -433,10 +433,12 @@ nsresult
nsExpatDriver::HandleEndElement(const PRUnichar *aValue)
{
NS_ASSERTION(mSink, "content sink not found!");
NS_ASSERTION(mInternalState != NS_ERROR_HTMLPARSER_BLOCK,
"Shouldn't block from HandleStartElement.");
if (mSink) {
mInternalState = mSink->HandleEndElement(aValue);
MaybeStopParser();
if (mSink && mInternalState != NS_ERROR_HTMLPARSER_STOPPARSING) {
nsresult rv = mSink->HandleEndElement(aValue);
MaybeStopParser(rv);
}
return NS_OK;
@ -452,8 +454,8 @@ nsExpatDriver::HandleCharacterData(const PRUnichar *aValue,
mCDataText.Append(aValue, aLength);
}
else if (mSink) {
mInternalState = mSink->HandleCharacterData(aValue, aLength);
MaybeStopParser();
nsresult rv = mSink->HandleCharacterData(aValue, aLength);
MaybeStopParser(rv);
}
return NS_OK;
@ -475,8 +477,8 @@ nsExpatDriver::HandleComment(const PRUnichar *aValue)
mInternalSubset.AppendLiteral("-->");
}
else if (mSink) {
mInternalState = mSink->HandleComment(aValue);
MaybeStopParser();
nsresult rv = mSink->HandleComment(aValue);
MaybeStopParser(rv);
}
return NS_OK;
@ -502,8 +504,8 @@ nsExpatDriver::HandleProcessingInstruction(const PRUnichar *aTarget,
mInternalSubset.AppendLiteral("?>");
}
else if (mSink) {
mInternalState = mSink->HandleProcessingInstruction(aTarget, aData);
MaybeStopParser();
nsresult rv = mSink->HandleProcessingInstruction(aTarget, aData);
MaybeStopParser(rv);
}
return NS_OK;
@ -515,8 +517,8 @@ nsExpatDriver::HandleXMLDeclaration(const PRUnichar *aVersion,
PRInt32 aStandalone)
{
if (mSink) {
mInternalState = mSink->HandleXMLDeclaration(aVersion, aEncoding, aStandalone);
MaybeStopParser();
nsresult rv = mSink->HandleXMLDeclaration(aVersion, aEncoding, aStandalone);
MaybeStopParser(rv);
}
return NS_OK;
@ -538,12 +540,13 @@ nsExpatDriver::HandleDefault(const PRUnichar *aValue,
}
else if (mSink) {
PRUint32 i;
for (i = 0; i < aLength && NS_SUCCEEDED(mInternalState); ++i) {
nsresult rv = mInternalState;
for (i = 0; i < aLength && NS_SUCCEEDED(rv); ++i) {
if (aValue[i] == '\n' || aValue[i] == '\r') {
mInternalState = mSink->HandleCharacterData(&aValue[i], 1);
rv = mSink->HandleCharacterData(&aValue[i], 1);
}
}
MaybeStopParser();
MaybeStopParser(rv);
}
return NS_OK;
@ -564,9 +567,9 @@ nsExpatDriver::HandleEndCdataSection()
mInCData = PR_FALSE;
if (mSink) {
mInternalState = mSink->HandleCDataSection(mCDataText.get(),
mCDataText.Length());
MaybeStopParser();
nsresult rv = mSink->HandleCDataSection(mCDataText.get(),
mCDataText.Length());
MaybeStopParser(rv);
}
mCDataText.Truncate();
@ -578,8 +581,8 @@ nsExpatDriver::HandleStartNamespaceDecl(const PRUnichar* aPrefix,
const PRUnichar* aUri)
{
if (mExtendedSink) {
mInternalState = mExtendedSink->HandleStartNamespaceDecl(aPrefix,
aUri);
nsresult rv = mExtendedSink->HandleStartNamespaceDecl(aPrefix, aUri);
MaybeStopParser(rv);
}
return NS_OK;
}
@ -587,8 +590,9 @@ nsExpatDriver::HandleStartNamespaceDecl(const PRUnichar* aPrefix,
nsresult
nsExpatDriver::HandleEndNamespaceDecl(const PRUnichar* aPrefix)
{
if (mExtendedSink) {
mInternalState = mExtendedSink->HandleEndNamespaceDecl(aPrefix);
if (mExtendedSink && mInternalState != NS_ERROR_HTMLPARSER_STOPPARSING) {
nsresult rv = mExtendedSink->HandleEndNamespaceDecl(aPrefix);
MaybeStopParser(rv);
}
return NS_OK;
}
@ -600,9 +604,9 @@ nsExpatDriver::HandleNotationDecl(const PRUnichar* aNotationName,
const PRUnichar* aPubid)
{
if (mExtendedSink) {
mInternalState = mExtendedSink->HandleNotationDecl(aNotationName,
aSysid,
aPubid);
nsresult rv = mExtendedSink->HandleNotationDecl(aNotationName, aSysid,
aPubid);
MaybeStopParser(rv);
}
return NS_OK;
}
@ -615,10 +619,11 @@ nsExpatDriver::HandleUnparsedEntityDecl(const PRUnichar* aEntityName,
const PRUnichar* aNotationName)
{
if (mExtendedSink) {
mInternalState = mExtendedSink->HandleUnparsedEntityDecl(aEntityName,
aSysid,
aPubid,
aNotationName);
nsresult rv = mExtendedSink->HandleUnparsedEntityDecl(aEntityName,
aSysid,
aPubid,
aNotationName);
MaybeStopParser(rv);
}
return NS_OK;
}
@ -634,8 +639,8 @@ nsExpatDriver::HandleStartDoctypeDecl(const PRUnichar* aDoctypeName,
mPublicID = aPubid;
if (mExtendedSink) {
mInternalState = mExtendedSink->HandleStartDTD(aDoctypeName,
aSysid, aPubid);
nsresult rv = mExtendedSink->HandleStartDTD(aDoctypeName, aSysid, aPubid);
MaybeStopParser(rv);
}
if (aHasInternalSubset) {
@ -666,9 +671,9 @@ nsExpatDriver::HandleEndDoctypeDecl()
}
// Note: mInternalSubset already doesn't include the [] around it.
mInternalState = mSink->HandleDoctypeDecl(mInternalSubset, mDoctypeName,
mSystemID, mPublicID, data);
MaybeStopParser();
nsresult rv = mSink->HandleDoctypeDecl(mInternalSubset, mDoctypeName,
mSystemID, mPublicID, data);
MaybeStopParser(rv);
}
mInternalSubset.SetCapacity(0);
@ -1002,9 +1007,7 @@ nsExpatDriver::ParseBuffer(const PRUnichar *aBuffer,
NS_ASSERTION(*aConsumed <= aLength + mExpatBuffered,
"Too many bytes consumed?");
NS_ASSERTION(status != XML_STATUS_SUSPENDED ||
(mInternalState == NS_ERROR_HTMLPARSER_BLOCK ||
mInternalState == NS_ERROR_HTMLPARSER_INTERRUPTED),
NS_ASSERTION(status != XML_STATUS_SUSPENDED || BlockedOrInterrupted(),
"Inconsistent expat suspension state.");
if (status == XML_STATUS_ERROR) {
@ -1399,9 +1402,28 @@ nsExpatDriver::CanContain(PRInt32 aParent,PRInt32 aChild) const
}
void
nsExpatDriver::MaybeStopParser()
nsExpatDriver::MaybeStopParser(nsresult aState)
{
if (BlockedOrInterrupted()) {
XML_StopParser(mExpatParser, XML_TRUE);
if (NS_FAILED(aState)) {
// If we had a failure we want to override NS_ERROR_HTMLPARSER_INTERRUPTED
// and we want to override NS_ERROR_HTMLPARSER_BLOCK but not with
// NS_ERROR_HTMLPARSER_INTERRUPTED.
if (NS_SUCCEEDED(mInternalState) ||
mInternalState == NS_ERROR_HTMLPARSER_INTERRUPTED ||
(mInternalState == NS_ERROR_HTMLPARSER_BLOCK &&
aState != NS_ERROR_HTMLPARSER_INTERRUPTED)) {
mInternalState = aState;
}
// If we get an error then we need to stop Expat (by calling XML_StopParser
// with PR_FALSE as the last argument). If the parser should be blocked or
// interrupted we need to pause Expat (by calling XML_StopParser with
// PR_TRUE as the last argument).
XML_StopParser(mExpatParser, BlockedOrInterrupted());
}
else if (NS_SUCCEEDED(mInternalState)) {
// Only clobber mInternalState with the success code if we didn't block or
// interrupt before.
mInternalState = aState;
}
}

View File

@ -124,7 +124,7 @@ private:
PRUint32 *aConsumed);
nsresult HandleError();
void MaybeStopParser();
void MaybeStopParser(nsresult aState);
PRBool BlockedOrInterrupted()
{