Bug 409458 - nsIMsgFolder.AddFolderListener should hold a reference to the listener. r=standard8,neil,darktrojan,jorgk
authorHiroyuki Ikezoe <hiikezoe@mozilla-japan.org>
Thu, 30 Aug 2018 15:42:58 +1200
changeset 33111 2cfa24cfd1ac6984457e9bd952fb2e347670faba
parent 33110 a682d50b9f77d581c589af056c5fe49b40a8b436
child 33112 fe6d8f59182d7efcda98f23ec9ccb41f1cbfa710
push id387
push userclokep@gmail.com
push dateMon, 10 Dec 2018 21:30:47 +0000
reviewersstandard8, neil, darktrojan, jorgk
bugs409458
Bug 409458 - nsIMsgFolder.AddFolderListener should hold a reference to the listener. r=standard8,neil,darktrojan,jorgk
mailnews/base/test/unit/test_nsIFolderListener.js
mailnews/base/test/unit/xpcshell.ini
mailnews/base/util/nsMsgDBFolder.cpp
mailnews/base/util/nsMsgDBFolder.h
mailnews/compose/src/nsMsgSendLater.cpp
mailnews/compose/src/nsMsgSendLater.h
new file mode 100644
--- /dev/null
+++ b/mailnews/base/test/unit/test_nsIFolderListener.js
@@ -0,0 +1,45 @@
+/*
+ * Test that adding nsIFolderListener in js does not cause any crash.
+ */
+
+ChromeUtils.import("resource:///modules/MailServices.jsm");
+load("../../../resources/logHelper.js");
+load("../../../resources/asyncTestUtils.js");
+load("../../../resources/messageModifier.js");
+load("../../../resources/messageGenerator.js");
+load("../../../resources/messageInjection.js");
+
+var folderListener = {
+  OnItemAdded: function() {},
+  OnItemRemoved: function() {},
+  OnItemPropertyChanged: function() {},
+  OnItemIntPropertyChanged: function() {},
+  OnItemBoolPropertyChanged: function() {},
+  OnItemUnicharPropertyChanged: function() {},
+  OnItemPropertyFlagChanged: function() {},
+  OnItemEvent: function() {},
+}
+
+var targetFolder;
+
+var tests = [
+  function setup() {
+    gMessageGenerator = new MessageGenerator();
+
+    configure_message_injection({mode: "local"});
+
+    targetFolder = make_empty_folder();
+    targetFolder.AddFolderListener(folderListener);
+    registerCleanupFunction(function() {
+      targetFolder.RemoveFolderListener(folderListener);
+    });
+  },
+  async function create_new_message() {
+    let [msgSet] = make_new_sets_in_folder(targetFolder, [{count: 1}]);
+    await wait_for_message_injection();
+  }
+];
+
+function run_test() {
+  async_run_tests(tests);
+}
--- a/mailnews/base/test/unit/xpcshell.ini
+++ b/mailnews/base/test/unit/xpcshell.ini
@@ -73,8 +73,9 @@ skip-if = true # See bug 1418063.
 [test_searchTag.js]
 [test_searchUint32HdrProperty.js]
 [test_testsuite_base64.js]
 [test_testsuite_fakeserver_imapd_gmail.js]
 [test_testsuite_fakeserver_imapd_list-extended.js]
 [test_testsuite_fakeserverAuth.js]
 [test_viewSortByAddresses.js]
 [test_formatFileSize.js]
+[test_nsIFolderListener.js]
--- a/mailnews/base/util/nsMsgDBFolder.cpp
+++ b/mailnews/base/util/nsMsgDBFolder.cpp
@@ -4924,47 +4924,55 @@ NS_IMETHODIMP nsMsgDBFolder::CopyDataToO
   return aOutputStream->WriteFrom(aInStream, aLength, &uiWritten);
 }
 
 NS_IMETHODIMP nsMsgDBFolder::CopyDataDone()
 {
   return NS_OK;
 }
 
