From 1caa5d5eb4f59e20702a042e56b685365c601f8f Mon Sep 17 00:00:00 2001 From: Olli Pettay Date: Tue, 28 Feb 2012 01:31:23 +0200 Subject: [PATCH] Bug 730470, FormFillController crashes, r=gavin --- .../satchel/nsFormFillController.cpp | 31 ++++++++++++++----- .../components/satchel/nsFormFillController.h | 2 ++ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/toolkit/components/satchel/nsFormFillController.cpp b/toolkit/components/satchel/nsFormFillController.cpp index 33e4fd245ba3..9e8702bb3f26 100644 --- a/toolkit/components/satchel/nsFormFillController.cpp +++ b/toolkit/components/satchel/nsFormFillController.cpp @@ -101,26 +101,27 @@ nsFormFillController::nsFormFillController() : struct PwmgrInputsEnumData { - PwmgrInputsEnumData(nsIMutationObserver* aMutationObserver, nsIDocument* aDoc) - : mMutationObserver(aMutationObserver), mDoc(aDoc) {} + PwmgrInputsEnumData(nsFormFillController* aFFC, nsIDocument* aDoc) + : mFFC(aFFC), mDoc(aDoc) {} - nsIMutationObserver* mMutationObserver; + nsFormFillController* mFFC; nsCOMPtr mDoc; }; nsFormFillController::~nsFormFillController() { - PwmgrInputsEnumData ed(this, nsnull); - mPwmgrInputs.Enumerate(RemoveForDocumentEnumerator, &ed); if (mListNode) { mListNode->RemoveMutationObserver(this); mListNode = nsnull; } if (mFocusedInputNode) { - mFocusedInputNode->RemoveMutationObserver(this); + MaybeRemoveMutationObserver(mFocusedInputNode); mFocusedInputNode = nsnull; mFocusedInput = nsnull; } + PwmgrInputsEnumData ed(this, nsnull); + mPwmgrInputs.Enumerate(RemoveForDocumentEnumerator, &ed); + // Remove ourselves as a focus listener from all cached docShells PRUint32 count; mDocShells->Count(&count); @@ -221,6 +222,17 @@ nsFormFillController::NodeWillBeDestroyed(const nsINode* aNode) } } +void +nsFormFillController::MaybeRemoveMutationObserver(nsINode* aNode) +{ + // Nodes being tracked in mPwmgrInputs will have their observers removed when + // they stop being tracked. + bool dummy; + if (!mPwmgrInputs.Get(aNode, &dummy)) { + aNode->RemoveMutationObserver(this); + } +} + //////////////////////////////////////////////////////////////////////// //// nsIFormFillController @@ -796,7 +808,10 @@ nsFormFillController::RemoveForDocumentEnumerator(const nsINode* aKey, { PwmgrInputsEnumData* ed = static_cast(aUserData); if (aKey && (!ed->mDoc || aKey->OwnerDoc() == ed->mDoc)) { - const_cast(aKey)->RemoveMutationObserver(ed->mMutationObserver); + // mFocusedInputNode's observer is tracked separately, don't remove it here. + if (aKey != ed->mFFC->mFocusedInputNode) { + const_cast(aKey)->RemoveMutationObserver(ed->mFFC); + } return PL_DHASH_REMOVE; } return PL_DHASH_NEXT; @@ -1105,7 +1120,7 @@ nsFormFillController::StopControllingInput() mController->SetInput(nsnull); if (mFocusedInputNode) { - mFocusedInputNode->RemoveMutationObserver(this); + MaybeRemoveMutationObserver(mFocusedInputNode); mFocusedInputNode = nsnull; mFocusedInput = nsnull; } diff --git a/toolkit/components/satchel/nsFormFillController.h b/toolkit/components/satchel/nsFormFillController.h index ddca69b19d3c..5d5e9d2e94d3 100644 --- a/toolkit/components/satchel/nsFormFillController.h +++ b/toolkit/components/satchel/nsFormFillController.h @@ -101,6 +101,8 @@ protected: inline nsIDOMWindow *GetWindowForDocShell(nsIDocShell *aDocShell); inline PRInt32 GetIndexOfDocShell(nsIDocShell *aDocShell); + void MaybeRemoveMutationObserver(nsINode* aNode); + static PLDHashOperator RemoveForDocumentEnumerator(const nsINode* aKey, bool& aEntry, void* aUserData);