[tor-commits] [tor-browser/tor-browser-38.7.1esr-6.0-1] fixup! Bug 13252 - Do not store data in the app bundle

gk at torproject.org gk at torproject.org
Wed Mar 30 19:07:32 UTC 2016


commit b9a6bef70d96a5aab0cea088d2dc3da4a17354a0
Author: Kathy Brade <brade at pearlcrescent.com>
Date:   Wed Mar 30 10:59:23 2016 -0400

    fixup! Bug 13252 - Do not store data in the app bundle
    
    On Mac OS, store user data under
    ~/Library/Application Support/TorBrowser-Data if the application
    is installed in a directory whose path contains "/Applications" or
    if the user lacks write permission to the directory that contains
    TorBrowser.app.
    
    Since the TorBrowser-Data directory may be shared among different
    installations of the application on Mac OS, embed the app path in
    the update dir so that the update history is partitioned.
---
 toolkit/xre/nsAppRunner.cpp            |  34 +++++----
 toolkit/xre/nsXREDirProvider.cpp       | 118 ++++++++++++------------------
 toolkit/xre/nsXREDirProvider.h         |   7 +-
 xpcom/io/TorFileUtils.cpp              | 130 +++++++++++++++++++++++++++++++++
 xpcom/io/TorFileUtils.h                |  35 +++++++++
 xpcom/io/moz.build                     |   2 +
 xpcom/io/nsAppFileLocationProvider.cpp |  52 ++++---------
 7 files changed, 255 insertions(+), 123 deletions(-)

diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp
index 4eb084b..700afb8 100644
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -2413,13 +2413,16 @@ static nsresult GetAppRootDir(nsIFile *aAppDir, nsIFile **aAppRootDir)
 static ProfileStatus CheckTorBrowserDataWriteAccess(nsIFile *aAppDir)
 {
   // Check whether we can write to the directory that will contain
-  // TorBrowser-Data, i.e., the directory that is above the application
-  // root directory.
-  nsCOMPtr<nsIFile> appRootDir;
-  nsresult rv = GetAppRootDir(aAppDir, getter_AddRefs(appRootDir));
+  // TorBrowser-Data.
+  nsCOMPtr<nsIFile> tbDataDir;
+  nsXREDirProvider* dirProvider = nsXREDirProvider::GetSingleton();
+  if (!dirProvider)
+    return PROFILE_STATUS_OTHER_ERROR;
+  nsresult rv =
+              dirProvider->GetTorBrowserUserDataDir(getter_AddRefs(tbDataDir));
   NS_ENSURE_SUCCESS(rv, PROFILE_STATUS_OTHER_ERROR);
   nsCOMPtr<nsIFile> tbDataDirParent;
-  rv = appRootDir->GetParent(getter_AddRefs(tbDataDirParent));
+  rv = tbDataDir->GetParent(getter_AddRefs(tbDataDirParent));
   NS_ENSURE_SUCCESS(rv, PROFILE_STATUS_OTHER_ERROR);
   return CheckProfileWriteAccess(tbDataDirParent);
 }
@@ -2550,12 +2553,12 @@ migrateInAppTorBrowserProfile(nsIToolkitProfile *aProfile, nsIFile *aAppDir)
                                         NS_LITERAL_CSTRING("TorBrowser"));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  // Create an nsIFile for the TorBrowser-Data directory (next to the app).
+  // Get an nsIFile for the TorBrowser-Data directory.
   nsCOMPtr<nsIFile> newTBDataDir;
-  rv = appRootDir->GetParent(getter_AddRefs(newTBDataDir));
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = newTBDataDir->AppendRelativeNativePath(
-                                      NS_LITERAL_CSTRING("TorBrowser-Data"));
+  nsXREDirProvider* dirProvider = nsXREDirProvider::GetSingleton();
+  if (!dirProvider)
+    return NS_ERROR_UNEXPECTED;
+  rv = dirProvider->GetTorBrowserUserDataDir(getter_AddRefs(newTBDataDir));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Try to migrate the browser profile. If this fails, we return an error
@@ -2588,9 +2591,14 @@ migrateInAppTorBrowserProfile(nsIToolkitProfile *aProfile, nsIFile *aAppDir)
   }
 
   // Try to migrate the UpdateInfo directory.
-  nsAutoCString updateInfoPath(NS_LITERAL_CSTRING("UpdateInfo"));
-  nsresult rv2 = migrateOneTorBrowserDataDir(oldTorBrowserDir, updateInfoPath,
-                                             newTBDataDir, updateInfoPath);
+  nsCOMPtr<nsIFile> newUpdateInfoDir;
+  nsresult rv2 = dirProvider->GetUpdateRootDir(
+                                            getter_AddRefs(newUpdateInfoDir));
+  if (NS_SUCCEEDED(rv2)) {
+    nsAutoCString updateInfoPath(NS_LITERAL_CSTRING("UpdateInfo"));
+    rv2 = migrateOneTorBrowserDataDir(oldTorBrowserDir, updateInfoPath,
+                                      newUpdateInfoDir, NS_LITERAL_CSTRING(""));
+  }
 
   // If all pieces of the migration succeeded, remove the old TorBrowser
   // directory.
diff --git a/toolkit/xre/nsXREDirProvider.cpp b/toolkit/xre/nsXREDirProvider.cpp
index 675039e..28f0210 100644
--- a/toolkit/xre/nsXREDirProvider.cpp
+++ b/toolkit/xre/nsXREDirProvider.cpp
@@ -39,6 +39,8 @@
 #include "mozilla/Preferences.h"
 #include "mozilla/Telemetry.h"
 
+#include "TorFileUtils.h"
+
 #include <stdlib.h>
 
 #ifdef XP_WIN
@@ -1023,40 +1025,48 @@ nsXREDirProvider::GetUpdateRootDir(nsIFile* *aResult)
                                       getter_AddRefs(updRoot));
   NS_ENSURE_SUCCESS(rv, rv);
 
-#else
+#elif defined(TOR_BROWSER_UPDATE)
+  // For Tor Browser, we store update history, etc. within the UpdateInfo
+  // directory under the user data directory.
+  nsresult rv = GetTorBrowserUserDataDir(getter_AddRefs(updRoot));
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = updRoot->AppendNative(NS_LITERAL_CSTRING("UpdateInfo"));
+  NS_ENSURE_SUCCESS(rv, rv);
+#if defined(XP_MACOSX) && defined(TOR_BROWSER_DATA_OUTSIDE_APP_DIR)
+  // Since the TorBrowser-Data directory may be shared among different
+  // installations of the application, embed the app path in the update dir
+  // so that the update history is partitioned. This is much less likely to
+  // be an issue on Linux or Windows because the Tor Browser packages for
+  // those platforms include a "container" folder that provides partitioning
+  // by default, and we do not support use of a shared, OS-recommended area
+  // for user data on those platforms.
   nsCOMPtr<nsIFile> appFile;
   bool per = false;
-  nsresult rv = GetFile(XRE_EXECUTABLE_FILE, &per, getter_AddRefs(appFile));
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = appFile->GetParent(getter_AddRefs(updRoot));
+  rv = GetFile(XRE_EXECUTABLE_FILE, &per, getter_AddRefs(appFile));
   NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<nsIFile> appRootDirFile;
+  nsAutoString appDirPath;
+  if (NS_FAILED(appFile->GetParent(getter_AddRefs(appRootDirFile))) ||
+      NS_FAILED(appRootDirFile->GetPath(appDirPath))) {
+    return NS_ERROR_FAILURE;
+  }
 
