fix crashes with offline imap operations, r/sr=standard8, 480090
authorDavid Bienvenu <bienvenu@nventure.com>
Mon, 08 Jun 2009 11:14:19 -0700
changeset 2805 14a9407ebddb8c5d0abbde11d2d18c4e76516d9a
parent 2804 86f9ec8efa439392362be2fc47f1758007fa04e2
child 2806 22248bfae2b78bd25a93ad4e180404c42759442e
push idunknown
push userunknown
push dateunknown
bugs480090
fix crashes with offline imap operations, r/sr=standard8, 480090
mailnews/db/msgdb/src/nsMsgOfflineImapOperation.cpp
mailnews/imap/src/nsImapOfflineSync.cpp
--- a/mailnews/db/msgdb/src/nsMsgOfflineImapOperation.cpp
+++ b/mailnews/db/msgdb/src/nsMsgOfflineImapOperation.cpp
@@ -80,16 +80,19 @@ nsMsgOfflineImapOperation::nsMsgOfflineI
   m_mdb->GetUint32Property(m_mdbRow, PROP_OPERATION, (PRUint32 *) &m_operation, 0);
   m_mdb->GetUint32Property(m_mdbRow, PROP_MESSAGE_KEY, &m_messageKey, 0);
   m_mdb->GetUint32Property(m_mdbRow, PROP_OPERATION_FLAGS, &m_operationFlags, 0);
   m_mdb->GetUint32Property(m_mdbRow, PROP_NEW_FLAGS, (PRUint32 *) &m_newFlags, 0);
 }
 
 nsMsgOfflineImapOperation::~nsMsgOfflineImapOperation()
 {
+  // clear the row first, in case we're holding the last reference
+  // to the db.
+  m_mdbRow = nsnull;
   NS_IF_RELEASE(m_mdb);
 }
 
 /* attribute nsOfflineImapOperationType operation; */
 NS_IMETHODIMP nsMsgOfflineImapOperation::GetOperation(nsOfflineImapOperationType *aOperation)
 {
   NS_ENSURE_ARG(aOperation);
   *aOperation = m_operation;
--- a/mailnews/imap/src/nsImapOfflineSync.cpp
+++ b/mailnews/imap/src/nsImapOfflineSync.cpp
@@ -478,20 +478,26 @@ nsImapOfflineSync::ProcessAppendMsgOpera
       }
     }
   }
 }
 
 void nsImapOfflineSync::ClearCurrentOps()
 {
   PRInt32 opCount = m_currentOpsToClear.Count();
-  for (PRInt32 i = 0; i < opCount; i++)
+  for (PRInt32 i = opCount - 1; i >= 0; i--)
   {
     m_currentOpsToClear[i]->SetPlayingBack(PR_FALSE);
     m_currentOpsToClear[i]->ClearOperation(mCurrentPlaybackOpType);
+    // if that was the last operation left for this object,
+    // remove the object from the array.
+    nsOfflineImapOperationType opsLeft;
+    m_currentOpsToClear[i]->GetOperation(&opsLeft);
+    if (!opsLeft)
+      m_currentOpsToClear.RemoveObjectAt(i);
   }
 }
 
 void nsImapOfflineSync::ProcessMoveOperation(nsIMsgOfflineImapOperation *op)
 {
   nsTArray<nsMsgKey> matchingFlagKeys;
   PRUint32 currentKeyIndex = m_KeyIndex;
   nsCString moveDestination;