[tbb-commits] [Git][tpo/applications/tor-browser][base-browser-102.7.0esr-12.5-1] 2 commits: Revert "Bug 9173: Change the default Firefox profile directory to be relative."

Pier Angelo Vendrame (@pierov) git at gitlab.torproject.org
Wed Feb 8 11:21:16 UTC 2023



Pier Angelo Vendrame pushed to branch base-browser-102.7.0esr-12.5-1 at The Tor Project / Applications / Tor Browser


Commits:
d41058d1 by Pier Angelo Vendrame at 2023-02-08T12:20:09+01:00
Revert "Bug 9173: Change the default Firefox profile directory to be relative."

This reverts commit 0ef716110c63ffa26a2c9b29cd954f2c971b5178.

- - - - -
9357ba91 by Pier Angelo Vendrame at 2023-02-08T12:20:18+01:00
Bug 9173: Change the default Firefox profile directory to be relative.

This commit makes Firefox look for the default profile directory in a
directory relative to the binary path.
The directory can be specified through the --with-relative-data-dir.
This is relative to the same directory as the firefox main binary for
Linux and Windows.

On macOS, we remove Contents/MacOS from it.
Or, in other words, the directory is relative to the application
bundle.

This behavior can be overriden at runtime, by placing a file called
system-install adjacent to the firefox main binary (also on macOS).

- - - - -


3 changed files:

- toolkit/xre/nsXREDirProvider.cpp
- toolkit/xre/nsXREDirProvider.h
- xpcom/io/nsAppFileLocationProvider.cpp


Changes:

=====================================
toolkit/xre/nsXREDirProvider.cpp
=====================================
@@ -111,6 +111,10 @@ nsIFile* gDataDirHome = nullptr;
 nsCOMPtr<nsIFile> gDataDirProfileLocal = nullptr;
 nsCOMPtr<nsIFile> gDataDirProfile = nullptr;
 
+#if defined(RELATIVE_DATA_DIR)
+mozilla::Maybe<nsCOMPtr<nsIFile>> gDataDirPortable;
+#endif
+
 // These are required to allow nsXREDirProvider to be usable in xpcshell tests.
 // where gAppData is null.
 #if defined(XP_MACOSX) || defined(XP_UNIX)
@@ -1324,6 +1328,91 @@ nsresult nsXREDirProvider::SetUserDataProfileDirectory(nsCOMPtr<nsIFile>& aFile,
   return NS_OK;
 }
 
