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); }