mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Fix for bug 603844 (Leak txUnknownHandler+ with transformToDocument(textnode)). r=sicking.
This commit is contained in:
parent
70a155c558
commit
5b1dbd07be
32
content/xslt/crashtests/603844.html
Normal file
32
content/xslt/crashtests/603844.html
Normal file
@ -0,0 +1,32 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<script>
|
||||
|
||||
function boom()
|
||||
{
|
||||
var frame = document.createElementNS("http://www.w3.org/1999/xhtml", "iframe");
|
||||
frame.onload = y;
|
||||
frame.src = "data:text/plain,0";
|
||||
document.body.appendChild(frame);
|
||||
frameDoc = frame.contentDocument;
|
||||
|
||||
function y()
|
||||
{
|
||||
frameDoc.removeChild(frameDoc.documentElement);
|
||||
|
||||
var xp = new XSLTProcessor;
|
||||
xp.importStylesheet(frameDoc);
|
||||
try {
|
||||
xp.transformToDocument(frameDoc.createTextNode('x'));
|
||||
} catch(e) { }
|
||||
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="boom();"></body>
|
||||
</html>
|
@ -11,4 +11,5 @@ load 528488.xml
|
||||
load 528963.xml
|
||||
load 545927.html
|
||||
load 601543.html
|
||||
load 603844.html
|
||||
load 602115.html
|
||||
|
@ -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<txAttributeAtomTransaction*>(aElement);
|
||||
rv = handler->attribute(transaction->mPrefix,
|
||||
transaction->mLocalName,
|
||||
transaction->mLowercaseLocalName,
|
||||
transaction->mNsID,
|
||||
transaction->mValue);
|
||||
break;
|
||||
static_cast<txAttributeAtomTransaction*>(aTransaction);
|
||||
return aHandler->attribute(transaction->mPrefix,
|
||||
transaction->mLocalName,
|
||||
transaction->mLowercaseLocalName,
|
||||
transaction->mNsID,
|
||||
transaction->mValue);
|
||||
}
|
||||
case txOutputTransaction::eAttributeTransaction:
|
||||
{
|
||||
txAttributeTransaction* attrTransaction =
|
||||
static_cast<txAttributeTransaction*>(aElement);
|
||||
rv = handler->attribute(attrTransaction->mPrefix,
|
||||
attrTransaction->mLocalName,
|
||||
attrTransaction->mNsID,
|
||||
attrTransaction->mValue);
|
||||
break;
|
||||
static_cast<txAttributeTransaction*>(aTransaction);
|
||||
return aHandler->attribute(attrTransaction->mPrefix,
|
||||
attrTransaction->mLocalName,
|
||||
attrTransaction->mNsID,
|
||||
attrTransaction->mValue);
|
||||
}
|
||||
case txOutputTransaction::eCharacterTransaction:
|
||||
case txOutputTransaction::eCharacterNoOETransaction:
|
||||
{
|
||||
txCharacterTransaction* charTransaction =
|
||||
static_cast<txCharacterTransaction*>(aElement);
|
||||
nsAFlatString::const_char_iterator& start =
|
||||
holder->mIter;
|
||||
static_cast<txCharacterTransaction*>(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<txCommentTransaction*>(aElement);
|
||||
rv = handler->comment(commentTransaction->mValue);
|
||||
break;
|
||||
static_cast<txCommentTransaction*>(aTransaction);
|
||||
return aHandler->comment(commentTransaction->mValue);
|
||||
}
|
||||
case txOutputTransaction::eEndElementTransaction:
|
||||
{
|
||||
rv = handler->endElement();
|
||||
break;
|
||||
return aHandler->endElement();
|
||||
}
|
||||
case txOutputTransaction::ePITransaction:
|
||||
{
|
||||
txPITransaction* piTransaction =
|
||||
static_cast<txPITransaction*>(aElement);
|
||||
rv = handler->processingInstruction(piTransaction->mTarget,
|
||||
piTransaction->mData);
|
||||
break;
|
||||
static_cast<txPITransaction*>(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<txStartElementAtomTransaction*>(aElement);
|
||||
rv = handler->startElement(transaction->mPrefix,
|
||||
transaction->mLocalName,
|
||||
transaction->mLowercaseLocalName,
|
||||
transaction->mNsID);
|
||||
break;
|
||||
static_cast<txStartElementAtomTransaction*>(aTransaction);
|
||||
return aHandler->startElement(transaction->mPrefix,
|
||||
transaction->mLocalName,
|
||||
transaction->mLowercaseLocalName,
|
||||
transaction->mNsID);
|
||||
}
|
||||
case txOutputTransaction::eStartElementTransaction:
|
||||
{
|
||||
txStartElementTransaction* transaction =
|
||||
static_cast<txStartElementTransaction*>(aElement);
|
||||
rv = handler->startElement(transaction->mPrefix,
|
||||
transaction->mLocalName,
|
||||
transaction->mNsID);
|
||||
break;
|
||||
static_cast<txStartElementTransaction*>(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*
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
|
@ -429,7 +429,7 @@ txCopyOf::execute(txExecutionState& aEs)
|
||||
txResultTreeFragment* rtf =
|
||||
static_cast<txResultTreeFragment*>
|
||||
(static_cast<txAExprResult*>(exprRes));
|
||||
return rtf->flushToHandler(&aEs.mResultHandler);
|
||||
return rtf->flushToHandler(aEs.mResultHandler);
|
||||
}
|
||||
default:
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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<nsIContent> mTextParent;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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<txMozillaXMLOutput> 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<txMozillaTextOutput> 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<txMozillaXMLOutput> 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<txMozillaTextOutput> 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
|
||||
|
@ -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;
|
||||
|
@ -51,7 +51,7 @@ public:
|
||||
|
||||
TX_DECL_EXPRRESULT
|
||||
|
||||
nsresult flushToHandler(txAXMLEventHandler** aHandler);
|
||||
nsresult flushToHandler(txAXMLEventHandler* aHandler);
|
||||
|
||||
void setNode(const txXPathNode* aNode)
|
||||
{
|
||||
|
@ -153,14 +153,17 @@ nsresult txUnknownHandler::createHandlerAndFlush(PRBool aHTMLRoot,
|
||||
format.mMethod = aHTMLRoot ? eHTMLOutput : eXMLOutput;
|
||||
}
|
||||
|
||||
txAXMLEventHandler *handler = nsnull;
|
||||
nsAutoPtr<txAXMLEventHandler> 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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user