Always use the '0' dir for updates - Bug 588163 - Crash [@ @0x0 | ProcessUpdates(nsIFile*, nsIFile*, nsIFile*, int, char**, char const*&) ]. r=dtownsend, approval2.0=dtownsend
authorRobert Strong <robert.bugzilla@gmail.com>
Tue, 17 Aug 2010 20:09:07 -0400
changeset 50756 9480e51be5b71d5f91d5d6d12842c627068af979
parent 50755 73de7cbbf3111c68227b8b81698d31b18cbff127
child 50757 b6cf560ce576a2d0c112e815eeb39069fd730c68
push id15153
push userjmuizelaar@mozilla.com
push dateWed, 18 Aug 2010 00:09:54 +0000
treeherdermozilla-central@9480e51be5b7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdtownsend
bugs588163
milestone2.0b5pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Always use the '0' dir for updates - Bug 588163 - Crash [@ @0x0 | ProcessUpdates(nsIFile*, nsIFile*, nsIFile*, int, char**, char const*&) ]. r=dtownsend, approval2.0=dtownsend
toolkit/xre/nsUpdateDriver.cpp
--- a/toolkit/xre/nsUpdateDriver.cpp
+++ b/toolkit/xre/nsUpdateDriver.cpp
@@ -39,20 +39,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include <stdlib.h>
 #include <stdio.h>
 #include "nsUpdateDriver.h"
 #include "nsXULAppAPI.h"
 #include "nsAppRunner.h"
 #include "nsILocalFile.h"
-#include "nsISimpleEnumerator.h"
-#include "nsIDirectoryEnumerator.h"
 #include "nsCOMPtr.h"
-#include "nsCOMArray.h"
 #include "nsString.h"
 #include "nsPrintfCString.h"
 #include "prproces.h"
 #include "prlog.h"
 #include "nsVersionComparator.h"
 
 #ifdef XP_MACOSX
 #include "nsILocalFileMac.h"
@@ -174,58 +171,16 @@ GetXULRunnerStubPath(const char* argv0, 
   if (NS_FAILED(rv))
     return rv;
 
   NS_ADDREF(*aResult = lf);
   return NS_OK;
 }
 #endif /* XP_MACOSX */
 
-static int
-ScanDirComparator(nsIFile *a, nsIFile *b, void *unused)
-{
-  // lexically compare the leaf names of these two files
-  nsCAutoString a_name, b_name;
-  a->GetNativeLeafName(a_name);
-  b->GetNativeLeafName(b_name);
-  return Compare(a_name, b_name);
-}
-
-static nsresult
-ScanDir(nsIFile *dir, nsCOMArray<nsIFile> *result)
-{
-  nsresult rv;
-
-  nsCOMPtr<nsISimpleEnumerator> simpEnum;
-  rv = dir->GetDirectoryEntries(getter_AddRefs(simpEnum));
-  if (NS_FAILED(rv))
-    return rv;
-
-  nsCOMPtr<nsIDirectoryEnumerator> dirEnum = do_QueryInterface(simpEnum, &rv);
-  if (NS_FAILED(rv))
-    return rv;
-
-  nsCOMPtr<nsIFile> file;
-  for (;;) {
-    rv = dirEnum->GetNextFile(getter_AddRefs(file));
-    if (NS_FAILED(rv))
-      return rv;
-
-    // enumeration complete when null file is returned
-    if (!file)
-      break;
-
-    if (!result->AppendObject(file))
-      return NS_ERROR_OUT_OF_MEMORY;
-  }
-
-  result->Sort(ScanDirComparator, nsnull);
-  return NS_OK;
-}
-
 static PRBool
 GetFile(nsIFile *dir, const nsCSubstring &name, nsCOMPtr<nsILocalFile> &result)
 {
   nsresult rv;
   
   nsCOMPtr<nsIFile> file;
   rv = dir->Clone(getter_AddRefs(file));
   if (NS_FAILED(rv))
@@ -563,41 +518,33 @@ ProcessUpdates(nsIFile *greDir, nsIFile 
   nsCOMPtr<nsIFile> updatesDir;
   rv = updRootDir->Clone(getter_AddRefs(updatesDir));
   if (NS_FAILED(rv))
     return rv;
   rv = updatesDir->AppendNative(NS_LITERAL_CSTRING("updates"));
   if (NS_FAILED(rv))
     return rv;
 
+  rv = updatesDir->AppendNative(NS_LITERAL_CSTRING("0"));
+  if (NS_FAILED(rv))
+    return rv;
+
   PRBool exists;
   rv = updatesDir->Exists(&exists);
   if (NS_FAILED(rv) || !exists)
     return rv;
 
-  nsCOMArray<nsIFile> dirEntries;
-  rv = ScanDir(updatesDir, &dirEntries);
-  if (NS_FAILED(rv))
-    return rv;
-  if (dirEntries.Count() == 0)
-    return NS_OK;
-
-  // look for the first update subdirectory with a status of pending
-  for (int i = 0; i < dirEntries.Count(); ++i) {
-    nsCOMPtr<nsILocalFile> statusFile;
-    if (GetStatusFile(dirEntries[i], statusFile) && IsPending(statusFile)) {
-      nsCOMPtr<nsILocalFile> versionFile;
-      // Remove the update if the update application version file doesn't exist
-      // or if the update's application version is less than the current
-      // application version.
-      if (!GetVersionFile(dirEntries[i], versionFile) ||
-          IsOlderVersion(versionFile, appVersion)) {
-        dirEntries[i]->Remove(PR_TRUE);
-        continue;
-      }
-
-      ApplyUpdate(greDir, dirEntries[i], statusFile, appDir, argc, argv);
-      break;
+  nsCOMPtr<nsILocalFile> statusFile;
+  if (GetStatusFile(updatesDir, statusFile) && IsPending(statusFile)) {
+    nsCOMPtr<nsILocalFile> versionFile;
+    // Remove the update if the update application version file doesn't exist
+    // or if the update's application version is less than the current
+    // application version.
+    if (!GetVersionFile(updatesDir, versionFile) ||
+        IsOlderVersion(versionFile, appVersion)) {
+      updatesDir->Remove(PR_TRUE);
+    } else {
+      ApplyUpdate(greDir, updatesDir, statusFile, appDir, argc, argv);
     }
   }
 
   return NS_OK;
 }