Bug 526047 - crash getting mail @ nsAddrDatabase::GetRowForCharColumn - nsSpamSettings::CheckWhiteList [@ nsAddrDatabase::GetRowForCharColumn(unsigned short const*, unsigned int, int, int, nsIMdbRow**, int*)]. r=dbienvenu,a=Standard8
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Mon, 03 Sep 2012 13:39:26 +0900
changeset 13608 0bf1c27bcdb07e63c2b08b60dcf708637ba806f6
parent 13607 830f2f1e3a3664956d6a3dce505962d78b40212b
child 13609 9d685c35a83982adfe96f8c74f32fb7db6dc5c35
push id30
push userbugzilla@standard8.plus.com
push dateFri, 08 Feb 2013 19:06:23 +0000
reviewersdbienvenu, Standard8
bugs526047
Bug 526047 - crash getting mail @ nsAddrDatabase::GetRowForCharColumn - nsSpamSettings::CheckWhiteList [@ nsAddrDatabase::GetRowForCharColumn(unsigned short const*, unsigned int, int, int, nsIMdbRow**, int*)]. r=dbienvenu,a=Standard8
mailnews/addrbook/src/nsAddrDatabase.cpp
--- a/mailnews/addrbook/src/nsAddrDatabase.cpp
+++ b/mailnews/addrbook/src/nsAddrDatabase.cpp
@@ -501,129 +501,128 @@ nsAddrDatabase::OpenInternal(nsIFile *aM
   return rv;
 }
 
 // Open the MDB database synchronously. If successful, this routine
 // will set up the m_mdbStore and m_mdbEnv of the database object
 // so other database calls can work.
 NS_IMETHODIMP nsAddrDatabase::OpenMDB(nsIFile *dbName, bool create)
 {
-  nsresult ret = NS_OK;
+  nsresult ret;
   nsCOMPtr<nsIMdbFactory> mdbFactory;
   GetMDBFactory(getter_AddRefs(mdbFactory));
-  if (mdbFactory)
+  NS_ENSURE_TRUE(mdbFactory, NS_ERROR_FAILURE);
+
+  ret = mdbFactory->MakeEnv(NULL, &m_mdbEnv);
+  if (NS_SUCCEEDED(ret))
   {
-    ret = mdbFactory->MakeEnv(NULL, &m_mdbEnv);
-    if (NS_SUCCEEDED(ret))
+    nsIMdbThumb *thumb = nullptr;
+    nsCAutoString filePath;
+
+    ret = dbName->GetNativePath(filePath);
+    NS_ENSURE_SUCCESS(ret, ret);
+
+    nsIMdbHeap* dbHeap = 0;
+    mdb_bool dbFrozen = mdbBool_kFalse; // not readonly, we want modifiable
+
+    if (m_mdbEnv)
+      m_mdbEnv->SetAutoClear(true);
+
+    bool dbNameExists = false;
+    ret = dbName->Exists(&dbNameExists);
+    NS_ENSURE_SUCCESS(ret, ret);
+
+    if (!dbNameExists)
+      ret = NS_ERROR_FILE_NOT_FOUND;
+    else
     {
-      nsIMdbThumb *thumb = nullptr;
-      nsCAutoString filePath;
-
-      ret = dbName->GetNativePath(filePath);
+      mdbOpenPolicy inOpenPolicy;
+      mdb_bool    canOpen;
+      mdbYarn        outFormatVersion;
+      nsIMdbFile* oldFile = 0;
+      int64_t fileSize;
+      ret = dbName->GetFileSize(&fileSize);
       NS_ENSURE_SUCCESS(ret, ret);
 
-      nsIMdbHeap* dbHeap = 0;
-      mdb_bool dbFrozen = mdbBool_kFalse; // not readonly, we want modifiable
-
-      if (m_mdbEnv)
-        m_mdbEnv->SetAutoClear(true);
-
-      bool dbNameExists = false;
-      ret = dbName->Exists(&dbNameExists);
-      NS_ENSURE_SUCCESS(ret, ret);
-
-      if (!dbNameExists)
-        ret = NS_ERROR_FILE_NOT_FOUND;
-      else
+      ret = mdbFactory->OpenOldFile(m_mdbEnv, dbHeap, filePath.get(),
+                                    dbFrozen, &oldFile);
+      if ( oldFile )
       {
-        mdbOpenPolicy inOpenPolicy;
-        mdb_bool    canOpen;
-        mdbYarn        outFormatVersion;
-        nsIMdbFile* oldFile = 0;
-        int64_t fileSize;
-        ret = dbName->GetFileSize(&fileSize);
-        NS_ENSURE_SUCCESS(ret, ret);
-
-        ret = mdbFactory->OpenOldFile(m_mdbEnv, dbHeap, filePath.get(),
-          dbFrozen, &oldFile);
-        if ( oldFile )
+        if ( ret == NS_OK )
         {
-          if ( ret == NS_OK )
+          ret = mdbFactory->CanOpenFilePort(m_mdbEnv, oldFile, // the file to investigate
+                                            &canOpen, &outFormatVersion);
+          if (ret == 0 && canOpen)
           {
-            ret = mdbFactory->CanOpenFilePort(m_mdbEnv, oldFile, // the file to investigate
-              &canOpen, &outFormatVersion);
-            if (ret == 0 && canOpen)
-            {
-              inOpenPolicy.mOpenPolicy_ScopePlan.mScopeStringSet_Count = 0;
-              inOpenPolicy.mOpenPolicy_MinMemory = 0;
-              inOpenPolicy.mOpenPolicy_MaxLazy = 0;
-
-              ret = mdbFactory->OpenFileStore(m_mdbEnv, dbHeap,
-                oldFile, &inOpenPolicy, &thumb);
-            }
-            else if (fileSize != 0)
-              ret = NS_ERROR_FILE_ACCESS_DENIED;
-          }
-          NS_RELEASE(oldFile); // always release our file ref, store has own
-        }
-        if (NS_FAILED(ret))
-          ret = NS_ERROR_FILE_ACCESS_DENIED;
-      }
-
-      if (NS_SUCCEEDED(ret) && thumb)
-      {
-        mdb_count outTotal;    // total somethings to do in operation
-        mdb_count outCurrent;  // subportion of total completed so far
-        mdb_bool outDone = false;      // is operation finished?
-        mdb_bool outBroken;     // is operation irreparably dead and broken?
-        do
-        {
-          ret = thumb->DoMore(m_mdbEnv, &outTotal, &outCurrent, &outDone, &outBroken);
-          if (ret != 0)
-          {
-            outDone = true;
-            break;
-          }
-        }
-        while (NS_SUCCEEDED(ret) && !outBroken && !outDone);
-        if (NS_SUCCEEDED(ret) && outDone)
-        {
-          ret = mdbFactory->ThumbToOpenStore(m_mdbEnv, thumb, &m_mdbStore);
-          if (ret == NS_OK && m_mdbStore)
-          {
-            ret = InitExistingDB();
-            create = false;
-          }
-        }
-      }
-      else if (create && ret != NS_ERROR_FILE_ACCESS_DENIED)
-      {
-        nsIMdbFile* newFile = 0;
-        ret = mdbFactory->CreateNewFile(m_mdbEnv, dbHeap, filePath.get(), &newFile);
-        if ( newFile )
-        {
-          if (ret == NS_OK)
-          {
-            mdbOpenPolicy inOpenPolicy;
-
             inOpenPolicy.mOpenPolicy_ScopePlan.mScopeStringSet_Count = 0;
             inOpenPolicy.mOpenPolicy_MinMemory = 0;
             inOpenPolicy.mOpenPolicy_MaxLazy = 0;
 
-            ret = mdbFactory->CreateNewFileStore(m_mdbEnv, dbHeap,
-                                                   newFile, &inOpenPolicy,
-                                                   &m_mdbStore);
-            if (ret == NS_OK)
-              ret = InitNewDB();
+            ret = mdbFactory->OpenFileStore(m_mdbEnv, dbHeap,
+                                            oldFile, &inOpenPolicy, &thumb);
           }
-          NS_RELEASE(newFile); // always release our file ref, store has own
+          else if (fileSize != 0)
+            ret = NS_ERROR_FILE_ACCESS_DENIED;
+        }
+        NS_RELEASE(oldFile); // always release our file ref, store has own
+      }
+      if (NS_FAILED(ret))
+        ret = NS_ERROR_FILE_ACCESS_DENIED;
+    }
+
+    if (NS_SUCCEEDED(ret) && thumb)
+    {
+      mdb_count outTotal;    // total somethings to do in operation
+      mdb_count outCurrent;  // subportion of total completed so far
+      mdb_bool outDone = false;      // is operation finished?
+      mdb_bool outBroken;     // is operation irreparably dead and broken?
+      do
+      {
+        ret = thumb->DoMore(m_mdbEnv, &outTotal, &outCurrent, &outDone, &outBroken);
+        if (ret != 0)
+        {
+          outDone = true;
+          break;
         }
       }
-      NS_IF_RELEASE(thumb);
+      while (NS_SUCCEEDED(ret) && !outBroken && !outDone);
+      if (NS_SUCCEEDED(ret) && outDone)
+      {
+        ret = mdbFactory->ThumbToOpenStore(m_mdbEnv, thumb, &m_mdbStore);
+        if (ret == NS_OK && m_mdbStore)
+        {
+          ret = InitExistingDB();
+          create = false;
+        }
+      }
     }
+    else if (create && ret != NS_ERROR_FILE_ACCESS_DENIED)
+    {
+      nsIMdbFile* newFile = 0;
+      ret = mdbFactory->CreateNewFile(m_mdbEnv, dbHeap, filePath.get(), &newFile);
+      if ( newFile )
+      {
+        if (ret == NS_OK)
+        {
+          mdbOpenPolicy inOpenPolicy;
+
+          inOpenPolicy.mOpenPolicy_ScopePlan.mScopeStringSet_Count = 0;
+          inOpenPolicy.mOpenPolicy_MinMemory = 0;
+          inOpenPolicy.mOpenPolicy_MaxLazy = 0;
+
+          ret = mdbFactory->CreateNewFileStore(m_mdbEnv, dbHeap,
+                                               newFile, &inOpenPolicy,
+                                               &m_mdbStore);
+          if (ret == NS_OK)
+            ret = InitNewDB();
+        }
+        NS_RELEASE(newFile); // always release our file ref, store has own
+      }
+    }
+    NS_IF_RELEASE(thumb);
   }
   //Convert the DB error to a valid nsresult error.
   if (ret == 1)
     ret = NS_ERROR_FAILURE;
   return ret;
 }
 
 NS_IMETHODIMP nsAddrDatabase::CloseMDB(bool commit)
@@ -3267,18 +3266,17 @@ nsresult
 nsAddrDatabase::GetRowForCharColumn(const PRUnichar *unicodeStr,
                                     mdb_column findColumn, bool aIsCard,
                                     bool aCaseInsensitive,
                                     nsIMdbRow **aFindRow,
                                     mdb_pos *aRowPos)
 {
   NS_ENSURE_ARG_POINTER(unicodeStr);
   NS_ENSURE_ARG_POINTER(aFindRow);
-  if (!m_mdbEnv)
-    return NS_ERROR_NULL_POINTER;
+  NS_ENSURE_TRUE(m_mdbEnv && m_mdbPabTable, NS_ERROR_NULL_POINTER);
 
   *aFindRow = nullptr;
 
   // see bug #198303
   // the addition of the m_mdbDeletedCardsTable table has complicated life in the addressbook
   // (it was added for palm sync).  until we fix the underlying problem, we have to jump through hoops
   // in order to know if we have a row (think card) for a given column value (think email=foo@bar.com)
   // there are 4 scenarios: