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/2bbd224...
tbb-commits@lists.torproject.org