Commit b9710b75 authored by Pier Angelo Vendrame's avatar Pier Angelo Vendrame 🎃
Browse files

BB 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).
parent 6cad5c46
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -48,3 +48,5 @@ ac_add_options --disable-legacy-profile-creation
if test -z "$WASI_SYSROOT"; then
    ac_add_options --without-wasm-sandboxed-libraries
fi

ac_add_options --with-relative-data-dir=BaseBrowser/Data/Browser
+19 −0
Original line number Diff line number Diff line
@@ -945,6 +945,25 @@ with only_when(cross_compiling):
    )
    set_config("JS_BINARY", depends_if("JS_BINARY")(lambda value: value[0]))

option(
    "--with-relative-data-dir",
    nargs=1,
    help="Sets the data directories to be relative to the application directory",
)


@depends("--with-relative-data-dir", target)
@imports("json")
def relative_data_dir(value, target):
    if value and target.os == "Android":
        die("--with-relative-data-dir is not supported on Android")
    if value:
        return json.dumps(value[0])


set_define("RELATIVE_DATA_DIR", relative_data_dir)


option(
    "--with-base-browser-version",
    nargs=1,
+3 −0
Original line number Diff line number Diff line
@@ -10,3 +10,6 @@ ac_add_options --disable-update-agent

# Let's make sure no preference is enabling either Adobe's or Google's CDM.
ac_add_options --disable-eme

# For base-browser we do not enable portable mode on macOS.
ac_add_options --without-relative-data-dir
+47 −3
Original line number Diff line number Diff line
@@ -17,6 +17,9 @@
#include <string>
#include <type_traits>

// tor-browser#42163
#include <filesystem>

#define EXPAND_STRING_MACRO2(t) t
#define EXPAND_STRING_MACRO(t) EXPAND_STRING_MACRO2(t)

@@ -585,6 +588,45 @@ LauncherRegistryInfo::GetBrowserStartTimestamp() {

LauncherResult<std::wstring>
LauncherRegistryInfo::BuildDefaultBlocklistFilename() {
  // tor-browser#42163: Make the DLL blocklist obey portable mode
  {
    std::filesystem::path appDir;
    {
      mozilla::UniquePtr<wchar_t[]> appDirStr = GetFullBinaryPath();
      if (!appDirStr) {
        return LAUNCHER_ERROR_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
      }
      appDir = std::filesystem::path(appDirStr.get()).parent_path();
    }
    std::error_code ec;
    const bool isPortable =
        !std::filesystem::exists(appDir / L"system-install", ec);
    if (ec) {
      // exists is supposed not to set an error when a file does not exist
      // (whereas other functions such as is_regular_file sets it).
      // The standard is quite opaque about the meaning of the numeric codes.
      // Moreover, we use libcxx on Windows, and it seems they created a sort of
      // POSIX compatibility layer (e.g., for stat), see
      // libcxx/src/filesystem/posix_compat.h.
      // std::error_code has a message function, but all the various macro are
      // specific to handle Windows errors, so we have to use the generic error.
      // At least, at the moment the error is dropped eventually.
      return LAUNCHER_ERROR_GENERIC();
    }
    if (isPortable) {
      // RELATIVE_DATA_DIR must have forward slashes, but weakly_canonical
      // already changes them to backslashes.
      const std::filesystem::path blocklistPath =
          std::filesystem::weakly_canonical(
              appDir / L"" RELATIVE_DATA_DIR / L"blocklist", ec);
      if (ec) {
        return LAUNCHER_ERROR_GENERIC();
      }
      return blocklistPath.wstring();
    }
    // Normal installation, continue on Mozilla's path
  }

  // These flags are chosen to avoid I/O, see bug 1363398.
  const DWORD flags =
      KF_FLAG_SIMPLE_IDLIST | KF_FLAG_DONT_VERIFY | KF_FLAG_NO_ALIAS;
@@ -617,6 +659,8 @@ LauncherRegistryInfo::BuildDefaultBlocklistFilename() {
}

LauncherResult<std::wstring> LauncherRegistryInfo::GetBlocklistFileName() {
  // tor-browser#42163: Make the DLL blocklist obey portable mode
#ifndef BASE_BROWSER_VERSION
  LauncherResult<Disposition> disposition = Open();
  if (disposition.isErr()) {
    return disposition.propagateErr();
@@ -632,19 +676,19 @@ LauncherResult<std::wstring> LauncherRegistryInfo::GetBlocklistFileName() {
    UniquePtr<wchar_t[]> buf = readResult.unwrap();
    return std::wstring(buf.get());
  }

#endif
  LauncherResult<std::wstring> defaultBlocklistPath =
      BuildDefaultBlocklistFilename();
  if (defaultBlocklistPath.isErr()) {
    return defaultBlocklistPath.propagateErr();
  }

#ifndef BASE_BROWSER_VERSION
  LauncherVoidResult writeResult = WriteRegistryValueString(
      mRegKey, ResolveBlocklistValueName(), defaultBlocklistPath.inspect());
  if (writeResult.isErr()) {
    return writeResult.propagateErr();
  }

#endif
  return defaultBlocklistPath;
}

+9 −5
Original line number Diff line number Diff line
@@ -2758,6 +2758,8 @@ static nsresult ProfileMissingDialog(nsINativeAppSupport* aNative) {
#endif  // MOZ_WIDGET_ANDROID
}

// If aUnlocker is NULL, it is also OK for the following arguments to be NULL:
//   aProfileDir, aProfileLocalDir, aResult.
static ReturnAbortOnError ProfileLockedDialog(nsIFile* aProfileDir,
                                              nsIFile* aProfileLocalDir,
                                              nsIProfileUnlocker* aUnlocker,
@@ -2771,11 +2773,13 @@ static ReturnAbortOnError ProfileLockedDialog(nsIFile* aProfileDir,
  gStartupLock = nullptr;
#endif

  if (aProfileDir) {
    bool exists;
    aProfileDir->Exists(&exists);
    if (!exists) {
      return ProfileMissingDialog(aNative);
    }
  }

  ScopedXPCOMStartup xpcom;
  rv = xpcom.Initialize();
@@ -2784,7 +2788,7 @@ static ReturnAbortOnError ProfileLockedDialog(nsIFile* aProfileDir,
#if defined(MOZ_TELEMETRY_REPORTING)
  // We cannot check if telemetry has been disabled by the user, yet.
  // So, rely on the build time settings, instead.
  mozilla::Telemetry::WriteFailedProfileLock(aProfileDir);
  if (aProfileDir) mozilla::Telemetry::WriteFailedProfileLock(aProfileDir);
#endif

  rv = xpcom.SetWindowCreator(aNative);
Loading