+#define NOTIFY_LISTENERS(propertyfunc_, params_) \
+  PR_BEGIN_MACRO \
+  nsTObserverArray<nsCOMPtr<nsIFolderListener>>::ForwardIterator iter(mListeners); \
+  nsCOMPtr<nsIFolderListener> listener; \
+  while (iter.HasMore()) { \
+    listener = iter.GetNext(); \
+    listener->propertyfunc_ params_; \
+  } \
+  PR_END_MACRO
+
 NS_IMETHODIMP
 nsMsgDBFolder::NotifyPropertyChanged(const nsACString &aProperty,
                                      const nsACString& aOldValue,
                                      const nsACString& aNewValue)
 {
-  NS_OBSERVER_ARRAY_NOTIFY_OBSERVERS(mListeners, nsIFolderListener,
-                                     OnItemPropertyChanged,
-                                     (this, aProperty,
-                                      nsCString(aOldValue).get(),
-                                      nsCString(aNewValue).get()));
+  NOTIFY_LISTENERS(OnItemPropertyChanged,
+                   (this, aProperty,
+                    nsCString(aOldValue).get(),
+                    nsCString(aNewValue).get()));
 
   // Notify listeners who listen to every folder
   nsresult rv;
   nsCOMPtr<nsIFolderListener> folderListenerManager =
            do_GetService(NS_MSGMAILSESSION_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
   return folderListenerManager->OnItemPropertyChanged(this, aProperty,
                                                       nsCString(aOldValue).get(),
                                                       nsCString(aNewValue).get());
 }
 
 NS_IMETHODIMP
 nsMsgDBFolder::NotifyUnicharPropertyChanged(const nsACString &aProperty,
                                           const nsAString& aOldValue,
                                           const nsAString& aNewValue)
 {
-  NS_OBSERVER_ARRAY_NOTIFY_OBSERVERS(mListeners, nsIFolderListener,
-                                     OnItemUnicharPropertyChanged,
-                                     (this, aProperty,
-                                      nsString(aOldValue).get(),
-                                      nsString(aNewValue).get()));
+  NOTIFY_LISTENERS(OnItemUnicharPropertyChanged,
+                   (this, aProperty,
+                    nsString(aOldValue).get(),
+                    nsString(aNewValue).get()));
 
   // Notify listeners who listen to every folder
   nsresult rv;
   nsCOMPtr<nsIFolderListener> folderListenerManager =
            do_GetService(NS_MSGMAILSESSION_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
   return folderListenerManager->OnItemUnicharPropertyChanged(this,
                                                  aProperty,
@@ -4977,53 +4985,50 @@ nsMsgDBFolder::NotifyIntPropertyChanged(
                                         int64_t aNewValue)
 {
   // Don't send off count notifications if they are turned off.
   if (!mNotifyCountChanges &&
       (aProperty.Equals(kTotalMessages)  ||
        aProperty.Equals(kTotalUnreadMessages)))
     return NS_OK;
 
-  NS_OBSERVER_ARRAY_NOTIFY_OBSERVERS(mListeners, nsIFolderListener,
-                                     OnItemIntPropertyChanged,
-                                     (this, aProperty, aOldValue, aNewValue));
+  NOTIFY_LISTENERS(OnItemIntPropertyChanged,
+                   (this, aProperty, aOldValue, aNewValue));
 
   // Notify listeners who listen to every folder
   nsresult rv;
   nsCOMPtr<nsIFolderListener> folderListenerManager =
            do_GetService(NS_MSGMAILSESSION_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
   return folderListenerManager->OnItemIntPropertyChanged(this, aProperty,
                                                          aOldValue, aNewValue);
 }
 
 NS_IMETHODIMP
 nsMsgDBFolder::NotifyBoolPropertyChanged(const nsACString &aProperty,
                                          bool aOldValue, bool aNewValue)
 {
-  NS_OBSERVER_ARRAY_NOTIFY_OBSERVERS(mListeners, nsIFolderListener,
-                                     OnItemBoolPropertyChanged,
-                                     (this, aProperty, aOldValue, aNewValue));
+  NOTIFY_LISTENERS(OnItemBoolPropertyChanged,
+                   (this, aProperty, aOldValue, aNewValue));
 
   // Notify listeners who listen to every folder
   nsresult rv;
   nsCOMPtr<nsIFolderListener> folderListenerManager =
            do_GetService(NS_MSGMAILSESSION_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
   return folderListenerManager->OnItemBoolPropertyChanged(this, aProperty,
                                                           aOldValue, aNewValue);
 }
 
 NS_IMETHODIMP
 nsMsgDBFolder::NotifyPropertyFlagChanged(nsIMsgDBHdr *aItem, const nsACString &aProperty,
                                          uint32_t aOldValue, uint32_t aNewValue)
 {
-  NS_OBSERVER_ARRAY_NOTIFY_OBSERVERS(mListeners, nsIFolderListener,
-                                     OnItemPropertyFlagChanged,
-                                     (aItem, aProperty, aOldValue, aNewValue));
+  NOTIFY_LISTENERS(OnItemPropertyFlagChanged,
+                   (aItem, aProperty, aOldValue, aNewValue));
 
   // Notify listeners who listen to every folder
   nsresult rv;
   nsCOMPtr<nsIFolderListener> folderListenerManager =
            do_GetService(NS_MSGMAILSESSION_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
   return folderListenerManager->OnItemPropertyFlagChanged(aItem, aProperty,
                                                           aOldValue, aNewValue);
@@ -5031,47 +5036,44 @@ nsMsgDBFolder::NotifyPropertyFlagChanged
 
 NS_IMETHODIMP nsMsgDBFolder::NotifyItemAdded(nsISupports *aItem)
 {
   static bool notify = true;
 
   if (!notify)
     return NS_OK;
 
-  NS_OBSERVER_ARRAY_NOTIFY_OBSERVERS(mListeners, nsIFolderListener,
-                                     OnItemAdded,
-                                     (this, aItem));
+  NOTIFY_LISTENERS(OnItemAdded,
+                   (this, aItem));
 
   // Notify listeners who listen to every folder
   nsresult rv;
   nsCOMPtr<nsIFolderListener> folderListenerManager =
            do_GetService(NS_MSGMAILSESSION_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
   return folderListenerManager->OnItemAdded(this, aItem);
 }
 
 nsresult nsMsgDBFolder::NotifyItemRemoved(nsISupports *aItem)
 {
-  NS_OBSERVER_ARRAY_NOTIFY_OBSERVERS(mListeners, nsIFolderListener,
-                                     OnItemRemoved,
-                                     (this, aItem));
+  NOTIFY_LISTENERS(OnItemRemoved,
+                   (this, aItem));
 
   // Notify listeners who listen to every folder
   nsresult rv;
   nsCOMPtr<nsIFolderListener> folderListenerManager =
            do_GetService(NS_MSGMAILSESSION_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
   return folderListenerManager->OnItemRemoved(this, aItem);
 }
 
 nsresult nsMsgDBFolder::NotifyFolderEvent(const nsACString &aEvent)
 {
-  NS_OBSERVER_ARRAY_NOTIFY_OBSERVERS(mListeners, nsIFolderListener,
-                                     OnItemEvent,
-                                     (this, aEvent));
+  NOTIFY_LISTENERS(OnItemEvent,
+                   (this, aEvent));
 
   //Notify listeners who listen to every folder
   nsresult rv;
   nsCOMPtr<nsIFolderListener> folderListenerManager =
            do_GetService(NS_MSGMAILSESSION_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
   return folderListenerManager->OnItemEvent(this, aEvent);
 }
--- a/mailnews/base/util/nsMsgDBFolder.h
+++ b/mailnews/base/util/nsMsgDBFolder.h
@@ -209,18 +209,17 @@ protected:
 
   uint32_t mFlags;
   nsWeakPtr mParent;     //This won't be refcounted for ownership reasons.
   int32_t mNumUnreadMessages;        /* count of unread messages (-1 means unknown; -2 means unknown but we already tried to find out.) */
   int32_t mNumTotalMessages;         /* count of existing messages. */
   bool mNotifyCountChanges;
   int64_t mExpungedBytes;
   nsCOMArray<nsIMsgFolder> mSubFolders;
-  // This can't be refcounted due to ownsership issues
-  nsTObserverArray<nsIFolderListener*> mListeners;
+  nsTObserverArray<nsCOMPtr<nsIFolderListener>> mListeners;
 
   bool mInitializedFromCache;
   nsISupports *mSemaphoreHolder; // set when the folder is being written to
                                  //Due to ownership issues, this won't be AddRef'd.
 
   nsWeakPtr mServer;
 
   // These values are used for tricking the front end into thinking that we have more
--- a/mailnews/compose/src/nsMsgSendLater.cpp
+++ b/mailnews/compose/src/nsMsgSendLater.cpp
@@ -112,22 +112,23 @@ nsMsgSendLater::Init()
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = observerService->AddObserver(this, "msg-shutdown", false);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Subscribe to the unsent messages folder
   // XXX This code should be set up for multiple unsent folders, however we
   // don't support that at the moment, so for now just assume one folder.
-  rv = GetUnsentMessagesFolder(nullptr, getter_AddRefs(mMessageFolder));
+  nsCOMPtr<nsIMsgFolder> folder;
+  rv = GetUnsentMessagesFolder(nullptr, getter_AddRefs(folder));
   // There doesn't have to be a nsMsgQueueForLater flagged folder.
-  if (NS_FAILED(rv) || !mMessageFolder)
+  if (NS_FAILED(rv) || !folder)
     return NS_OK;
 
-  rv = mMessageFolder->AddFolderListener(this);
+  rv = folder->AddFolderListener(this);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // XXX may want to send messages X seconds after startup if there are any.
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -159,18 +160,22 @@ nsMsgSendLater::Observe(nsISupports *aSu
   else if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID))
   {
     // We're shutting down. Unsubscribe from the unsentFolder notifications
     // they aren't any use to us now, we don't want to start sending more
     // messages.
     nsresult rv;
     if (mMessageFolder)
     {
-      rv = mMessageFolder->RemoveFolderListener(this);
-      NS_ENSURE_SUCCESS(rv, rv);
+      nsCOMPtr<nsIMsgFolder> folder = do_QueryReferent(mMessageFolder, &rv);
+      if (folder)
+      {
+        rv = folder->RemoveFolderListener(this);
+        NS_ENSURE_SUCCESS(rv, rv);
+      }
     }
 
     // Now remove ourselves from the observer service as well.
     nsCOMPtr<nsIObserverService> observerService =
       mozilla::services::GetObserverService();
     NS_ENSURE_TRUE(observerService, NS_ERROR_UNEXPECTED);
 
     rv = observerService->RemoveObserver(this, "xpcom-shutdown");
@@ -605,17 +610,19 @@ nsMsgSendLater::StartNextMailFileSend(ns
   mMessage = do_QueryInterface(currentItem);
   if (!mMessage)
     return NS_ERROR_NOT_AVAILABLE;
 
   if (!mMessageFolder)
     return NS_ERROR_UNEXPECTED;
 
   nsCString messageURI;
-  mMessageFolder->GetUriForMsg(mMessage, messageURI);
+  nsCOMPtr<nsIMsgFolder> folder = do_QueryReferent(mMessageFolder, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+  folder->GetUriForMsg(mMessage, messageURI);
 
   rv = nsMsgCreateTempFile("nsqmail.tmp", getter_AddRefs(mTempFile));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIMsgMessageService> messageService;
   rv = GetMessageServiceFromURI(messageURI, getter_AddRefs(messageService));
   if (NS_FAILED(rv) && !messageService)
     return NS_ERROR_FACTORY_NOT_LOADED;
@@ -652,22 +659,31 @@ nsMsgSendLater::StartNextMailFileSend(ns
                                       static_cast<nsIStreamListener*>(this),
                                       nullptr, nullptr, nullptr,
                                       getter_AddRefs(dummyNull));
 
   return rv;
 }
 
 NS_IMETHODIMP
-nsMsgSendLater::GetUnsentMessagesFolder(nsIMsgIdentity *aIdentity, nsIMsgFolder **folder)
+nsMsgSendLater::GetUnsentMessagesFolder(nsIMsgIdentity *aIdentity, nsIMsgFolder **aFolder)
 {
-  nsCString uri;
-  GetFolderURIFromUserPrefs(nsIMsgSend::nsMsgQueueForLater, aIdentity, uri);
-  return LocateMessageFolder(aIdentity, nsIMsgSend::nsMsgQueueForLater,
-                             uri.get(), folder);
+  nsresult rv = NS_OK;
+  nsCOMPtr<nsIMsgFolder> folder = do_QueryReferent(mMessageFolder);
+  if (!folder) {
+    nsCString uri;
+    GetFolderURIFromUserPrefs(nsIMsgSend::nsMsgQueueForLater, aIdentity, uri);
+    rv = LocateMessageFolder(aIdentity, nsIMsgSend::nsMsgQueueForLater, uri.get(), getter_AddRefs(folder));
+    mMessageFolder = do_GetWeakReference(folder);
+    if (!mMessageFolder)
+      return NS_ERROR_FAILURE;
+  }
+  if (folder)
+    folder.forget(aFolder);
+  return rv;
 }
 
 NS_IMETHODIMP
 nsMsgSendLater::HasUnsentMessages(nsIMsgIdentity *aIdentity, bool *aResult)
 {
   NS_ENSURE_ARG_POINTER(aResult);
   *aResult = false;
   nsresult rv;
@@ -684,26 +700,29 @@ nsMsgSendLater::HasUnsentMessages(nsIMsg
   rv = accounts->GetLength(&cnt);
   if (cnt == 0)
     return NS_OK; // no account set up -> no unsent messages
 
   // XXX This code should be set up for multiple unsent folders, however we
   // don't support that at the moment, so for now just assume one folder.
   if (!mMessageFolder)
   {
-    rv = GetUnsentMessagesFolder(nullptr, getter_AddRefs(mMessageFolder));
+    nsCOMPtr<nsIMsgFolder> folder;
+    rv = GetUnsentMessagesFolder(nullptr, getter_AddRefs(folder));
     // There doesn't have to be a nsMsgQueueForLater flagged folder.
-    if (NS_FAILED(rv) || !mMessageFolder)
+    if (NS_FAILED(rv) || !folder)
       return NS_OK;
   }
   rv = ReparseDBIfNeeded(nullptr);
   NS_ENSURE_SUCCESS(rv, rv);
 
   int32_t totalMessages;
-  rv = mMessageFolder->GetTotalMessages(false, &totalMessages);
+  nsCOMPtr<nsIMsgFolder> folder = do_QueryReferent(mMessageFolder, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = folder->GetTotalMessages(false, &totalMessages);
   NS_ENSURE_SUCCESS(rv, rv);
 
   *aResult = totalMessages > 0;
   return NS_OK;
 }
 
 //
 // To really finalize this capability, we need to have the ability to get
@@ -736,17 +755,17 @@ nsMsgSendLater::SendUnsentMessages(nsIMs
 
 // Returns NS_OK if the db is OK, an error otherwise, e.g., we had to reparse.
 nsresult nsMsgSendLater::ReparseDBIfNeeded(nsIUrlListener *aListener)
 {
   // This will kick off a reparse, if needed. So the next time we check if
   // there are unsent messages, the db will be up to date.
   nsCOMPtr<nsIMsgDatabase> unsentDB;
   nsresult rv;
-  nsCOMPtr<nsIMsgLocalMailFolder> locFolder(do_QueryInterface(mMessageFolder, &rv));
+  nsCOMPtr<nsIMsgLocalMailFolder> locFolder(do_QueryReferent(mMessageFolder, &rv));
   NS_ENSURE_SUCCESS(rv, rv);
   return locFolder->GetDatabaseWithReparse(aListener, nullptr,
                                            getter_AddRefs(unsentDB));
 }
 
 nsresult
 nsMsgSendLater::InternalSendMessages(bool aUserInitiated,
                                      nsIMsgIdentity *aIdentity)
@@ -762,30 +781,33 @@ nsMsgSendLater::InternalSendMessages(boo
   }
 
   nsresult rv;
 
   // XXX This code should be set up for multiple unsent folders, however we
   // don't support that at the moment, so for now just assume one folder.
   if (!mMessageFolder)
   {
-    rv = GetUnsentMessagesFolder(nullptr,
-                                 getter_AddRefs(mMessageFolder));
-    NS_ENSURE_SUCCESS(rv, rv);
+    nsCOMPtr<nsIMsgFolder> folder;
+    rv = GetUnsentMessagesFolder(nullptr, getter_AddRefs(folder));
+    if (NS_FAILED(rv) || !folder)
+      return NS_ERROR_FAILURE;
   }
   nsCOMPtr<nsIMsgDatabase> unsentDB;
   // Remember these in case we need to reparse the db.
   mUserInitiated = aUserInitiated;
   mIdentity = aIdentity;
   rv = ReparseDBIfNeeded(this);
   NS_ENSURE_SUCCESS(rv, rv);
   mIdentity = nullptr; // don't hold onto the identity since we're a service.
 
   nsCOMPtr<nsISimpleEnumerator> enumerator;
-  rv = mMessageFolder->GetMessages(getter_AddRefs(enumerator));
+  nsCOMPtr<nsIMsgFolder> folder = do_QueryReferent(mMessageFolder, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = folder->GetMessages(getter_AddRefs(enumerator));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // copy all the elements in the enumerator into our isupports array....
 
   nsCOMPtr<nsISupports> currentItem;
   nsCOMPtr<nsIMsgDBHdr> messageHeader;
   bool hasMoreElements = false;
   while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreElements)) && hasMoreElements)
@@ -881,18 +903,21 @@ nsMsgSendLater::DeleteCurrentMessage()
   if (!msgArray)
     return NS_ERROR_FACTORY_NOT_LOADED;
 
   if (!mMessageFolder)
     return NS_ERROR_UNEXPECTED;
 
   msgArray->InsertElementAt(mMessage, 0);
 
-  nsresult res = mMessageFolder->DeleteMessages(msgArray, nullptr, true, false, nullptr, false /*allowUndo*/);
-  if (NS_FAILED(res))
+  nsresult rv;
+  nsCOMPtr<nsIMsgFolder> folder = do_QueryReferent(mMessageFolder, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = folder->DeleteMessages(msgArray, nullptr, true, false, nullptr, false /*allowUndo*/);
+  if (NS_FAILED(rv))
     return NS_ERROR_FAILURE;
 
   // Null out the message so we don't try and delete it again.
   mMessage = nullptr;
 
   return NS_OK;
 }
 
@@ -1308,18 +1333,21 @@ nsMsgSendLater::EndSendMessages(nsresult
   // StartNextMailFileSend to fully finish the sending. Therefore set
   // mSendingMessages to false here so that we don't think we're still trying
   // to send messages
   mSendingMessages = false;
 
   // Clear out our array of messages.
   mMessagesToSend.Clear();
 
+  nsresult rv;
+  nsCOMPtr<nsIMsgFolder> folder = do_QueryReferent(mMessageFolder, &rv);
+  NS_ENSURE_SUCCESS(rv,);
   // We don't need to keep hold of the database now we've finished sending.
-  (void)mMessageFolder->SetMsgDatabase(nullptr);
+  (void)folder->SetMsgDatabase(nullptr);
 
   // or the enumerator, temp file or output stream
   mEnumerator = nullptr;
   mTempFile = nullptr;
   mOutFile = nullptr;
 
   NOTIFY_LISTENERS(OnStopSending, (aStatus, aMsg, aTotalTried, aSuccessful));
 
--- a/mailnews/compose/src/nsMsgSendLater.h
+++ b/mailnews/compose/src/nsMsgSendLater.h
@@ -12,16 +12,17 @@
 #include "nsIMsgSendLaterListener.h"
 #include "nsIMsgSendLater.h"
 #include "nsIMsgStatusFeedback.h"
 #include "nsTObserverArray.h"
 #include "nsIObserver.h"
 #include "nsITimer.h"
 #include "nsCOMPtr.h"
 #include "nsIMsgShutdown.h"
+#include "nsWeakPtr.h"
 
 ////////////////////////////////////////////////////////////////////////////////////
 // This is the listener class for the send operation. We have to create this class
 // to listen for message send completion and eventually notify the caller
 ////////////////////////////////////////////////////////////////////////////////////
 class nsMsgSendLater;
 
 class SendOperationListener : public nsIMsgSendListener,
@@ -89,17 +90,17 @@ public:
   bool OnSendStepFinished(nsresult aStatus);
   void OnCopyStepFinished(nsresult aStatus);
 
   // counters and things for enumeration
   uint32_t                  mTotalSentSuccessfully;
   uint32_t                  mTotalSendCount;
   nsCOMArray<nsIMsgDBHdr> mMessagesToSend;
   nsCOMPtr<nsISimpleEnumerator> mEnumerator;
-  nsCOMPtr<nsIMsgFolder>    mMessageFolder;
+  nsWeakPtr mMessageFolder;
   nsCOMPtr<nsIMsgStatusFeedback> mFeedback;
 
   // Private Information
 private:
   virtual ~nsMsgSendLater();
   nsresult GetIdentityFromKey(const char *aKey, nsIMsgIdentity **aIdentity);
   nsresult ReparseDBIfNeeded(nsIUrlListener *aListener);
   nsresult InternalSendMessages(bool aUserInitiated,