Fix for bug 153480 - crash deleting download manager entries.

r=rjc sr=waterson


git-svn-id: svn://10.0.0.236/trunk@124831 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
tingley%sundell.net 2002-07-09 05:21:33 +00:00
parent ccff9eabc4
commit abbb6cec3f

View File

@ -765,27 +765,44 @@ InMemoryArcsEnumeratorImpl::HasMoreElements(PRBool* aResult)
}
}
else
while (mAssertion) {
nsIRDFResource* next = mAssertion->u.as.mProperty;
while (mAssertion) {
nsIRDFResource* next = mAssertion->u.as.mProperty;
PRBool alreadyReturned = PR_FALSE;
for (PRInt32 i = mAlreadyReturned.Count() - 1; i >= 0; --i) {
if (mAlreadyReturned[i] == mCurrent) {
alreadyReturned = PR_TRUE;
break;
// "next" is the property arc we are tentatively going to return
// in a subsequent GetNext() call. It is important to do two
// things, however, before that can happen:
// 1) Make sure it's not an arc we've already returned.
// 2) Make sure that |mAssertion| is not left pointing to
// another assertion that has the same property as this one.
// The first is a practical concern; the second a defense against
// an obscure crash and other erratic behavior. To ensure the
// second condition, skip down the chain until we find the next
// assertion with a property that doesn't match the current one.
// (All these assertions would be skipped via mAlreadyReturned
// checks anyways; this is even a bit faster.)
do {
mAssertion = (mSource ? mAssertion->mNext :
mAssertion->u.as.mInvNext);
}
while (mAssertion && (next == mAssertion->u.as.mProperty));
PRBool alreadyReturned = PR_FALSE;
for (PRInt32 i = mAlreadyReturned.Count() - 1; i >= 0; --i) {
if (mAlreadyReturned[i] == next) {
alreadyReturned = PR_TRUE;
break;
}
}
if (! alreadyReturned) {
mCurrent = next;
NS_ADDREF(mCurrent);
*aResult = PR_TRUE;
return NS_OK;
}
}
mAssertion = (mSource ? mAssertion->mNext : mAssertion->u.as.mInvNext);
if (! alreadyReturned) {
mCurrent = next;
NS_ADDREF(mCurrent);
*aResult = PR_TRUE;
return NS_OK;
}
}
*aResult = PR_FALSE;
return NS_OK;
}