diff --git a/content/xslt/crashtests/603844.html b/content/xslt/crashtests/603844.html
deleted file mode 100644
index f576effdb6a..00000000000
--- a/content/xslt/crashtests/603844.html
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/content/xslt/crashtests/crashtests.list b/content/xslt/crashtests/crashtests.list
index 182f22486d5..ffe0e29a7f8 100644
--- a/content/xslt/crashtests/crashtests.list
+++ b/content/xslt/crashtests/crashtests.list
@@ -11,4 +11,3 @@ load 528488.xml
load 528963.xml
load 545927.html
load 601543.html
-load 603844.html
diff --git a/content/xslt/src/xslt/txBufferingHandler.cpp b/content/xslt/src/xslt/txBufferingHandler.cpp
index 64edd9c0fc1..61d6754ffc1 100644
--- a/content/xslt/src/xslt/txBufferingHandler.cpp
+++ b/content/xslt/src/xslt/txBufferingHandler.cpp
@@ -408,103 +408,122 @@ txResultBuffer::addTransaction(txOutputTransaction* aTransaction)
return NS_OK;
}
-static nsresult
-flushTransaction(txOutputTransaction* aTransaction,
- txAXMLEventHandler* aHandler,
- nsAFlatString::const_char_iterator& aIter)
+struct Holder
{
- switch (aTransaction->mType) {
+ txAXMLEventHandler** mHandler;
+ nsresult mResult;
+ nsAFlatString::const_char_iterator mIter;
+};
+
+static PRBool
+flushTransaction(txOutputTransaction* aElement, Holder* aData)
+{
+ Holder* holder = aData;
+ txAXMLEventHandler* handler = *holder->mHandler;
+ txOutputTransaction* transaction = aElement;
+
+ nsresult rv;
+ switch (transaction->mType) {
case txOutputTransaction::eAttributeAtomTransaction:
{
txAttributeAtomTransaction* transaction =
- static_cast(aTransaction);
- return aHandler->attribute(transaction->mPrefix,
- transaction->mLocalName,
- transaction->mLowercaseLocalName,
- transaction->mNsID,
- transaction->mValue);
+ static_cast(aElement);
+ rv = handler->attribute(transaction->mPrefix,
+ transaction->mLocalName,
+ transaction->mLowercaseLocalName,
+ transaction->mNsID,
+ transaction->mValue);
+ break;
}
case txOutputTransaction::eAttributeTransaction:
{
txAttributeTransaction* attrTransaction =
- static_cast(aTransaction);
- return aHandler->attribute(attrTransaction->mPrefix,
- attrTransaction->mLocalName,
- attrTransaction->mNsID,
- attrTransaction->mValue);
+ static_cast(aElement);
+ rv = handler->attribute(attrTransaction->mPrefix,
+ attrTransaction->mLocalName,
+ attrTransaction->mNsID,
+ attrTransaction->mValue);
+ break;
}
case txOutputTransaction::eCharacterTransaction:
case txOutputTransaction::eCharacterNoOETransaction:
{
txCharacterTransaction* charTransaction =
- static_cast(aTransaction);
- nsAFlatString::const_char_iterator& start = aIter;
+ static_cast(aElement);
+ nsAFlatString::const_char_iterator& start =
+ holder->mIter;
nsAFlatString::const_char_iterator end =
start + charTransaction->mLength;
- aIter = end;
- return aHandler->characters(Substring(start, end),
- aTransaction->mType ==
- txOutputTransaction::eCharacterNoOETransaction);
+ rv = handler->characters(Substring(start, end),
+ transaction->mType ==
+ txOutputTransaction::eCharacterNoOETransaction);
+ start = end;
+ break;
}
case txOutputTransaction::eCommentTransaction:
{
txCommentTransaction* commentTransaction =
- static_cast(aTransaction);
- return aHandler->comment(commentTransaction->mValue);
+ static_cast(aElement);
+ rv = handler->comment(commentTransaction->mValue);
+ break;
}
case txOutputTransaction::eEndElementTransaction:
{
- return aHandler->endElement();
+ rv = handler->endElement();
+ break;
}
case txOutputTransaction::ePITransaction:
{
txPITransaction* piTransaction =
- static_cast(aTransaction);
- return aHandler->processingInstruction(piTransaction->mTarget,
- piTransaction->mData);
+ static_cast(aElement);
+ rv = handler->processingInstruction(piTransaction->mTarget,
+ piTransaction->mData);
+ break;
}
case txOutputTransaction::eStartDocumentTransaction:
{
- return aHandler->startDocument();
+ rv = handler->startDocument();
+ break;
}
case txOutputTransaction::eStartElementAtomTransaction:
{
txStartElementAtomTransaction* transaction =
- static_cast(aTransaction);
- return aHandler->startElement(transaction->mPrefix,
- transaction->mLocalName,
- transaction->mLowercaseLocalName,
- transaction->mNsID);
+ static_cast(aElement);
+ rv = handler->startElement(transaction->mPrefix,
+ transaction->mLocalName,
+ transaction->mLowercaseLocalName,
+ transaction->mNsID);
+ break;
}
case txOutputTransaction::eStartElementTransaction:
{
txStartElementTransaction* transaction =
- static_cast(aTransaction);
- return aHandler->startElement(transaction->mPrefix,
- transaction->mLocalName,
- transaction->mNsID);
- }
- default:
- {
- NS_NOTREACHED("Unexpected transaction type");
+ static_cast(aElement);
+ rv = handler->startElement(transaction->mPrefix,
+ transaction->mLocalName,
+ transaction->mNsID);
+ break;
}
}
- return NS_ERROR_UNEXPECTED;
+ holder->mResult = rv;
+
+ return NS_SUCCEEDED(rv);
}
nsresult
-txResultBuffer::flushToHandler(txAXMLEventHandler* aHandler)
+txResultBuffer::flushToHandler(txAXMLEventHandler** aHandler)
{
- nsAFlatString::const_char_iterator iter;
- mStringValue.BeginReading(iter);
+ Holder data = { aHandler, NS_OK };
+ mStringValue.BeginReading(data.mIter);
for (PRUint32 i = 0, len = mTransactions.Length(); i < len; ++i) {
- nsresult rv = flushTransaction(mTransactions[i], aHandler, iter);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (!flushTransaction(mTransactions[i], &data)) {
+ break;
+ }
}
- return NS_OK;
+ return data.mResult;
}
txOutputTransaction*
diff --git a/content/xslt/src/xslt/txBufferingHandler.h b/content/xslt/src/xslt/txBufferingHandler.h
index b62feba2703..df80f892767 100644
--- a/content/xslt/src/xslt/txBufferingHandler.h
+++ b/content/xslt/src/xslt/txBufferingHandler.h
@@ -56,7 +56,12 @@ public:
nsresult addTransaction(txOutputTransaction* aTransaction);
- nsresult flushToHandler(txAXMLEventHandler* aHandler);
+ /**
+ * Flush the transactions to aHandler. Some handlers create a new handler
+ * and replace themselves with the new handler. The pointer that aHandler
+ * points to should be updated in that case.
+ */
+ nsresult flushToHandler(txAXMLEventHandler** aHandler);
txOutputTransaction* getLastTransaction();
diff --git a/content/xslt/src/xslt/txEXSLTFunctions.cpp b/content/xslt/src/xslt/txEXSLTFunctions.cpp
index 1589795b39e..6808a980a4f 100644
--- a/content/xslt/src/xslt/txEXSLTFunctions.cpp
+++ b/content/xslt/src/xslt/txEXSLTFunctions.cpp
@@ -88,7 +88,10 @@ convertRtfToNode(txIEvalContext *aContext, txResultTreeFragment *aRtf)
txOutputFormat format;
txMozillaXMLOutput mozHandler(&format, domFragment, PR_TRUE);
- rv = aRtf->flushToHandler(&mozHandler);
+ txAXMLEventHandler* handler = &mozHandler;
+ rv = aRtf->flushToHandler(&handler);
+ NS_ASSERTION(handler == &mozHandler,
+ "This handler shouldn't have been replaced!");
NS_ENSURE_SUCCESS(rv, rv);
rv = mozHandler.closePrevious(PR_TRUE);
diff --git a/content/xslt/src/xslt/txInstructions.cpp b/content/xslt/src/xslt/txInstructions.cpp
index 046890d1249..dcb45283a63 100644
--- a/content/xslt/src/xslt/txInstructions.cpp
+++ b/content/xslt/src/xslt/txInstructions.cpp
@@ -432,7 +432,7 @@ txCopyOf::execute(txExecutionState& aEs)
txResultTreeFragment* rtf =
static_cast
(static_cast(exprRes));
- return rtf->flushToHandler(aEs.mResultHandler);
+ return rtf->flushToHandler(&aEs.mResultHandler);
}
default:
{
diff --git a/content/xslt/src/xslt/txRtfHandler.cpp b/content/xslt/src/xslt/txRtfHandler.cpp
index 90deffc71bb..55efdbf6a01 100644
--- a/content/xslt/src/xslt/txRtfHandler.cpp
+++ b/content/xslt/src/xslt/txRtfHandler.cpp
@@ -80,7 +80,7 @@ double txResultTreeFragment::numberValue()
return Double::toDouble(mBuffer->mStringValue);
}
-nsresult txResultTreeFragment::flushToHandler(txAXMLEventHandler* aHandler)
+nsresult txResultTreeFragment::flushToHandler(txAXMLEventHandler** aHandler)
{
if (!mBuffer) {
return NS_ERROR_FAILURE;
diff --git a/content/xslt/src/xslt/txRtfHandler.h b/content/xslt/src/xslt/txRtfHandler.h
index 4b38f3a3ad7..9418e1aefaa 100644
--- a/content/xslt/src/xslt/txRtfHandler.h
+++ b/content/xslt/src/xslt/txRtfHandler.h
@@ -51,7 +51,7 @@ public:
TX_DECL_EXPRRESULT
- nsresult flushToHandler(txAXMLEventHandler* aHandler);
+ nsresult flushToHandler(txAXMLEventHandler** aHandler);
void setNode(const txXPathNode* aNode)
{
diff --git a/content/xslt/src/xslt/txUnknownHandler.cpp b/content/xslt/src/xslt/txUnknownHandler.cpp
index 24313fa4053..45dce419828 100644
--- a/content/xslt/src/xslt/txUnknownHandler.cpp
+++ b/content/xslt/src/xslt/txUnknownHandler.cpp
@@ -153,17 +153,14 @@ nsresult txUnknownHandler::createHandlerAndFlush(PRBool aHTMLRoot,
format.mMethod = aHTMLRoot ? eHTMLOutput : eXMLOutput;
}
- nsAutoPtr handler;
+ txAXMLEventHandler *handler = nsnull;
nsresult rv = mEs->mOutputHandlerFactory->createHandlerWith(&format, aName,
aNsID,
- getter_Transfers(handler));
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = mBuffer->flushToHandler(handler);
+ &handler);
NS_ENSURE_SUCCESS(rv, rv);
mEs->mOutputHandler = handler;
- mEs->mResultHandler = handler.forget();
+ mEs->mResultHandler = handler;
- return NS_OK;
+ return mBuffer->flushToHandler(&handler);
}