-#ifdef XP_MACOSX
-#ifdef TOR_BROWSER_UPDATE
-#ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR
-  // For Tor Browser, we cannot store update history, etc. under the user's
-  // home directory. Instead, we place it under
-  // Tor Browser.app/../TorBrowser-Data/UpdateInfo/
-  nsCOMPtr<nsIFile> appRootDir;
-  rv = GetAppRootDir(getter_AddRefs(appRootDir));
-  NS_ENSURE_SUCCESS(rv, rv);
-  nsCOMPtr<nsIFile> localDir;
-  rv = appRootDir->GetParent(getter_AddRefs(localDir));
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("TorBrowser-Data"
-                                     XPCOM_FILE_PATH_SEPARATOR "UpdateInfo"));
-#else
-  // For Tor Browser, we cannot store update history, etc. under the user's home directory.
-  // Instead, we place it under Tor Browser.app/TorBrowser/UpdateInfo/
-  nsCOMPtr<nsIFile> localDir;
-  rv = GetAppRootDir(getter_AddRefs(localDir));
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = localDir->AppendNative(NS_LITERAL_CSTRING("TorBrowser"));
+  int32_t dotIndex = appDirPath.RFind(".app");
+  if (dotIndex == kNotFound) {
+    dotIndex = appDirPath.Length();
+  }
+  appDirPath = Substring(appDirPath, 1, dotIndex - 1);
+  rv = updRoot->AppendRelativePath(appDirPath);
   NS_ENSURE_SUCCESS(rv, rv);
-  rv = localDir->AppendNative(NS_LITERAL_CSTRING("UpdateInfo"));
 #endif
+#else // ! TOR_BROWSER_UPDATE
+  nsCOMPtr<nsIFile> appFile;
+  bool per = false;
+  nsresult rv = GetFile(XRE_EXECUTABLE_FILE, &per, getter_AddRefs(appFile));
   NS_ENSURE_SUCCESS(rv, rv);
-#else
+  rv = appFile->GetParent(getter_AddRefs(updRoot));
+  NS_ENSURE_SUCCESS(rv, rv);
+#ifdef XP_MACOSX
   nsCOMPtr<nsIFile> appRootDirFile;
   nsCOMPtr<nsIFile> localDir;
   nsAutoString appDirPath;
@@ -1087,7 +1097,6 @@ nsXREDirProvider::GetUpdateRootDir(nsIFile* *aResult)
       NS_FAILED(localDir->AppendRelativePath(appDirPath))) {
     return NS_ERROR_FAILURE;
   }
-#endif
 
   NS_ADDREF(*aResult = localDir);
   return NS_OK;
@@ -1182,7 +1191,7 @@ nsXREDirProvider::GetUpdateRootDir(nsIFile* *aResult)
   NS_ENSURE_SUCCESS(rv, rv);
 
 #endif // XP_WIN
-#endif
+#endif // ! TOR_BROWSER_UPDATE
   NS_ADDREF(*aResult = updRoot);
   return NS_OK;
 }
@@ -1235,20 +1244,13 @@ nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile, bool aLocal)
   // Copied from nsAppFileLocationProvider (more or less)
   NS_ENSURE_ARG_POINTER(aFile);
   nsCOMPtr<nsIFile> localDir;
+  nsresult rv = GetTorBrowserUserDataDir(getter_AddRefs(localDir));
+  NS_ENSURE_SUCCESS(rv, rv);
 
 #ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR
-  nsCOMPtr<nsIFile> appRootDir;
-  nsresult rv = GetAppRootDir(getter_AddRefs(appRootDir));
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = appRootDir->GetParent(getter_AddRefs(localDir));
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("TorBrowser-Data"
-                                     XPCOM_FILE_PATH_SEPARATOR "Browser"));
+  rv = localDir->AppendNative(NS_LITERAL_CSTRING("Browser"));
 #else
