Bug 1785278 - Reading AutoConfig from /etc/firefox when running under Snap r=mkaply,xpcom-reviewers,barret

Differential Revision: https://phabricator.services.mozilla.com/D159059
This commit is contained in:
Alexandre Lissy 2022-10-18 21:06:43 +00:00
parent 520c17080c
commit f955bb9c1e
16 changed files with 220 additions and 9 deletions

View File

@ -6,6 +6,6 @@
DIRS += ["src"]
XPCSHELL_TESTS_MANIFESTS += ["test/unit/xpcshell.ini"]
XPCSHELL_TESTS_MANIFESTS += ["test/unit/xpcshell.ini", "test/unit/xpcshell_snap.ini"]
MARIONETTE_UNIT_MANIFESTS += ["test/marionette/manifest.ini"]

View File

@ -26,6 +26,10 @@
#include "nspr.h"
#include "nsXULAppAPI.h"
#if defined(MOZ_WIDGET_GTK)
# include "mozilla/WidgetUtilsGtk.h"
#endif // defined(MOZ_WIDGET_GTK)
using namespace mozilla;
extern bool sandboxEnabled;
@ -243,7 +247,16 @@ nsresult nsReadConfig::openAndEvaluateJSFile(const char* aFileName,
nsCOMPtr<nsIInputStream> inStr;
if (isBinDir) {
nsCOMPtr<nsIFile> jsFile;
rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(jsFile));
#if defined(MOZ_WIDGET_GTK)
if (!mozilla::widget::IsRunningUnderFlatpakOrSnap()) {
#endif // defined(MOZ_WIDGET_GTK)
rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(jsFile));
#if defined(MOZ_WIDGET_GTK)
} else {
rv = NS_GetSpecialDirectory(NS_OS_SYSTEM_CONFIG_DIR,
getter_AddRefs(jsFile));
}
#endif // defined(MOZ_WIDGET_GTK)
if (NS_FAILED(rv)) return rv;
rv = jsFile->AppendNative(nsDependentCString(aFileName));

View File

@ -0,0 +1,4 @@
// # don't remove this comment! (the first line is ignored by Mozilla)
// Verify this one has a user value
pref("_autoconfig_.test.userpref-snap", "userpref-snap");

View File

@ -0,0 +1,5 @@
/* global pref */
pref("general.config.sandbox_enabled", true);
pref("general.config.filename", "autoconfig-snap.cfg");
pref("general.config.vendor", "autoconfig-snap");
pref("general.config.obscure_value", 0);

View File

@ -0,0 +1,23 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
const { updateAppInfo } = ChromeUtils.import(
"resource://testing-common/AppInfo.jsm"
);
function run_test() {
let env = Cc["@mozilla.org/process/environment;1"].getService(
Ci.nsIEnvironment
);
let testDirName = do_get_cwd().clone();
env.set("MOZ_SYSTEM_CONFIG_DIR", testDirName.path);
updateAppInfo();
let customSysConfD = Services.dirsvc.get("SysConfD", Ci.nsIFile);
let parent = customSysConfD.parent;
let child = customSysConfD.leafName;
notEqual("/etc", parent.path, "SysConfD is not in /etc");
equal("xpcshell", child, "SysConfD is xpcshell");
}

View File

@ -0,0 +1,13 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
const { updateAppInfo } = ChromeUtils.import(
"resource://testing-common/AppInfo.jsm"
);
function run_test() {
updateAppInfo();
let defaultSysConfD = Services.dirsvc.get("SysConfD", Ci.nsIFile);
equal("/etc/xpcshell", defaultSysConfD.path, "SysConfD is in /etc");
}

View File

