commit 85253fe54b195202ee36907183c81bc8b79da7f4 Author: Arthur Edelstein arthuredelstein@gmail.com Date: Mon Mar 23 00:18:37 2015 -0700
fixup! Bug #5926: Allow customization of content JS locale.
See https://trac.torproject.org/projects/tor/ticket/13019#comment:17
This changes commit 6b90e18cd63c6dcad3b2bee1d3a45a7e3645ff50. --- browser/base/content/test/general/mochitest.ini | 1 + .../test/general/test_bug_jsdefaultlocale.html | 41 ++++++++++++++++++++ xpcom/build/nsXPComInit.cpp | 37 +++++++++--------- 3 files changed, 60 insertions(+), 19 deletions(-)
diff --git a/browser/base/content/test/general/mochitest.ini b/browser/base/content/test/general/mochitest.ini index caccc6f..7f228fe 100644 --- a/browser/base/content/test/general/mochitest.ini +++ b/browser/base/content/test/general/mochitest.ini @@ -29,6 +29,7 @@ support-files =
[test_bug364677.html] [test_bug395533.html] +[test_bug_jsdefaultlocale.html] [test_contextmenu.html] skip-if = toolkit == "gtk2" || toolkit == "gtk3" # disabled on Linux due to bug 513558 [test_contextmenu_input.html] diff --git a/browser/base/content/test/general/test_bug_jsdefaultlocale.html b/browser/base/content/test/general/test_bug_jsdefaultlocale.html new file mode 100644 index 0000000..6566ae0 --- /dev/null +++ b/browser/base/content/test/general/test_bug_jsdefaultlocale.html @@ -0,0 +1,41 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugs.torproject.org/13019 +--> +<head> + <meta charset="utf-8"> + <title>Test for Tor Bug #13019: Prevent fingerprinting of JS-exposed locale</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugs.torproject.org">Bug 13019</a> +<p id="display"></p> +<pre id="test"></pre> +<script type="application/javascript;version=1.8"> +let prefName = "javascript.use_us_english_locale", + originalPrefValue = null, + date = new Date(); +// Read the current pref value. +try { + originalPrefValue = SpecialPowers.getBoolPref(prefName); +} catch (e) { } +// Enable pref "javascript.use_us_english_locale". +SpecialPowers.setBoolPref(prefName, true); +// Test that we are getting en-US locale everywhere it is exposed in JavaScript +is(Intl.Collator().resolvedOptions().locale, "en-US", "content JS locale from Intl.Collator"); +is(Intl.DateTimeFormat().resolvedOptions().locale, "en-US", "content JS locale Intl.DateTimeFormat"); +is(Intl.NumberFormat().resolvedOptions().locale, "en-US", "content JS locale from Intl.NumberFormat"); +is(date.toLocaleString(), date.toLocaleString("en-US"), "Date formatted by JS locale"); +// Return pref to its original value, if it had one. +if (originalPrefValue === null) { + SpecialPowers.clearUserPref(prefName); +} else { + SpecialPowers.setBoolPref(prefName, originalPrefValue); +} + +</script> +</body> +</html> diff --git a/xpcom/build/nsXPComInit.cpp b/xpcom/build/nsXPComInit.cpp index 979e10b..12e46d4 100644 --- a/xpcom/build/nsXPComInit.cpp +++ b/xpcom/build/nsXPComInit.cpp @@ -447,12 +447,12 @@ NS_IMPL_ISUPPORTS(NesteggReporter, nsIMemoryReporter) #endif /* MOZ_WEBM */
// Anonymous namespace for customizing the default locale that JavaScript -// uses, according to the value of the "javascript.default_locale" pref. +// uses, according to the value of the "javascript.use_us_english_locale" pref. // The current default locale can be detected in JavaScript by calling // `Intl.DateTimeFormat().resolvedOptions().locale` namespace {
-#define DEFAULT_LOCALE_PREF "javascript.default_locale" +#define USE_US_ENGLISH_LOCALE_PREF "javascript.use_us_english_locale"
static char* sSystemLocale; static char* sJSLocale; @@ -468,27 +468,26 @@ JSRuntime* GetRuntime() { return rt; }
-// Takes the "javascript.default_locale" pref value and applies it. If the locale -// is empty, we fall back to the default system and JS locales. +// If the USE_US_ENGLISH_LOCALE_PREF is active, set all locales to US English. +// Otherwise, fall back to the default system and JS locales. static -void DefaultLocaleChangedCallback(const char* /* pref */, void* /* closure */) { +void UseUSEnglishLocalePrefChangedCallback(const char* /* pref */, void* /* closure */) { // Get a pointer to the default JS Runtime. JSRuntime* rt = GetRuntime(); if (rt) { - // Read the pref, which may contain a custom default locale to be used in JavaScript. - nsAutoCString prefLocale; - mozilla::Preferences::GetCString(DEFAULT_LOCALE_PREF, &prefLocale); + // Read the pref to see if we will use US English locale. + bool useUSEnglishLocale = mozilla::Preferences::GetBool(USE_US_ENGLISH_LOCALE_PREF, false); // Set the application-wide C-locale. Needed for Date.toLocaleFormat(). - setlocale(LC_ALL, prefLocale.IsEmpty() ? sSystemLocale : prefLocale.get()); + setlocale(LC_ALL, useUSEnglishLocale ? "en_US" : sSystemLocale); // Now override the JavaScript Runtime Locale that is used by the Intl API // as well as Date.toLocaleString, Number.toLocaleString, and String.localeCompare. - JS_SetDefaultLocale(rt, prefLocale.IsEmpty() ? sJSLocale : prefLocale.get()); + JS_SetDefaultLocale(rt, useUSEnglishLocale ? "en-US" : sJSLocale); } }
static -void StartWatchingDefaultLocalePref() { - // Get the default system locale. To be used if pref is not available. +void StartWatchingUseUSEnglishLocalePref() { + // Get the default system locale. To be used if US English locale pref is deactivated. sSystemLocale = strdup(setlocale(LC_ALL,NULL)); // Store the default JavaScript locale. JSRuntime* rt = GetRuntime(); @@ -496,17 +495,17 @@ void StartWatchingDefaultLocalePref() { sJSLocale = strdup(JS_GetDefaultLocale(rt)); } // Now keep the locale updated with the current pref value. - mozilla::Preferences::RegisterCallbackAndCall(DefaultLocaleChangedCallback, DEFAULT_LOCALE_PREF); + mozilla::Preferences::RegisterCallbackAndCall(UseUSEnglishLocalePrefChangedCallback, USE_US_ENGLISH_LOCALE_PREF); }
static -void StopWatchingDefaultLocalePref() { - mozilla::Preferences::UnregisterCallback(DefaultLocaleChangedCallback, DEFAULT_LOCALE_PREF); +void StopWatchingUseUSEnglishLocalePref() { + mozilla::Preferences::UnregisterCallback(UseUSEnglishLocalePrefChangedCallback, USE_US_ENGLISH_LOCALE_PREF); if (sSystemLocale) free(sSystemLocale); if (sJSLocale) JS_free(nullptr, sJSLocale); }
-} // anonymous namespace for locale pref +} // anonymous namespace for locale hiding
EXPORT_XPCOM_API(nsresult) NS_InitXPCOM2(nsIServiceManager* *result, @@ -766,8 +765,8 @@ NS_InitXPCOM2(nsIServiceManager* *result, mozilla::eventtracer::Init(); #endif
- // Start watching the javascript.default_locale pref. - StartWatchingDefaultLocalePref(); + // Start watching the "javascript.use_us_english_locale" pref. + StartWatchingUseUSEnglishLocalePref(); return NS_OK; }
@@ -1033,7 +1032,7 @@ ShutdownXPCOM(nsIServiceManager* servMgr) sExitManager = nullptr; }
- StopWatchingDefaultLocalePref(); + StopWatchingUseUSEnglishLocalePref();
Omnijar::CleanUp();