From 4ef55072b958e992717ca7ad54518496cf56f7e2 Mon Sep 17 00:00:00 2001 From: Kris Maglione Date: Mon, 23 Jul 2018 17:32:54 -0700 Subject: [PATCH] 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 --- modules/libpref/Preferences.cpp | 57 +++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/modules/libpref/Preferences.cpp b/modules/libpref/Preferences.cpp index 79943ac82b73..b9a5ff4ce558 100644 --- a/modules/libpref/Preferences.cpp +++ b/modules/libpref/Preferences.cpp @@ -1693,7 +1693,8 @@ static Result pref_LookupForModify(const char* aPrefName, const std::function& aCheckFn) { - Maybe wrapper = pref_Lookup(aPrefName, /* includeTypeNone */ true); + Maybe 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 +static T +GetPref(const char* aName, T aDefaultValue); + +template<> +bool MOZ_MAYBE_UNUSED +GetPref(const char* aName, bool aDefaultValue) +{ + return Preferences::GetBool(aName, aDefaultValue); +} + +template<> +int32_t MOZ_MAYBE_UNUSED +GetPref(const char* aName, int32_t aDefaultValue) +{ + return Preferences::GetInt(aName, aDefaultValue); +} + +template<> +uint32_t MOZ_MAYBE_UNUSED +GetPref(const char* aName, uint32_t aDefaultValue) +{ + return Preferences::GetInt(aName, aDefaultValue); +} + +template<> +float MOZ_MAYBE_UNUSED +GetPref(const char* aName, float aDefaultValue) +{ + return Preferences::GetFloat(aName, aDefaultValue); +} + // Initialize default preference JavaScript buffers from appropriate TEXT // resources. /* static */ Result @@ -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>(name, value) == StaticPrefs::id(), \ + "Incorrect cached value for " name); +#include "mozilla/StaticPrefList.h" +#undef PREF +#undef VARCACHE_PREF +#endif + return Ok(); }