@ -0,0 +1,80 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/* eslint no-unsafe-finally: "off"*/
/* Turning off this rule to allow control flow operations in finally block
* http://eslint.org/docs/rules/no-unsafe-finally */
const { updateAppInfo } = ChromeUtils.import(
"resource://testing-common/AppInfo.jsm"
);
function ensureRemove(file) {
try {
file.remove(false);
} catch (e) {
if (e.result != Cr.NS_ERROR_FILE_NOT_FOUND) {
throw e;
}
}
}
async function run_test() {
let env = Cc["@mozilla.org/process/environment;1"].getService(
Ci.nsIEnvironment
);
let prefs = Services.prefs.getBranch(null);
let testDir = do_get_cwd();
let confDir = testDir.clone();
confDir.append("MozSystemConfigDir");
env.set("MOZ_SYSTEM_CONFIG_DIR", confDir.path);
env.set("SNAP_INSTANCE_NAME", "xpcshell");
updateAppInfo();
let sysConfD = Services.dirsvc.get("SysConfD", Ci.nsIFile);
let defaultPrefDExtra = sysConfD.clone();
defaultPrefDExtra.append("defaults");
defaultPrefDExtra.append("pref");
await IOUtils.makeDirectory(defaultPrefDExtra.path);
const kAutoConfigFile = defaultPrefDExtra.clone();
kAutoConfigFile.append("autoconfig_snap.js");
const kAutoConfigCfg = sysConfD.clone();
kAutoConfigCfg.append("autoconfig-snap.cfg");
let autoConfigJS = testDir.clone();
autoConfigJS.append(kAutoConfigFile.leafName);
let autoConfigCfg = testDir.clone();
autoConfigCfg.append(kAutoConfigCfg.leafName);
try {
autoConfigJS.copyTo(kAutoConfigFile.parent, kAutoConfigFile.leafName);
autoConfigCfg.copyTo(kAutoConfigCfg.parent, kAutoConfigCfg.leafName);
// Make sure nsReadConfig is initialized.
Cc["@mozilla.org/readconfig;1"].getService(Ci.nsISupports);
Services.prefs.resetPrefs();
Services.obs.notifyObservers(
Services.prefs,
"prefservice:before-read-userprefs"
);
ok(prefs.prefHasUserValue("_autoconfig_.test.userpref-snap"));
equal(
"userpref-snap",
prefs.getStringPref("_autoconfig_.test.userpref-snap")
);
Services.prefs.resetPrefs();
} finally {
ensureRemove(kAutoConfigFile);
ensureRemove(kAutoConfigCfg);
Services.prefs.resetPrefs();
}
}

View File

@ -15,3 +15,7 @@ support-files =
run-sequentially = very high failure rate in parallel
[test_autoconfig_no_sandbox.js]
run-sequentially = very high failure rate in parallel
[test_autoconfig_default_path.js]
run-if = os == 'linux'
[test_autoconfig_custom_path.js]
run-if = os == 'linux'

View File

@ -0,0 +1,8 @@
[DEFAULT]
head =
skip-if = os != 'linux'
[test_autoconfig_snap.js]
support-files =
autoconfig_snap.js
autoconfig-snap.cfg

View File

@ -107,6 +107,10 @@
# include "windows.h"
#endif
#if defined(MOZ_WIDGET_GTK)
# include "mozilla/WidgetUtilsGtk.h"
#endif // defined(MOZ_WIDGET_GTK)
using namespace mozilla;
using ipc::FileDescriptor;
@ -4860,6 +4864,23 @@ nsresult Preferences::InitInitialObjects(bool aIsStartup) {
NS_WARNING("Error parsing application default preferences.");
}
#if defined(MOZ_WIDGET_GTK)
// Under Flatpak/Snap package, load /etc/firefox/defaults/pref/*.js.
if (mozilla::widget::IsRunningUnderFlatpakOrSnap()) {
nsCOMPtr<nsIFile> defaultSnapPrefDir;
rv = NS_GetSpecialDirectory(NS_OS_SYSTEM_CONFIG_DIR,
getter_AddRefs(defaultSnapPrefDir));
NS_ENSURE_SUCCESS(rv, rv);
defaultSnapPrefDir->AppendNative("defaults"_ns);
defaultSnapPrefDir->AppendNative("pref"_ns);
rv = pref_LoadPrefsInDir(defaultSnapPrefDir, nullptr, 0);
if (NS_FAILED(rv)) {
NS_WARNING("Error parsing application default preferences under Snap.");
}
}
#endif
// Load jar:$app/omni.jar!/defaults/preferences/*.js
// or jar:$gre/omni.jar!/defaults/preferences/*.js.
RefPtr<nsZipArchive> appJarReader = Omnijar::GetReader(Omnijar::APP);

View File

