Bug 489925 and bug 522030 branch-safe fix. Hold strong refs in the id table. r=jst

git-svn-id: svn://10.0.0.236/trunk@258670 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
bzbarsky%mit.edu
2009-10-14 22:08:40 +00:00
parent 852e25eac8
commit da52d243fe
2 changed files with 59 additions and 10 deletions

View File

@@ -242,6 +242,14 @@ public:
if (mNameContentList && mNameContentList != NAME_NOT_VALID) {
NS_RELEASE(mNameContentList);
}
if (mIdContentList.Count() != 1 ||
mIdContentList[0] != ID_NOT_IN_DOCUMENT) {
for (PRInt32 i = 0; i < mIdContentList.Count(); ++i) {
nsIContent* content = static_cast<nsIContent*>(mIdContentList[i]);
NS_RELEASE(content);
}
}
}
nsIContent* GetIdContent() {
@@ -253,8 +261,11 @@ public:
PRBool RemoveIdContent(nsIContent* aContent) {
// XXXbz should this ever Compact() I guess when all the content is gone
// we'll just get cleaned up in the natural order of things...
return mIdContentList.RemoveElement(aContent) &&
mIdContentList.Count() == 0;
if (!mIdContentList.RemoveElement(aContent)) {
return PR_FALSE;
}
NS_RELEASE(aContent);
return mIdContentList.Count() == 0;
}
void FlagIDNotInDocument() {
@@ -264,10 +275,13 @@ public:
mIdContentList.AppendElement(ID_NOT_IN_DOCUMENT);
}
void Traverse(nsCycleCollectionTraversalCallback* cb);
nsCOMPtr<nsIAtom> mKey;
nsBaseContentList *mNameContentList;
nsRefPtr<nsContentList> mDocAllList;
private:
// The content nodes are stored addrefed.
nsSmallVoidArray mIdContentList;
};
@@ -282,12 +296,20 @@ IdAndNameMapEntry::AddIdContent(nsIContent* aContent)
if (GetIdContent() == ID_NOT_IN_DOCUMENT) {
NS_ASSERTION(mIdContentList.Count() == 1, "Bogus count");
return mIdContentList.ReplaceElementAt(aContent, 0);
if (!mIdContentList.ReplaceElementAt(aContent, 0)) {
return PR_FALSE;
}
NS_ADDREF(aContent);
return PR_TRUE;
}
// Common case
if (mIdContentList.Count() == 0) {
return mIdContentList.AppendElement(aContent);
if (!mIdContentList.AppendElement(aContent)) {
return PR_FALSE;
}
NS_ADDREF(aContent);
return PR_TRUE;
}
// We seem to have multiple content nodes for the same id, or we're doing our
@@ -314,7 +336,11 @@ IdAndNameMapEntry::AddIdContent(nsIContent* aContent)
}
} while (start != end);
return mIdContentList.InsertElementAt(aContent, start);
if (!mIdContentList.InsertElementAt(aContent, start)) {
return PR_FALSE;
}
NS_ADDREF(aContent);
return PR_TRUE;
}
@@ -388,15 +414,26 @@ IdAndNameMapEntryTraverse(PLDHashTable *table, PLDHashEntryHdr *hdr,
nsCycleCollectionTraversalCallback *cb =
static_cast<nsCycleCollectionTraversalCallback*>(arg);
IdAndNameMapEntry *entry = static_cast<IdAndNameMapEntry*>(hdr);
if (entry->mNameContentList != NAME_NOT_VALID)
cb->NoteXPCOMChild(entry->mNameContentList);
cb->NoteXPCOMChild(static_cast<nsIDOMNodeList*>(entry->mDocAllList));
entry->Traverse(cb);
return PL_DHASH_NEXT;
}
void
IdAndNameMapEntry::Traverse(nsCycleCollectionTraversalCallback* cb)
{
if (mNameContentList != NAME_NOT_VALID)
cb->NoteXPCOMChild(mNameContentList);
cb->NoteXPCOMChild(static_cast<nsIDOMNodeList*>(mDocAllList));
if (mIdContentList.Count() != 1 || mIdContentList[0] != ID_NOT_IN_DOCUMENT) {
for (PRInt32 i = 0; i < mIdContentList.Count(); ++i) {
cb->NoteXPCOMChild(static_cast<nsIContent*>(mIdContentList[i]));
}
}
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLDocument, nsDocument)
if (tmp->mIdAndNameHashTable.ops) {
PL_DHashTableEnumerate(&tmp->mIdAndNameHashTable,
@@ -4805,3 +4842,13 @@ nsHTMLDocument::CreateElem(nsIAtom *aName, nsIAtom *aPrefix,
aDocumentDefaultType, aResult);
}
#endif
void
nsHTMLDocument::Destroy()
{
nsDocument::Destroy();
// Try really really hard to make sure we don't leak things through
// mIdAndNameHashTable
InvalidateHashTables();
}

View File

@@ -201,6 +201,8 @@ public:
nsIContent** aResult);
#endif
virtual NS_HIDDEN_(void) Destroy();
nsresult ChangeContentEditableCount(nsIContent *aElement, PRInt32 aChange);
virtual EditingState GetEditingState()