Bug 1477254: Assert that varcache prefs match pref values at content process startup. r=njn

In order to avoid the overhead of doing a full pref lookup for every static
var cache at content process startup, we currently assume that the default
value of any static varcache pref will always match the default value of its
database entry (as long as the pref isn't locked). This lets us only perform
lookups for preferences which have a user value, or are locked.

If the default values of those preferences are changed in a bundled preference
file, though, the varcache value will be correct in the parent process, but
not in child processes. Since this is an easy mistake to make, we should
assert that it doesn't happen.

Note: This change only affects applications which use e10s. Applications like
Thunderbird can still override default values of any static pref with
impunity. Repacks and distributors can only do so by changing user values or
locking the preference after the change (which is the standard practice for
enterprise deployments).

MozReview-Commit-ID: JMHQBrp9HN

--HG--
extra : source : 1b389b00030ed38cdb3543aa5d1a67795be47565
extra : amend_source : 16f2dccf40664db9daa42a6edaabb933acbc6204
This commit is contained in:
Kris Maglione 2018-07-23 17:32:54 -07:00
Родитель dfd38a6ac3
Коммит 4ef55072b9
1 изменённых файлов: 54 добавлений и 3 удалений

Просмотреть файл

@ -1693,7 +1693,8 @@ static Result<Pref*, nsresult>
pref_LookupForModify(const char* aPrefName,
const std::function<bool(const PrefWrapper&)>& aCheckFn)
{
Maybe<PrefWrapper> wrapper = pref_Lookup(aPrefName, /* includeTypeNone */ true);
Maybe<PrefWrapper> wrapper =
pref_Lookup(aPrefName, /* includeTypeNone */ true);
if (wrapper.isNothing()) {
return Err(NS_ERROR_INVALID_ARG);
}
@ -1756,8 +1757,8 @@ pref_SetPref(const char* aPrefName,
bool valueChanged = false;
nsresult rv;
if (aKind == PrefValueKind::Default) {
rv = pref->SetDefaultValue(
aType, aValue, aIsSticky, aIsLocked, &valueChanged);
rv =
pref->SetDefaultValue(aType, aValue, aIsSticky, aIsLocked, &valueChanged);
} else {
MOZ_ASSERT(!aIsLocked); // `locked` is disallowed in user pref files
rv = pref->SetUserValue(aType, aValue, aFromInit, &valueChanged);
@ -4776,6 +4777,41 @@ pref_ReadPrefFromJar(nsZipArchive* aJarReader, const char* aName)
return NS_OK;
}
// These preference getter wrappers allow us to look up the value for static
// preferences based on their native types, rather than manually mapping them to
// the appropriate Preferences::Get* functions.
template<typename T>
static T
GetPref(const char* aName, T aDefaultValue);
template<>
bool MOZ_MAYBE_UNUSED
GetPref<bool>(const char* aName, bool aDefaultValue)
{
return Preferences::GetBool(aName, aDefaultValue);
}
template<>
int32_t MOZ_MAYBE_UNUSED
GetPref<int32_t>(const char* aName, int32_t aDefaultValue)
{
return Preferences::GetInt(aName, aDefaultValue);
}
template<>
uint32_t MOZ_MAYBE_UNUSED
GetPref<uint32_t>(const char* aName, uint32_t aDefaultValue)
{
return Preferences::GetInt(aName, aDefaultValue);
}
template<>
float MOZ_MAYBE_UNUSED
GetPref<float>(const char* aName, float aDefaultValue)
{
return Preferences::GetFloat(aName, aDefaultValue);
}
// Initialize default preference JavaScript buffers from appropriate TEXT
// resources.
/* static */ Result<Ok, const char*>
@ -4804,6 +4840,21 @@ Preferences::InitInitialObjects(bool aIsStartup)
}
}
#ifdef DEBUG
// Check that all varcache preferences match their current values. This can
// currently fail if the default value of a static varcache preference is
// changed in a preference file or at runtime, rather than in
// StaticPrefList.h.
#define PREF(name, cpp_type, value)
#define VARCACHE_PREF(name, id, cpp_type, value) \
MOZ_ASSERT(GetPref<StripAtomic<cpp_type>>(name, value) == StaticPrefs::id(), \
"Incorrect cached value for " name);
#include "mozilla/StaticPrefList.h"
#undef PREF
#undef VARCACHE_PREF
#endif
return Ok();
}