-  nsresult rv = GetAppRootDir(getter_AddRefs(localDir));
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("TorBrowser"
-                                     XPCOM_FILE_PATH_SEPARATOR "Data"
+  rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("Data"
                                      XPCOM_FILE_PATH_SEPARATOR "Browser"));
 #endif
   NS_ENSURE_SUCCESS(rv, rv);
@@ -1354,43 +1356,17 @@ nsXREDirProvider::GetUserDataDirectory(nsIFile** aFile, bool aLocal,
 }
 
 nsresult
-nsXREDirProvider::GetAppRootDir(nsIFile* *aFile)
+nsXREDirProvider::GetTorBrowserUserDataDir(nsIFile* *aFile)
 {
   NS_ENSURE_ARG_POINTER(aFile);
-  nsCOMPtr<nsIFile> appRootDir;
 
-  nsresult rv = GetAppDir()->Clone(getter_AddRefs(appRootDir));
+  nsCOMPtr<nsIFile> exeFile;
+  bool per = false;
+  nsresult rv = GetFile(XRE_EXECUTABLE_FILE, &per, getter_AddRefs(exeFile));
   NS_ENSURE_SUCCESS(rv, rv);
-
-  int levelsToRemove = 1; // In FF21+, appDir points to browser subdirectory.
-#if defined(XP_MACOSX)
-  levelsToRemove += 2;
-#endif
-  while (appRootDir && (levelsToRemove > 0)) {
-    // When crawling up the hierarchy, components named "." do not count.
-    nsAutoCString removedName;
-    rv = appRootDir->GetNativeLeafName(removedName);
-    NS_ENSURE_SUCCESS(rv, rv);
-    bool didRemove = !removedName.Equals(".");
-
-    // Remove a directory component.
-    nsCOMPtr<nsIFile> parentDir;
-    rv = appRootDir->GetParent(getter_AddRefs(parentDir));
-    NS_ENSURE_SUCCESS(rv, rv);
-    appRootDir = parentDir;
-
-    if (didRemove)
-      --levelsToRemove;
-  }
-
-  if (!appRootDir)
-    return NS_ERROR_FAILURE;
-
-  NS_ADDREF(*aFile = appRootDir);
-  return NS_OK;
+  return TorBrowser_GetUserDataDir(exeFile, aFile);
 }
 
