Landing fix for regression bug 402422. XPathResult crashes when holding nodeset and accessing stringValue/numberValue/booleanValue. Patch by peterv@propagandism.org, r+sr=jst@mozilla.org. Landing this one w/o direct approval to get it in for the upcoming nightlies.

This commit is contained in:
jst@mozilla.org 2007-11-05 00:06:48 -08:00
Родитель 61c9f47139
Коммит e128eafec0
2 изменённых файлов: 38 добавлений и 17 удалений

Просмотреть файл

@ -52,7 +52,9 @@
nsXPathResult::nsXPathResult() : mDocument(nsnull),
mCurrentPos(0),
mResultType(ANY_TYPE),
mInvalidIteratorState(PR_TRUE)
mInvalidIteratorState(PR_TRUE),
mBooleanResult(PR_FALSE),
mNumberResult(0)
{
}
@ -120,7 +122,7 @@ nsXPathResult::GetNumberValue(double *aNumberValue)
return NS_ERROR_DOM_TYPE_ERR;
}
*aNumberValue = mResult->numberValue();
*aNumberValue = mNumberResult;
return NS_OK;
}
@ -132,10 +134,7 @@ nsXPathResult::GetStringValue(nsAString &aStringValue)
return NS_ERROR_DOM_TYPE_ERR;
}
nsAutoString stringValue;
mResult->stringValue(stringValue);
aStringValue.Assign(stringValue);
aStringValue = mStringResult;
return NS_OK;
}
@ -147,7 +146,7 @@ nsXPathResult::GetBooleanValue(PRBool *aBooleanValue)
return NS_ERROR_DOM_TYPE_ERR;
}
*aBooleanValue = mResult->booleanValue();
*aBooleanValue = mBooleanResult;
return NS_OK;
}
@ -284,14 +283,18 @@ nsresult
nsXPathResult::SetExprResult(txAExprResult* aExprResult, PRUint16 aResultType,
nsINode* aContextNode)
{
mResultType = aResultType;
mContextNode = do_GetWeakReference(aContextNode);
if ((isSnapshot() || isIterator() || isNode()) &&
if ((isSnapshot(aResultType) || isIterator(aResultType) ||
isNode(aResultType)) &&
aExprResult->getResultType() != txAExprResult::NODESET) {
// The DOM spec doesn't really say what should happen when reusing an
// XPathResult and an error is thrown. Let's not touch the XPathResult
// in that case.
return NS_ERROR_DOM_TYPE_ERR;
}
mResultType = aResultType;
mContextNode = do_GetWeakReference(aContextNode);
if (mDocument) {
mDocument->RemoveMutationObserver(this);
mDocument = nsnull;
@ -301,6 +304,9 @@ nsXPathResult::SetExprResult(txAExprResult* aExprResult, PRUint16 aResultType,
// XXX This will keep the recycler alive, should we clear it?
mResult = aExprResult;
mBooleanResult = mResult->booleanValue();
mNumberResult = mResult->numberValue();
mResult->stringValue(mStringResult);
if (aExprResult && aExprResult->getResultType() == txAExprResult::NODESET) {
txNodeSet *nodeSet = static_cast<txNodeSet*>(aExprResult);

Просмотреть файл

@ -99,20 +99,32 @@ public:
nsresult Clone(nsIXPathResult **aResult);
void RemoveObserver();
private:
static PRBool isSnapshot(PRUint16 aResultType)
{
return aResultType == UNORDERED_NODE_SNAPSHOT_TYPE ||
aResultType == ORDERED_NODE_SNAPSHOT_TYPE;
}
static PRBool isIterator(PRUint16 aResultType)
{
return aResultType == UNORDERED_NODE_ITERATOR_TYPE ||
aResultType == ORDERED_NODE_ITERATOR_TYPE;
}
static PRBool isNode(PRUint16 aResultType)
{
return aResultType == FIRST_ORDERED_NODE_TYPE ||
aResultType == ANY_UNORDERED_NODE_TYPE;
}
PRBool isSnapshot() const
{
return mResultType == UNORDERED_NODE_SNAPSHOT_TYPE ||
mResultType == ORDERED_NODE_SNAPSHOT_TYPE;
return isSnapshot(mResultType);
}
PRBool isIterator() const
{
return mResultType == UNORDERED_NODE_ITERATOR_TYPE ||
mResultType == ORDERED_NODE_ITERATOR_TYPE;
return isIterator(mResultType);
}
PRBool isNode() const
{
return mResultType == FIRST_ORDERED_NODE_TYPE ||
mResultType == ANY_UNORDERED_NODE_TYPE;
return isNode(mResultType);
}
void Invalidate(const nsIContent* aChangeRoot);
@ -124,6 +136,9 @@ private:
PRUint16 mResultType;
nsWeakPtr mContextNode;
PRPackedBool mInvalidIteratorState;
PRBool mBooleanResult;
double mNumberResult;
nsString mStringResult;
};
#endif