diff --git a/content/xslt/crashtests/603844.html b/content/xslt/crashtests/603844.html new file mode 100644 index 000000000000..f576effdb6a8 --- /dev/null +++ b/content/xslt/crashtests/603844.html @@ -0,0 +1,32 @@ + + + + + + + + diff --git a/content/xslt/crashtests/crashtests.list b/content/xslt/crashtests/crashtests.list index 3d78e114fdbc..4a0524a1fd09 100644 --- a/content/xslt/crashtests/crashtests.list +++ b/content/xslt/crashtests/crashtests.list @@ -11,4 +11,5 @@ load 528488.xml load 528963.xml load 545927.html load 601543.html +load 603844.html load 602115.html diff --git a/content/xslt/src/xslt/txBufferingHandler.cpp b/content/xslt/src/xslt/txBufferingHandler.cpp index 61d6754ffc10..4b2f4ce630c3 100644 --- a/content/xslt/src/xslt/txBufferingHandler.cpp +++ b/content/xslt/src/xslt/txBufferingHandler.cpp @@ -408,122 +408,103 @@ txResultBuffer::addTransaction(txOutputTransaction* aTransaction) return NS_OK; } -struct Holder +static nsresult +flushTransaction(txOutputTransaction* aTransaction, + txAXMLEventHandler* aHandler, + nsAFlatString::const_char_iterator& aIter) { - 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) { + switch (aTransaction->mType) { case txOutputTransaction::eAttributeAtomTransaction: { txAttributeAtomTransaction* transaction = - static_cast(aElement); - rv = handler->attribute(transaction->mPrefix, - transaction->mLocalName, - transaction->mLowercaseLocalName, - transaction->mNsID, - transaction->mValue); - break; + static_cast(aTransaction); + return aHandler->attribute(transaction->mPrefix, + transaction->mLocalName, + transaction->mLowercaseLocalName, + transaction->mNsID, + transaction->mValue); } case txOutputTransaction::eAttributeTransaction: { txAttributeTransaction* attrTransaction = - static_cast(aElement); - rv = handler->attribute(attrTransaction->mPrefix, - attrTransaction->mLocalName, - attrTransaction->mNsID, - attrTransaction->mValue); - break; + static_cast(aTransaction); + return aHandler->attribute(attrTransaction->mPrefix, + attrTransaction->mLocalName, + attrTransaction->mNsID, + attrTransaction->mValue); } case txOutputTransaction::eCharacterTransaction: case txOutputTransaction::eCharacterNoOETransaction: { txCharacterTransaction* charTransaction = - static_cast(aElement); - nsAFlatString::const_char_iterator& start = - holder->mIter; + static_cast(aTransaction); + nsAFlatString::const_char_iterator start = aIter; nsAFlatString::const_char_iterator end = start + charTransaction->mLength; - rv = handler->characters(Substring(start, end), - transaction->mType == - txOutputTransaction::eCharacterNoOETransaction); - start = end; - break; + aIter = end; + return aHandler->characters(Substring(start, end), + aTransaction->mType == + txOutputTransaction::eCharacterNoOETransaction); } case txOutputTransaction::eCommentTransaction: { txCommentTransaction* commentTransaction = - static_cast(aElement); - rv = handler->comment(commentTransaction->mValue); - break; + static_cast(aTransaction); + return aHandler->comment(commentTransaction->mValue); } case txOutputTransaction::eEndElementTransaction: { - rv = handler->endElement(); - break; + return aHandler->endElement(); } case txOutputTransaction::ePITransaction: { txPITransaction* piTransaction = - static_cast(aElement); - rv = handler->processingInstruction(piTransaction->mTarget, - piTransaction->mData); - break; + static_cast(aTransaction); + return aHandler->processingInstruction(piTransaction->mTarget, + piTransaction->mData); } case txOutputTransaction::eStartDocumentTransaction: { - rv = handler->startDocument(); - break; + return aHandler->startDocument(); } case txOutputTransaction::eStartElementAtomTransaction: { txStartElementAtomTransaction* transaction = - static_cast(aElement); - rv = handler->startElement(transaction->mPrefix, - transaction->mLocalName, - transaction->mLowercaseLocalName, - transaction->mNsID); - break; + static_cast(aTransaction); + return aHandler->startElement(transaction->mPrefix, + transaction->mLocalName, + transaction->mLowercaseLocalName, + transaction->mNsID); } case txOutputTransaction::eStartElementTransaction: { txStartElementTransaction* transaction = - static_cast(aElement); - rv = handler->startElement(transaction->mPrefix, - transaction->mLocalName, - transaction->mNsID); - break; + static_cast(aTransaction); + return aHandler->startElement(transaction->mPrefix, + transaction->mLocalName, + transaction->mNsID); + } + default: + { + NS_NOTREACHED("Unexpected transaction type"); } } - holder->mResult = rv; - - return NS_SUCCEEDED(rv); + return NS_ERROR_UNEXPECTED; } nsresult -txResultBuffer::flushToHandler(txAXMLEventHandler** aHandler) +txResultBuffer::flushToHandler(txAXMLEventHandler* aHandler) { - Holder data = { aHandler, NS_OK }; - mStringValue.BeginReading(data.mIter); + nsAFlatString::const_char_iterator iter; + mStringValue.BeginReading(iter); for (PRUint32 i = 0, len = mTransactions.Length(); i < len; ++i) { - if (!flushTransaction(mTransactions[i], &data)) { - break; - } + nsresult rv = flushTransaction(mTransactions[i], aHandler, iter); + NS_ENSURE_SUCCESS(rv, rv); } - return data.mResult; + return NS_OK; } txOutputTransaction* diff --git a/content/xslt/src/xslt/txBufferingHandler.h b/content/xslt/src/xslt/txBufferingHandler.h index df80f8927677..b62feba27039 100644 --- a/content/xslt/src/xslt/txBufferingHandler.h +++ b/content/xslt/src/xslt/txBufferingHandler.h @@ -56,12 +56,7 @@ public: nsresult addTransaction(txOutputTransaction* aTransaction); - /** - * 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); + nsresult flushToHandler(txAXMLEventHandler* aHandler); txOutputTransaction* getLastTransaction(); diff --git a/content/xslt/src/xslt/txEXSLTFunctions.cpp b/content/xslt/src/xslt/txEXSLTFunctions.cpp index 6808a980a4f5..1589795b39ea 100644 --- a/content/xslt/src/xslt/txEXSLTFunctions.cpp +++ b/content/xslt/src/xslt/txEXSLTFunctions.cpp @@ -88,10 +88,7 @@ convertRtfToNode(txIEvalContext *aContext, txResultTreeFragment *aRtf) txOutputFormat format; txMozillaXMLOutput mozHandler(&format, domFragment, PR_TRUE); - txAXMLEventHandler* handler = &mozHandler; - rv = aRtf->flushToHandler(&handler); - NS_ASSERTION(handler == &mozHandler, - "This handler shouldn't have been replaced!"); + rv = aRtf->flushToHandler(&mozHandler); 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 33630efd7579..ee9149fa2658 100644 --- a/content/xslt/src/xslt/txInstructions.cpp +++ b/content/xslt/src/xslt/txInstructions.cpp @@ -429,7 +429,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/txMozillaTextOutput.cpp b/content/xslt/src/xslt/txMozillaTextOutput.cpp index 75525c0a4dfb..92bfa614d038 100644 --- a/content/xslt/src/xslt/txMozillaTextOutput.cpp +++ b/content/xslt/src/xslt/txMozillaTextOutput.cpp @@ -58,13 +58,10 @@ using namespace mozilla::dom; -txMozillaTextOutput::txMozillaTextOutput(nsIDOMDocument* aSourceDocument, - nsIDOMDocument* aResultDocument, - nsITransformObserver* aObserver) +txMozillaTextOutput::txMozillaTextOutput(nsITransformObserver* aObserver) { MOZ_COUNT_CTOR(txMozillaTextOutput); mObserver = do_GetWeakReference(aObserver); - createResultDocument(aSourceDocument, aResultDocument); } txMozillaTextOutput::txMozillaTextOutput(nsIDOMDocumentFragment* aDest) diff --git a/content/xslt/src/xslt/txMozillaTextOutput.h b/content/xslt/src/xslt/txMozillaTextOutput.h index 3a51cf6ce691..4b311f6092ea 100644 --- a/content/xslt/src/xslt/txMozillaTextOutput.h +++ b/content/xslt/src/xslt/txMozillaTextOutput.h @@ -54,18 +54,17 @@ class nsIContent; class txMozillaTextOutput : public txAOutputXMLEventHandler { public: - txMozillaTextOutput(nsIDOMDocument* aSourceDocument, - nsIDOMDocument* aResultDocument, - nsITransformObserver* aObserver); + txMozillaTextOutput(nsITransformObserver* aObserver); txMozillaTextOutput(nsIDOMDocumentFragment* aDest); virtual ~txMozillaTextOutput(); TX_DECL_TXAXMLEVENTHANDLER TX_DECL_TXAOUTPUTXMLEVENTHANDLER -private: nsresult createResultDocument(nsIDOMDocument* aSourceDocument, nsIDOMDocument* aResultDocument); + +private: nsresult createXHTMLElement(nsIAtom* aName, nsIContent** aResult); nsCOMPtr mTextParent; diff --git a/content/xslt/src/xslt/txMozillaXMLOutput.cpp b/content/xslt/src/xslt/txMozillaXMLOutput.cpp index 4653fa62f8e2..e49d7da4dbd2 100644 --- a/content/xslt/src/xslt/txMozillaXMLOutput.cpp +++ b/content/xslt/src/xslt/txMozillaXMLOutput.cpp @@ -80,11 +80,7 @@ using namespace mozilla::dom; if (!mCurrentNode) \ return NS_ERROR_UNEXPECTED -txMozillaXMLOutput::txMozillaXMLOutput(const nsSubstring& aRootName, - PRInt32 aRootNsID, - txOutputFormat* aFormat, - nsIDOMDocument* aSourceDocument, - nsIDOMDocument* aResultDocument, +txMozillaXMLOutput::txMozillaXMLOutput(txOutputFormat* aFormat, nsITransformObserver* aObserver) : mTreeDepth(0), mBadChildLevel(0), @@ -104,8 +100,6 @@ txMozillaXMLOutput::txMozillaXMLOutput(const nsSubstring& aRootName, mOutputFormat.merge(*aFormat); mOutputFormat.setFromDefaults(); - - createResultDocument(aRootName, aRootNsID, aSourceDocument, aResultDocument); } txMozillaXMLOutput::txMozillaXMLOutput(txOutputFormat* aFormat, diff --git a/content/xslt/src/xslt/txMozillaXMLOutput.h b/content/xslt/src/xslt/txMozillaXMLOutput.h index 88adb9ca2549..1c563d07bf34 100644 --- a/content/xslt/src/xslt/txMozillaXMLOutput.h +++ b/content/xslt/src/xslt/txMozillaXMLOutput.h @@ -93,11 +93,7 @@ private: class txMozillaXMLOutput : public txAOutputXMLEventHandler { public: - txMozillaXMLOutput(const nsSubstring& aRootName, - PRInt32 aRootNsID, - txOutputFormat* aFormat, - nsIDOMDocument* aSourceDocument, - nsIDOMDocument* aResultDocument, + txMozillaXMLOutput(txOutputFormat* aFormat, nsITransformObserver* aObserver); txMozillaXMLOutput(txOutputFormat* aFormat, nsIDOMDocumentFragment* aFragment, @@ -109,14 +105,15 @@ public: nsresult closePrevious(PRBool aFlushText); + nsresult createResultDocument(const nsSubstring& aName, PRInt32 aNsID, + nsIDOMDocument* aSourceDocument, + nsIDOMDocument* aResultDocument); + private: nsresult createTxWrapper(); nsresult startHTMLElement(nsIContent* aElement, PRBool aXHTML); nsresult endHTMLElement(nsIContent* aElement); void processHTTPEquiv(nsIAtom* aHeader, const nsString& aValue); - nsresult createResultDocument(const nsSubstring& aName, PRInt32 aNsID, - nsIDOMDocument* aSourceDocument, - nsIDOMDocument* aResultDocument); nsresult createHTMLElement(nsIAtom* aName, nsIContent** aResult); diff --git a/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp b/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp index d77a9d29f67a..ce13d501558d 100644 --- a/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp +++ b/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp @@ -121,28 +121,39 @@ txToDocHandlerFactory::createHandlerWith(txOutputFormat* aFormat, case eXMLOutput: { *aHandler = new txUnknownHandler(mEs); - break; + return NS_OK; } case eHTMLOutput: { - *aHandler = new txMozillaXMLOutput(EmptyString(), - kNameSpaceID_None, - aFormat, mSourceDocument, - mResultDocument, mObserver); - break; + nsAutoPtr handler( + new txMozillaXMLOutput(aFormat, mObserver)); + + nsresult rv = handler->createResultDocument(EmptyString(), + kNameSpaceID_None, + mSourceDocument, + mResultDocument); + if (NS_SUCCEEDED(rv)) { + *aHandler = handler.forget(); + } + + return rv; } case eTextOutput: { - *aHandler = new txMozillaTextOutput(mSourceDocument, - mResultDocument, - mObserver); - break; + nsAutoPtr handler( + new txMozillaTextOutput(mObserver)); + + nsresult rv = handler->createResultDocument(mSourceDocument, + mResultDocument); + if (NS_SUCCEEDED(rv)) { + *aHandler = handler.forget(); + } + + return rv; } } - NS_ENSURE_TRUE(*aHandler, NS_ERROR_OUT_OF_MEMORY); - return NS_OK; } nsresult @@ -162,23 +173,33 @@ txToDocHandlerFactory::createHandlerWith(txOutputFormat* aFormat, case eXMLOutput: case eHTMLOutput: { - *aHandler = new txMozillaXMLOutput(aName, aNsID, aFormat, - mSourceDocument, - mResultDocument, - mObserver); - break; + nsAutoPtr handler( + new txMozillaXMLOutput(aFormat, mObserver)); + + nsresult rv = handler->createResultDocument(aName, aNsID, + mSourceDocument, + mResultDocument); + if (NS_SUCCEEDED(rv)) { + *aHandler = handler.forget(); + } + + return rv; } case eTextOutput: { - *aHandler = new txMozillaTextOutput(mSourceDocument, - mResultDocument, - mObserver); - break; + nsAutoPtr handler( + new txMozillaTextOutput(mObserver)); + + nsresult rv = handler->createResultDocument(mSourceDocument, + mResultDocument); + if (NS_SUCCEEDED(rv)) { + *aHandler = handler.forget(); + } + + return rv; } } - NS_ENSURE_TRUE(*aHandler, NS_ERROR_OUT_OF_MEMORY); - return NS_OK; } nsresult diff --git a/content/xslt/src/xslt/txRtfHandler.cpp b/content/xslt/src/xslt/txRtfHandler.cpp index 55efdbf6a01a..90deffc71bbb 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 9418e1aefaa0..4b38f3a3ad75 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 45dce419828d..24313fa4053e 100644 --- a/content/xslt/src/xslt/txUnknownHandler.cpp +++ b/content/xslt/src/xslt/txUnknownHandler.cpp @@ -153,14 +153,17 @@ nsresult txUnknownHandler::createHandlerAndFlush(PRBool aHTMLRoot, format.mMethod = aHTMLRoot ? eHTMLOutput : eXMLOutput; } - txAXMLEventHandler *handler = nsnull; + nsAutoPtr handler; nsresult rv = mEs->mOutputHandlerFactory->createHandlerWith(&format, aName, aNsID, - &handler); + getter_Transfers(handler)); + NS_ENSURE_SUCCESS(rv, rv); + + rv = mBuffer->flushToHandler(handler); NS_ENSURE_SUCCESS(rv, rv); mEs->mOutputHandler = handler; - mEs->mResultHandler = handler; + mEs->mResultHandler = handler.forget(); - return mBuffer->flushToHandler(&handler); + return NS_OK; } diff --git a/xpcom/base/nsCycleCollector.cpp b/xpcom/base/nsCycleCollector.cpp index d917a0e4b76f..cbbeaf6fa55d 100644 --- a/xpcom/base/nsCycleCollector.cpp +++ b/xpcom/base/nsCycleCollector.cpp @@ -1576,8 +1576,10 @@ GCGraphBuilder::DescribeNode(CCNodeType type, nsrefcnt refCount, } if (type == RefCounted) { - if (refCount == 0 || refCount == PR_UINT32_MAX) - Fault("zero or overflowing refcount", mCurrPi); + if (refCount == 0) + Fault("zero refcount", mCurrPi); + if (refCount == PR_UINT32_MAX) + Fault("overflowing refcount", mCurrPi); mCurrPi->mRefCount = refCount; }