-
 nsresult
 nsXREDirProvider::EnsureDirectoryExists(nsIFile* aDirectory)
 {
diff --git a/toolkit/xre/nsXREDirProvider.h b/toolkit/xre/nsXREDirProvider.h
index be9a11c..4eb2d87 100644
--- a/toolkit/xre/nsXREDirProvider.h
+++ b/toolkit/xre/nsXREDirProvider.h
@@ -100,6 +100,12 @@ public:
    */
   nsresult GetProfileDir(nsIFile* *aResult);
 
+  /**
+   * Get the TorBrowser user data directory by calling the
+   * TorBrowser_GetUserDataDir() utility function.
+   */
+  nsresult GetTorBrowserUserDataDir(nsIFile* *aFile);
+
 protected:
   nsresult GetFilesInternal(const char* aProperty, nsISimpleEnumerator** aResult);
   nsresult GetUserDataDirectoryHome(nsIFile* *aFile, bool aLocal);
@@ -107,7 +113,6 @@ protected:
 #if defined(XP_UNIX) || defined(XP_MACOSX)
   static nsresult GetSystemExtensionsDirectory(nsIFile** aFile);
 #endif
-  nsresult GetAppRootDir(nsIFile* *aFile);
   static nsresult EnsureDirectoryExists(nsIFile* aDirectory);
   void EnsureProfileFileExists(nsIFile* aFile);
 
diff --git a/xpcom/io/TorFileUtils.cpp b/xpcom/io/TorFileUtils.cpp
new file mode 100644
index 0000000..7e42071
--- /dev/null
+++ b/xpcom/io/TorFileUtils.cpp
@@ -0,0 +1,130 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "TorFileUtils.h"
+
+static nsresult GetAppRootDir(nsIFile *aExeFile, nsIFile** aFile);
+
+//-----------------------------------------------------------------------------
+NS_METHOD
+TorBrowser_GetUserDataDir(nsIFile *aExeFile, nsIFile** aFile)
+{
+  NS_ENSURE_ARG_POINTER(aFile);
+  nsCOMPtr<nsIFile> tbDataDir;
+
+#ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR
+  nsAutoCString tbDataLeafName(NS_LITERAL_CSTRING("TorBrowser-Data"));
+  nsCOMPtr<nsIFile> appRootDir;
+  nsresult rv = GetAppRootDir(aExeFile, getter_AddRefs(appRootDir));
+  NS_ENSURE_SUCCESS(rv, rv);
+#ifndef XP_MACOSX
+  // On all platforms except Mac OS, we always operate in a "portable" mode
+  // where the TorBrowser-Data directory is located next to the application.
+  rv = appRootDir->GetParent(getter_AddRefs(tbDataDir));
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = tbDataDir->AppendNative(tbDataLeafName);
+  NS_ENSURE_SUCCESS(rv, rv);
+#else
+  // For Mac OS, determine whether we should store user data in the OS's
+  // standard location (i.e., under ~/Library/Application Support). We use
+  // the OS location if (1) the application is installed in a directory whose
+  // path contains "/Applications" or (2) the TorBrowser-Data directory does
+  // not exist and cannot be created (which probably means we lack write
+  // permission to the directory that contains the application).
+  nsAutoString appRootPath;
+  rv = appRootDir->GetPath(appRootPath);
+  NS_ENSURE_SUCCESS(rv, rv);
+  bool useOSLocation = (appRootPath.Find("/Applications",
+                                         true /* ignore case */) >= 0);
+  if (!useOSLocation) {
+    // We hope to use the portable (aka side-by-side) approach, but before we
+    // commit to that, let's ensure that we can create the TorBrowser-Data
+    // directory. If it already exists, we will try to use it; if not and we
+    // fail to create it, we will switch to ~/Library/Application Support.
+    rv = appRootDir->GetParent(getter_AddRefs(tbDataDir));
+    NS_ENSURE_SUCCESS(rv, rv);
+    rv = tbDataDir->AppendNative(tbDataLeafName);
+    NS_ENSURE_SUCCESS(rv, rv);
+    bool exists = false;
+    rv = tbDataDir->Exists(&exists);
+    if (NS_SUCCEEDED(rv) && !exists)
+      rv = tbDataDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
+    useOSLocation = NS_FAILED(rv);
+  }
+
+  if (useOSLocation) {
+    // We are using ~/Library/Application Support/TorBrowser-Data. We do not
+    // need to create that directory here because the code in nsXREDirProvider
+    // will do so (and the user should always have write permission for
+    // ~/Library/Application Support; if they do not we have no more options).
+    FSRef fsRef;
+    OSErr err = ::FSFindFolder(kUserDomain, kApplicationSupportFolderType,
+                               kCreateFolder, &fsRef);
+    NS_ENSURE_FALSE(err, NS_ERROR_FAILURE);
+    // To convert the FSRef returned by FSFindFolder() into an nsIFile that
+    // points to ~/Library/Application Support, we first create an empty
+    // nsIFile object (no path) and then use InitWithFSRef() to set the
+    // path.
+    nsresult rv = NS_NewNativeLocalFile(EmptyCString(), true,
+                                        getter_AddRefs(tbDataDir));
+    NS_ENSURE_SUCCESS(rv, rv);
+    nsCOMPtr<nsILocalFileMac> dirFileMac = do_QueryInterface(tbDataDir);
+    if (!dirFileMac)
+      return NS_ERROR_UNEXPECTED;
+    rv = dirFileMac->InitWithFSRef(&fsRef);
+    NS_ENSURE_SUCCESS(rv, rv);
+    rv = tbDataDir->AppendNative(tbDataLeafName);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+#endif
+
+#else
+  // User data is embedded within the application directory (i.e.,
+  // TOR_BROWSER_DATA_OUTSIDE_APP_DIR is not defined).
+  nsresult rv = GetAppRootDir(aExeFile, getter_AddRefs(tbDataDir));
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = tbDataDir->AppendNative(NS_LITERAL_CSTRING("TorBrowser"));
+  NS_ENSURE_SUCCESS(rv, rv);
+#endif
+
+  NS_ADDREF(*aFile = tbDataDir);
+  return NS_OK;
+}
+
+static nsresult
+GetAppRootDir(nsIFile *aExeFile, nsIFile** aFile)
+{
+  NS_ENSURE_ARG_POINTER(aExeFile);
+  NS_ENSURE_ARG_POINTER(aFile);
+  nsCOMPtr<nsIFile> appRootDir = aExeFile;
+
+  int levelsToRemove = 1; // Remove firefox (the executable file).
+#if defined(XP_MACOSX)
+  levelsToRemove += 2;   // On Mac OS, we must also remove Contents/MacOS.
+#endif
+  while (appRootDir && (levelsToRemove > 0)) {
+    // When crawling up the hierarchy, components named "." do not count.
+    nsAutoCString removedName;
+    nsresult rv = appRootDir->GetNativeLeafName(removedName);
+    NS_ENSURE_SUCCESS(rv, rv);
+    bool didRemove = !removedName.Equals(".");
+
+    // Remove a directory component.
+    nsCOMPtr<nsIFile> parentDir;
+    rv = appRootDir->GetParent(getter_AddRefs(parentDir));
+    NS_ENSURE_SUCCESS(rv, rv);
+    appRootDir = parentDir;
+
+    if (didRemove)
+      --levelsToRemove;
+  }
+
+  if (!appRootDir)
+    return NS_ERROR_FAILURE;
+
+  NS_ADDREF(*aFile = appRootDir);
+  return NS_OK;
+}
diff --git a/xpcom/io/TorFileUtils.h b/xpcom/io/TorFileUtils.h
new file mode 100644
index 0000000..293ed04
--- /dev/null
+++ b/xpcom/io/TorFileUtils.h
@@ -0,0 +1,35 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef TorFileUtils_h__
+#define TorFileUtils_h__
+
+#include "nsIFile.h"
+
+class nsIFile;
+
+/**
+ * TorBrowser_GetUserDataDir
+ *
+ * Retrieve the Tor Browser user data directory.
+ * When built with --enable-tor-browser-data-outside-app-dir, the directory
+ * is next to the application directory, except on Mac OS where it may be
+ * there or it may be at ~/Library/Application Support/TorBrowser-Data (the
+ * latter location is used if the .app bundle is in a directory whose path
+ * contains /Applications or if we lack write access to the directory that
+ * contains the .app).
+ * When built without --enable-tor-browser-data-outside-app-dir, this
+ * directory is TorBrowser.app/TorBrowser.
+ *
+ * @param aExeFile  The firefox executable.
+ * @param aFile     Out parameter that is set to the Tor Browser user data
+ *                  directory.
+ * @return NS_OK on success.  Error otherwise.
+ */
+extern NS_METHOD
+TorBrowser_GetUserDataDir(nsIFile *aExeFile, nsIFile** aFile);
+
+#endif // !TorFileUtils_h__
diff --git a/xpcom/io/moz.build b/xpcom/io/moz.build
index 6e1936f..00a061b 100644
--- a/xpcom/io/moz.build
+++ b/xpcom/io/moz.build
@@ -80,6 +80,7 @@ EXPORTS += [
     'nsUnicharInputStream.h',
     'nsWildCard.h',
     'SpecialSystemDirectory.h',
+    'TorFileUtils.h',
 ]
 
 EXPORTS.mozilla += [
@@ -116,6 +117,7 @@ UNIFIED_SOURCES += [
     'SnappyFrameUtils.cpp',
     'SnappyUncompressInputStream.cpp',
     'SpecialSystemDirectory.cpp',
+    'TorFileUtils.cpp',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
diff --git a/xpcom/io/nsAppFileLocationProvider.cpp b/xpcom/io/nsAppFileLocationProvider.cpp
index 4948dbe..022dfd8 100644
--- a/xpcom/io/nsAppFileLocationProvider.cpp
+++ b/xpcom/io/nsAppFileLocationProvider.cpp
@@ -28,6 +28,7 @@
 #include <sys/param.h>
 #endif
 
+#include "TorFileUtils.h"
 
 // WARNING: These hard coded names need to go away. They need to
 // come from localizable resources
@@ -282,7 +283,8 @@ nsAppFileLocationProvider::CloneMozBinDirectory(nsIFile** aLocalFile)
 //
 #ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR
 // UNIX and WIN   : <App Folder>/../TorBrowser-Data/Browser
-// Mac            : <App Folder>/../../../TorBrowser-Data/Browser
+// Mac            : <App Folder>/../../../TorBrowser-Data/Browser OR
+//                  ~/Library/Application Support/TorBrowser-Data/Browser
 #else
 // UNIX and WIN   : <App Folder>/TorBrowser/Data/Browser
 // Mac            : <App Folder>/../../TorBrowser/Data/Browser
@@ -296,49 +298,23 @@ nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile,
     return NS_ERROR_INVALID_ARG;
   }
 
-  nsresult rv;
+  nsresult rv = NS_ERROR_UNEXPECTED;
   bool exists;
-  nsCOMPtr<nsIFile> localDir;
+  nsCOMPtr<nsIFile> localDir, exeFile;
 
-  rv = CloneMozBinDirectory(getter_AddRefs(localDir));
+  nsCOMPtr<nsIProperties> directoryService(
+                         do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv));
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = directoryService->Get(XRE_EXECUTABLE_FILE, NS_GET_IID(nsIFile),
+                             getter_AddRefs(exeFile));
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = TorBrowser_GetUserDataDir(exeFile, getter_AddRefs(localDir));
   NS_ENSURE_SUCCESS(rv, rv);
 
 #ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR
-  int levelsToRemove = 2; // In FF21+, bin dir points to browser subdirectory.
-#else
-  int levelsToRemove = 1; // In FF21+, bin dir points to browser subdirectory.
-#endif
-#if defined(XP_MACOSX)
-  levelsToRemove += 2;
-#endif
-  while (localDir && (levelsToRemove > 0)) {
-    // When crawling up the hierarchy, components named "." do not count.
-    nsAutoCString removedName;
-    rv = localDir->GetNativeLeafName(removedName);
-    NS_ENSURE_SUCCESS(rv, rv);
-    bool didRemove = !removedName.Equals(".");
-
-    // Remove a directory component.
-    nsCOMPtr<nsIFile> parentDir;
-    rv = localDir->GetParent(getter_AddRefs(parentDir));
-    NS_ENSURE_SUCCESS(rv, rv);
-    localDir = parentDir;
-
-    if (didRemove) {
-      --levelsToRemove;
-    }
-  }
-
-  if (!localDir) {
-    return NS_ERROR_FAILURE;
-  }
-
-#ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR
-  rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("TorBrowser-Data"
-                                        XPCOM_FILE_PATH_SEPARATOR "Browser"));
+  rv = localDir->AppendNative(NS_LITERAL_CSTRING("Browser"));
 #else
-  rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("TorBrowser"
-                                        XPCOM_FILE_PATH_SEPARATOR "Data"
+  rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("Data"
                                         XPCOM_FILE_PATH_SEPARATOR "Browser"));
 #endif
   NS_ENSURE_SUCCESS(rv, rv);



More information about the tor-commits mailing list