@ -532,12 +532,8 @@ class JSONPoliciesProvider {
let configFile = null;
if (AppConstants.platform == "linux" && AppConstants.MOZ_SYSTEM_POLICIES) {
let systemConfigFile = Cc["@mozilla.org/file/local;1"].createInstance(
Ci.nsIFile
);
systemConfigFile.initWithPath(
"/etc/" + Services.appinfo.name.toLowerCase() + "/policies"
);
let systemConfigFile = Services.dirsvc.get("SysConfD", Ci.nsIFile);
systemConfigFile.append("policies");
systemConfigFile.append(POLICIES_FILENAME);
if (systemConfigFile.exists()) {
return systemConfigFile;

View File

@ -2447,6 +2447,7 @@ STATIC_ATOMS = [
Atom("DirectoryService_OS_TemporaryDirectory", "TmpD"),
Atom("DirectoryService_OS_CurrentProcessDirectory", "CurProcD"),
Atom("DirectoryService_OS_CurrentWorkingDirectory", "CurWorkD"),
Atom("DirectoryService_OS_SystemConfigDir", "SysConfD"),
# Atom("DirectoryService_OS_HomeDirectory", "Home"), # "Home" is present above
Atom("DirectoryService_OS_DesktopDirectory", "Desk"),
Atom("DirectoryService_InitCurrentProcess_dummy", "MozBinD"),

View File

@ -7,6 +7,7 @@
#include "SpecialSystemDirectory.h"
#include "nsString.h"
#include "nsDependentString.h"
#include "nsIXULAppInfo.h"
#if defined(XP_WIN)
@ -185,6 +186,37 @@ static nsresult GetUnixHomeDir(nsIFile** aFile) {
# endif
}
static nsresult GetUnixSystemConfigDir(nsIFile** aFile) {
# if defined(ANDROID)
return NS_ERROR_FAILURE;
# else
nsCOMPtr<nsIXULAppInfo> appInfo =
do_GetService("@mozilla.org/xre/app-info;1");
if (!appInfo) {
MOZ_CRASH("No appInfo");
}
nsAutoCString appName;
nsresult rv = appInfo->GetName(appName);
NS_ENSURE_SUCCESS(rv, rv);
ToLowerCase(appName);
const char* mozSystemConfigDir = PR_GetEnv("MOZ_SYSTEM_CONFIG_DIR");
const char* defaultSystemConfigDir = "/etc";
nsDependentCString sysConfigDir = nsDependentCString(
mozSystemConfigDir ? mozSystemConfigDir : defaultSystemConfigDir);
rv = NS_NewNativeLocalFile(sysConfigDir, true, aFile);
NS_ENSURE_SUCCESS(rv, rv);
(*aFile)->AppendNative(appName);
NS_ENSURE_SUCCESS(rv, rv);
return rv;
# endif
}
/*
The following license applies to the xdg_user_dir_lookup function:
@ -634,6 +666,9 @@ nsresult GetSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory,
case Unix_XDG_Desktop:
case Unix_XDG_Download:
return GetUnixXDGUserDirectory(aSystemSystemDirectory, aFile);
case Unix_SystemConfigDirectory:
return GetUnixSystemConfigDir(aFile);
#endif
default:

View File

@ -50,7 +50,8 @@ enum SystemDirectories {
Unix_HomeDirectory = 303,
Unix_XDG_Desktop = 304,
Unix_XDG_Download = 306
Unix_XDG_Download = 306,
Unix_SystemConfigDirectory = 307
};
nsresult GetSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory,

View File

@ -442,6 +442,9 @@ nsDirectoryService::GetFile(const char* aProp, bool* aPersistent,
rv =
GetSpecialSystemDirectory(Unix_XDG_Download, getter_AddRefs(localFile));
*aPersistent = false;
} else if (inAtom == nsGkAtoms::DirectoryService_OS_SystemConfigDir) {
rv = GetSpecialSystemDirectory(Unix_SystemConfigDirectory,
getter_AddRefs(localFile));
}
#endif

View File

@ -93,4 +93,8 @@
# define NS_UNIX_HOME_DIR NS_OS_HOME_DIR
#endif
#if defined(MOZ_WIDGET_GTK)
# define NS_OS_SYSTEM_CONFIG_DIR "SysConfD"
#endif // defined(MOZ_WIDGET_GTK)
#endif