+#if defined(RELATIVE_DATA_DIR)
+nsresult nsXREDirProvider::GetPortableDataDir(nsIFile** aFile,
+                                              bool& aIsPortable) {
+  if (gDataDirPortable) {
+    if (*gDataDirPortable) {
+      nsresult rv = (*gDataDirPortable)->Clone(aFile);
+      NS_ENSURE_SUCCESS(rv, rv);
+      aIsPortable = true;
+    } else {
+      aIsPortable = false;
+    }
+    return NS_OK;
+  }
+
+  nsCOMPtr<nsIFile> exeFile, exeDir;
+  bool persistent = false;
+  nsresult rv =
+      GetFile(XRE_EXECUTABLE_FILE, &persistent, getter_AddRefs(exeFile));
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = exeFile->Normalize();
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = exeFile->GetParent(getter_AddRefs(exeDir));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+#if defined(XP_MACOSX)
+  nsAutoString exeDirPath;
+  rv = exeDir->GetPath(exeDirPath);
+  NS_ENSURE_SUCCESS(rv, rv);
+  // When the browser is installed in /Applications, we never run in portable
+  // mode.
+  if (exeDirPath.Find("/Applications/", true /* ignore case */) == 0) {
+    aIsPortable = false;
+    return NS_OK;
+  }
+#endif
+
+  nsCOMPtr<nsIFile> systemInstallFile;
+  rv = exeDir->Clone(getter_AddRefs(systemInstallFile));
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = systemInstallFile->AppendNative("system-install"_ns);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  bool exists = false;
+  rv = systemInstallFile->Exists(&exists);
+  NS_ENSURE_SUCCESS(rv, rv);
+  if (exists) {
+    aIsPortable = false;
+    gDataDirPortable.emplace(nullptr);
+    return NS_OK;
+  }
+
+  nsCOMPtr<nsIFile> localDir = exeDir;
+#if defined(XP_MACOSX)
+  rv = exeDir->GetParent(getter_AddRefs(localDir));
+  NS_ENSURE_SUCCESS(rv, rv);
+  exeDir = localDir;
+  rv = exeDir->GetParent(getter_AddRefs(localDir));
+  NS_ENSURE_SUCCESS(rv, rv);
+#endif
+  rv = localDir->SetRelativePath(localDir.get(),
+                                 nsLiteralCString(RELATIVE_DATA_DIR));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+#if defined(XP_MACOSX)
+  // On macOS we try to create the directory immediately to switch to
+  // system-install mode if needed (e.g., when running from the DMG).
+  rv = localDir->Exists(&exists);
+  NS_ENSURE_SUCCESS(rv, rv);
+  if (!exists) {
+    rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
+    if (NS_FAILED(rv)) {
+      aIsPortable = false;
+      return NS_OK;
+    }
+  }
+#endif
+
+  gDataDirPortable.emplace(localDir);
+  rv = (*gDataDirPortable)->Clone(aFile);
+  NS_ENSURE_SUCCESS(rv, rv);
+  aIsPortable = true;
+  return rv;
+}
+#endif
+
 nsresult nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile,
                                                     bool aLocal) {
   // Copied from nsAppFileLocationProvider (more or less)
@@ -1343,16 +1432,20 @@ nsresult nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile,
   if (!singleton) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
-  rv = singleton->GetAppRootDir(getter_AddRefs(localDir));
-  NS_ENSURE_SUCCESS(rv, rv);
-  nsAutoCString profileDir(RELATIVE_DATA_DIR);
-  rv = localDir->SetRelativePath(localDir.get(), profileDir);
+  bool isPortable = false;
+  rv = singleton->GetPortableDataDir(getter_AddRefs(localDir), isPortable);
   NS_ENSURE_SUCCESS(rv, rv);
-  if (aLocal) {
-    rv = localDir->AppendNative("Caches"_ns);
-    NS_ENSURE_SUCCESS(rv, rv);
+  if (isPortable) {
+    if (aLocal) {
+      rv = localDir->AppendNative("Caches"_ns);
+      NS_ENSURE_SUCCESS(rv, rv);
+    }
+    NS_IF_ADDREF(*aFile = localDir);
+    return rv;
   }
-#elif defined(XP_MACOSX)
+#endif
+
+#if defined(XP_MACOSX)
   FSRef fsRef;
   OSType folderType;
   if (aLocal) {
@@ -1495,25 +1588,6 @@ nsresult nsXREDirProvider::GetUserDataDirectory(nsIFile** aFile, bool aLocal) {
   return NS_OK;
 }
 
-nsresult nsXREDirProvider::GetAppRootDir(nsIFile** aFile) {
-  bool persistent = false;
-  nsCOMPtr<nsIFile> file, appRootDir;
-  nsresult rv = GetFile(XRE_EXECUTABLE_FILE, &persistent, getter_AddRefs(file));
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = file->Normalize();
-  NS_ENSURE_SUCCESS(rv, rv);
-  int levelsToRemove = 1;
-#if defined(XP_MACOSX)
-  levelsToRemove += 2;
-#endif
-  while (levelsToRemove-- > 0) {
-    rv = file->GetParent(getter_AddRefs(appRootDir));
-    NS_ENSURE_SUCCESS(rv, rv);
-    file = appRootDir;
-  }
-  return appRootDir->Clone(aFile);
-}
-
 nsresult nsXREDirProvider::EnsureDirectoryExists(nsIFile* aDirectory) {
   nsresult rv = aDirectory->Create(nsIFile::DIRECTORY_TYPE, 0700);
 
@@ -1564,6 +1638,13 @@ nsresult nsXREDirProvider::AppendProfilePath(nsIFile* aFile, bool aLocal) {
     return NS_OK;
   }
 
+#if defined(RELATIVE_DATA_DIR)
+  if (gDataDirPortable && *gDataDirPortable) {
+    // Do nothing in portable mode
+    return NS_OK;
+  }
+#endif
+
   nsAutoCString profile;
   nsAutoCString appName;
   nsAutoCString vendor;
@@ -1579,27 +1660,23 @@ nsresult nsXREDirProvider::AppendProfilePath(nsIFile* aFile, bool aLocal) {
 #if defined(XP_MACOSX)
   if (!profile.IsEmpty()) {
     rv = AppendProfileString(aFile, profile.get());
-#  ifndef RELATIVE_DATA_DIR
   } else {
     // Note that MacOS ignores the vendor when creating the profile hierarchy -
     // all application preferences directories live alongside one another in
     // ~/Library/Application Support/
     rv = aFile->AppendNative(appName);
-#  endif
   }
   NS_ENSURE_SUCCESS(rv, rv);
 
 #elif defined(XP_WIN)
   if (!profile.IsEmpty()) {
     rv = AppendProfileString(aFile, profile.get());
-#  ifndef RELATIVE_DATA_DIR
   } else {
     if (!vendor.IsEmpty()) {
       rv = aFile->AppendNative(vendor);
       NS_ENSURE_SUCCESS(rv, rv);
     }
     rv = aFile->AppendNative(appName);
-#  endif
   }
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -1614,26 +1691,21 @@ nsresult nsXREDirProvider::AppendProfilePath(nsIFile* aFile, bool aLocal) {
   nsAutoCString folder;
   // Make it hidden (by starting with "."), except when local (the
   // profile is already under ~/.cache or XDG_CACHE_HOME).
-#  ifndef RELATIVE_DATA_DIR
   if (!aLocal) folder.Assign('.');
-#  endif
 
   if (!profile.IsEmpty()) {
     // Skip any leading path characters
     const char* profileStart = profile.get();
     while (*profileStart == '/' || *profileStart == '\\') profileStart++;
 
-#  ifndef RELATIVE_DATA_DIR
     // On the off chance that someone wanted their folder to be hidden don't
     // let it become ".."
     if (*profileStart == '.' && !aLocal) profileStart++;
-#  endif
 
     folder.Append(profileStart);
     ToLowerCase(folder);
 
     rv = AppendProfileString(aFile, folder.BeginReading());
-#  ifndef RELATIVE_DATA_DIR
   } else {
     if (!vendor.IsEmpty()) {
       folder.Append(vendor);
@@ -1652,7 +1724,6 @@ nsresult nsXREDirProvider::AppendProfilePath(nsIFile* aFile, bool aLocal) {
 
       rv = aFile->AppendNative(folder);
     }
-#  endif
   }
   NS_ENSURE_SUCCESS(rv, rv);
 


=====================================
toolkit/xre/nsXREDirProvider.h
=====================================
@@ -109,14 +109,6 @@ class nsXREDirProvider final : public nsIDirectoryServiceProvider2,
    */
   nsresult GetProfileDir(nsIFile** aResult);
 
-  /**
-   * Get the path to the base application directory.
-   *
-   * In almost all platforms it is the directory that contains the Firefox
-   * executable; on macOS we remove also Contents/MacOS from it.
-   */
-  nsresult GetAppRootDir(nsIFile** aFile);
-
  protected:
   nsresult GetFilesInternal(const char* aProperty,
                             nsISimpleEnumerator** aResult);
@@ -163,6 +155,14 @@ class nsXREDirProvider final : public nsIDirectoryServiceProvider2,
  private:
   static nsresult SetUserDataProfileDirectory(nsCOMPtr<nsIFile>& aFile,
                                               bool aLocal);
+
+#if defined(RELATIVE_DATA_DIR)
+  /**
+   * Get the path to the portable data dir, if the application is running in
+   * portable mode.
+   */
+  nsresult GetPortableDataDir(nsIFile** aFile, bool& aIsPortable);
+#endif
 };
 
 #endif


=====================================
xpcom/io/nsAppFileLocationProvider.cpp
=====================================
@@ -229,57 +229,130 @@ nsresult nsAppFileLocationProvider::CloneMozBinDirectory(nsIFile** aLocalFile) {
   return NS_OK;
 }
 
-//----------------------------------------------------------------------------------------
-// GetProductDirectory - Gets the directory which contains the application data
-// folder
-//
-// UNIX   : ~/.mozilla/
-// WIN    : <Application Data folder on user's machine>\Mozilla
-// Mac    : :Documents:Mozilla:
-//----------------------------------------------------------------------------------------
-nsresult nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile,
-                                                        bool aLocal) {
-  if (NS_WARN_IF(!aLocalFile)) {
-    return NS_ERROR_INVALID_ARG;
-  }
+#ifdef RELATIVE_DATA_DIR
+static nsresult SetupPortableMode(nsIFile** aDirectory, bool aLocal,
+                                  bool& aIsPortable) {
+  // This is almost the same as nsXREDirProvider::GetPortableDataDir.
+  // However, it seems that this is never called, at least during simple usage
+  // of the browser.
 
   nsresult rv = NS_ERROR_UNEXPECTED;
-  bool exists;
-  nsCOMPtr<nsIFile> localDir;
-
-#if defined(RELATIVE_DATA_DIR)
   nsCOMPtr<nsIProperties> directoryService(
       do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv));
   NS_ENSURE_SUCCESS(rv, rv);
-
-  bool persistent = false;
-  nsCOMPtr<nsIFile> file, appRootDir;
+  nsCOMPtr<nsIFile> exeFile, exeDir;
   rv = directoryService->Get(XRE_EXECUTABLE_FILE, NS_GET_IID(nsIFile),
-                             getter_AddRefs(file));
+                             getter_AddRefs(exeFile));
+  rv = exeFile->Normalize();
   NS_ENSURE_SUCCESS(rv, rv);
-  rv = file->Normalize();
+  rv = exeFile->GetParent(getter_AddRefs(exeDir));
   NS_ENSURE_SUCCESS(rv, rv);
-  int levelsToRemove = 1;
+
 #  if defined(XP_MACOSX)
-  levelsToRemove += 2;
+  nsAutoString exeDirPath;
+  rv = exeDir->GetPath(exeDirPath);
+  NS_ENSURE_SUCCESS(rv, rv);
+  // When the browser is installed in /Applications, we never run in portable
+  // mode.
+  if (exeDirPath.Find("/Applications/", true /* ignore case */) == 0) {
+    aIsPortable = false;
+    return NS_OK;
+  }
 #  endif
-  while (levelsToRemove-- > 0) {
-    rv = file->GetParent(getter_AddRefs(appRootDir));
-    NS_ENSURE_SUCCESS(rv, rv);
-    file = appRootDir;
+
+  nsCOMPtr<nsIFile> systemInstallFile;
+  rv = exeDir->Clone(getter_AddRefs(systemInstallFile));
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = systemInstallFile->AppendNative("system-install"_ns);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  bool exists = false;
+  rv = systemInstallFile->Exists(&exists);
+  NS_ENSURE_SUCCESS(rv, rv);
+  if (exists) {
+    aIsPortable = false;
+    return NS_OK;
   }
 
-  localDir = appRootDir;
-  nsAutoCString profileDir(RELATIVE_DATA_DIR);
-  rv = localDir->SetRelativePath(localDir.get(), profileDir);
+  nsCOMPtr<nsIFile> localDir = exeDir;
+#  if defined(XP_MACOSX)
+  rv = exeDir->GetParent(getter_AddRefs(localDir));
   NS_ENSURE_SUCCESS(rv, rv);
+  exeDir = localDir;
+  rv = exeDir->GetParent(getter_AddRefs(localDir));
+  NS_ENSURE_SUCCESS(rv, rv);
+#  endif
 
+  rv = localDir->SetRelativePath(localDir.get(),
+                                 nsLiteralCString(RELATIVE_DATA_DIR));
+  NS_ENSURE_SUCCESS(rv, rv);
   if (aLocal) {
     rv = localDir->AppendNative("Caches"_ns);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
-#elif defined(MOZ_WIDGET_COCOA)
+  rv = localDir->Exists(&exists);
+  NS_ENSURE_SUCCESS(rv, rv);
+  if (!exists) {
+    rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
+#  if defined(XP_MACOSX)
+    if (NS_FAILED(rv)) {
+      // On macOS, we forgive this failure to allow running from the DMG.
+      aIsPortable = false;
+      return NS_OK;
+    }
+#  else
+    NS_ENSURE_SUCCESS(rv, rv);
+#  endif
+  }
+
+  localDir.forget(aDirectory);
+  aIsPortable = true;
+  return rv;
+}
+#endif
+
+//----------------------------------------------------------------------------------------
+// GetProductDirectory - Gets the directory which contains the application data
+// folder
+//
+// If portable mode is enabled:
+//  - aLocal == false: $APP_ROOT/$RELATIVE_DATA_DIR
+//  - aLocal == true:  $APP_ROOT/$RELATIVE_DATA_DIR/Caches
+// where $APP_ROOT is:
+//  - the parent directory of the executable on Windows and Linux
+//  - the root of the app bundle on macOS
+//
+// Otherwise:
+//  - Windows:
+//    - aLocal == false: %APPDATA%/$MOZ_USER_DIR
+//    - aLocal == true: %LOCALAPPDATA%/$MOZ_USER_DIR
+//  - macOS:
+//    - aLocal == false: kDomainLibraryFolderType/$MOZ_USER_DIR
+//    - aLocal == true: kCachedDataFolderType/$MOZ_USER_DIR
+//  - Unix: ~/$MOZ_USER_DIR
+//----------------------------------------------------------------------------------------
+nsresult nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile,
+                                                        bool aLocal) {
+  if (NS_WARN_IF(!aLocalFile)) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  nsresult rv = NS_ERROR_UNEXPECTED;
+  bool exists;
+  nsCOMPtr<nsIFile> localDir;
+
+#if defined(RELATIVE_DATA_DIR)
+  bool isPortable = false;
+  rv = SetupPortableMode(aLocalFile, aLocal, isPortable);
+  // If portable mode is enabled, we absolutely want it (e.g., to be sure there
+  // will not be disk leaks), so a failure is to be propagated.
+  if (NS_FAILED(rv) || isPortable) {
+    return rv;
+  }
+#endif
+
+#if defined(MOZ_WIDGET_COCOA)
   FSRef fsRef;
   OSType folderType =
       aLocal ? (OSType)kCachedDataFolderType : (OSType)kDomainLibraryFolderType;
@@ -318,12 +391,10 @@ nsresult nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile,
 #  error dont_know_how_to_get_product_dir_on_your_platform
 #endif
 
-#if !defined(RELATIVE_DATA_DIR)
   rv = localDir->AppendRelativeNativePath(DEFAULT_PRODUCT_DIR);
   if (NS_FAILED(rv)) {
     return rv;
   }
-#endif
   rv = localDir->Exists(&exists);
 
   if (NS_SUCCEEDED(rv) && !exists) {
@@ -342,6 +413,11 @@ nsresult nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile,
 //----------------------------------------------------------------------------------------
 // GetDefaultUserProfileRoot - Gets the directory which contains each user
 // profile dir
+//
+// - Windows and macOS: $PRODUCT_DIRECTORY/Profiles
+// - Unix: $PRODUCT_DIRECTORY
+// See also GetProductDirectory for instructions on how $PRODUCT_DIRECTORY is
+// generated.
 //----------------------------------------------------------------------------------------
 nsresult nsAppFileLocationProvider::GetDefaultUserProfileRoot(
     nsIFile** aLocalFile, bool aLocal) {



View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/2bbd224029ba26cc75d7dfeff14cfa571434c1d8...9357ba9193471283ca1e15596b05c951c0871616

-- 
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/2bbd224029ba26cc75d7dfeff14cfa571434c1d8...9357ba9193471283ca1e15596b05c951c0871616
You're receiving this email because of your account on gitlab.torproject.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.torproject.org/pipermail/tbb-commits/attachments/20230208/705235e2/attachment-0001.htm>


More information about the tbb-commits mailing list