[tbb-commits] [tor-browser/tor-browser-52.5.2esr-7.5-2] Bug 23016: "Print to File" does not create the expected file in non-English locales
gk at torproject.org
gk at torproject.org
Thu Dec 14 12:53:02 UTC 2017
commit 8ea9839478bfddd4f078f16c9268edf1755e9cb0
Author: Richard Pospesel <richard at torproject.org>
Date: Wed Nov 15 10:48:38 2017 -0800
Bug 23016: "Print to File" does not create the expected file in non-English locales
The Problem:
During firefox and Web Content process startup,
::OverrideDefaultLocaleIfNeeded() is called which will conditionally
::setlocale() to "C.UTF-8" or "C" based off of the
javascript.use_us_english_locale preference (to prevent fingerprinting
based on how dates and what-not are formatted). Sometime after this
call in the Web Content process the locale is set to the system's locale
which effectively stomps over the work done by the
::OverrideDefaultLocaleIfNeeded() call. As a result, the firefox
process and the Web Content process are configured to use different
locales; firefox uses "C.UTF-8" while Web Content uses "" (system
default).
On Linux, the "Print to File" printer is a default GTK printer whose
name is localized based off of the process's locale. The GTK print dialog
is hosted in the firefox process and therefore the printer name will be
'Print to File.' This process sends this name over to the Web Content
process, which iterates over the list of printers and finds one whose
name matches. However, as the Web Content process's locale is set to
system, its printer names will be localized and in the language of the
system, so no printer with the name 'Print to File' will be found, and
printing fails.
This is why disabling javascript.use_us_english_locale fixes the issue.
It also explains why disabling multi-process mode via the
browser.tabs.remote.autostart.2 preference fixes the issue; one
process means the printer-name is never used as a selector and also
means no mismatched locale can happen.
The Solution:
The fix for this issue is to first check the
javascript.use_us_english_locale preference each place in code where
setlocale occurs, particularly in the nsLocaleService object which is the
particular code path which overrides setlocale in the Web Content
process.
---
intl/locale/nsLocaleService.cpp | 72 +++++++++++++++++++++++++++------------
xpcom/build/XPCOMInit.cpp | 14 ++++++--
xpcom/io/nsNativeCharsetUtils.cpp | 14 ++++++--
3 files changed, 73 insertions(+), 27 deletions(-)
diff --git a/intl/locale/nsLocaleService.cpp b/intl/locale/nsLocaleService.cpp
index 6d45ec9afa2a..e89ff32346cd 100644
--- a/intl/locale/nsLocaleService.cpp
+++ b/intl/locale/nsLocaleService.cpp
@@ -12,6 +12,7 @@
#include "nsTArray.h"
#include "nsString.h"
#include "mozilla/UniquePtr.h"
+#include "mozilla/Preferences.h"
#include <ctype.h>
@@ -93,12 +94,20 @@ protected:
//
nsLocaleService::nsLocaleService(void)
{
+ // conditionally use us english locale when initialization locale objects
+ const auto use_us_english_locale =
+ mozilla::Preferences::GetBool("javascript.use_us_english_locale", false);
+
#ifdef XP_WIN
nsAutoString xpLocale;
+ // 1033 is default english us locale LCID
+ // https://msdn.microsoft.com/en-us/library/ms912047(v=winembedded.10).aspx
+ const LCID en_US_lcid = 1033;
+
//
// get the system LCID
//
- LCID win_lcid = GetSystemDefaultLCID();
+ LCID win_lcid = use_us_english_locale ? en_US_lcid : GetSystemDefaultLCID();
NS_ENSURE_TRUE_VOID(win_lcid);
nsWin32Locale::GetXPLocale(win_lcid, xpLocale);
nsresult rv = NewLocale(xpLocale, getter_AddRefs(mSystemLocale));
@@ -107,7 +116,7 @@ nsLocaleService::nsLocaleService(void)
//
// get the application LCID
//
- win_lcid = GetUserDefaultLCID();
+ win_lcid = use_us_english_locale ? en_US_lcid : GetUserDefaultLCID();
NS_ENSURE_TRUE_VOID(win_lcid);
nsWin32Locale::GetXPLocale(win_lcid, xpLocale);
rv = NewLocale(xpLocale, getter_AddRefs(mApplicationLocale));
@@ -118,7 +127,7 @@ nsLocaleService::nsLocaleService(void)
NS_ENSURE_TRUE_VOID(resultLocale);
// Get system configuration
- const char* lang = getenv("LANG");
+ const char* lang = use_us_english_locale ? "en-US" : getenv("LANG");
nsAutoString xpLocale, platformLocale;
nsAutoString category, category_platform;
@@ -127,7 +136,19 @@ nsLocaleService::nsLocaleService(void)
for( i = 0; i < LocaleListLength; i++ ) {
nsresult result;
// setlocale( , "") evaluates LC_* and LANG
- char* lc_temp = setlocale(posix_locale_category[i], "");
+ const auto current_posix_locale_category = posix_locale_category[i];
+ const char* lc_temp = nullptr;
+
+ if (use_us_english_locale) {
+ lc_temp = setlocale(current_posix_locale_category, "C.UTF-8");
+ if (lc_temp == nullptr) {
+ lc_temp = setlocale(current_posix_locale_category, "C");
+ }
+ }
+ else {
+ lc_temp = setlocale(current_posix_locale_category, "");
+ }
+
CopyASCIItoUTF16(LocaleList[i], category);
category_platform = category;
category_platform.AppendLiteral("##PLATFORM");
@@ -163,30 +184,37 @@ nsLocaleService::nsLocaleService(void)
#endif // XP_UNIX
#ifdef XP_MACOSX
- // Get string representation of user's current locale
- CFLocaleRef userLocaleRef = ::CFLocaleCopyCurrent();
- CFStringRef userLocaleStr = ::CFLocaleGetIdentifier(userLocaleRef);
- ::CFRetain(userLocaleStr);
-
- AutoTArray<UniChar, 32> buffer;
- int size = ::CFStringGetLength(userLocaleStr);
- buffer.SetLength(size + 1);
- CFRange range = ::CFRangeMake(0, size);
- ::CFStringGetCharacters(userLocaleStr, range, buffer.Elements());
- buffer[size] = 0;
-
- // Convert the locale string to the format that Mozilla expects
- nsAutoString xpLocale(reinterpret_cast<char16_t*>(buffer.Elements()));
- xpLocale.ReplaceChar('_', '-');
+ nsAutoString xpLocale;
+
+ if (use_us_english_locale) {
+ xpLocale = NS_LITERAL_STRING("en-US").get();
+ }
+ else {
+ // Get string representation of user's current locale
+ CFLocaleRef userLocaleRef = ::CFLocaleCopyCurrent();
+ CFStringRef userLocaleStr = ::CFLocaleGetIdentifier(userLocaleRef);
+ ::CFRetain(userLocaleStr);
+
+ AutoTArray<UniChar, 32> buffer;
+ int size = ::CFStringGetLength(userLocaleStr);
+ buffer.SetLength(size + 1);
+ CFRange range = ::CFRangeMake(0, size);
+ ::CFStringGetCharacters(userLocaleStr, range, buffer.Elements());
+ buffer[size] = 0;
+
+ // Convert the locale string to the format that Mozilla expects
+ xpLocale = reinterpret_cast<char16_t*>(buffer.Elements());
+ xpLocale.ReplaceChar('_', '-');
+
+ ::CFRelease(userLocaleStr);
+ ::CFRelease(userLocaleRef);
+ }
nsresult rv = NewLocale(xpLocale, getter_AddRefs(mSystemLocale));
if (NS_SUCCEEDED(rv)) {
mApplicationLocale = mSystemLocale;
}
- ::CFRelease(userLocaleStr);
- ::CFRelease(userLocaleRef);
-
NS_ASSERTION(mApplicationLocale, "Failed to create locale objects");
#endif // XP_MACOSX
}
diff --git a/xpcom/build/XPCOMInit.cpp b/xpcom/build/XPCOMInit.cpp
index c72ea48d77c8..4fe9c93de2ec 100644
--- a/xpcom/build/XPCOMInit.cpp
+++ b/xpcom/build/XPCOMInit.cpp
@@ -11,6 +11,7 @@
#include "mozilla/Poison.h"
#include "mozilla/SharedThreadPool.h"
#include "mozilla/XPCOM.h"
+#include "mozilla/Preferences.h"
#include "nsXULAppAPI.h"
#include "nsXPCOMPrivate.h"
@@ -571,11 +572,18 @@ NS_InitXPCOM2(nsIServiceManager** aResult,
}
#ifndef ANDROID
+
// If the locale hasn't already been setup by our embedder,
- // get us out of the "C" locale and into the system
- if (strcmp(setlocale(LC_ALL, nullptr), "C") == 0) {
- setlocale(LC_ALL, "");
+ // get us out of the "C" locale and into the system,
+ // but only do so if we aren't force using english locale
+ if (mozilla::Preferences::GetBool("javascript.use_us_english_locale", false)) {
+ setlocale(LC_ALL, "C.UTF-8") || setlocale(LC_ALL, "C");
+ } else {
+ if (strcmp(setlocale(LC_ALL, nullptr), "C") == 0) {
+ setlocale(LC_ALL, "");
+ }
}
+
#endif
#if defined(XP_UNIX)
diff --git a/xpcom/io/nsNativeCharsetUtils.cpp b/xpcom/io/nsNativeCharsetUtils.cpp
index e53307af5628..f81c1179256b 100644
--- a/xpcom/io/nsNativeCharsetUtils.cpp
+++ b/xpcom/io/nsNativeCharsetUtils.cpp
@@ -48,6 +48,7 @@ NS_ShutdownNativeCharsetUtils()
#include <stdlib.h> // mbtowc, wctomb
#include <locale.h> // setlocale
#include "mozilla/Mutex.h"
+#include "mozilla/Preferences.h"
#include "nscore.h"
#include "nsAString.h"
#include "nsReadableUtils.h"
@@ -316,7 +317,12 @@ nsNativeCharsetConverter::LazyInit()
// NS_StartupNativeCharsetUtils, assume we are called early enough that
// we are the first to care about the locale's charset.
if (!gLock) {
- setlocale(LC_CTYPE, "");
+
+ if (mozilla::Preferences::GetBool("javascript.use_us_english_locale", false)) {
+ setlocale(LC_CTYPE, "C.UTF-8") || setlocale(LC_CTYPE, "C");
+ } else {
+ setlocale(LC_CTYPE, "");
+ }
}
const char* blank_list[] = { "", nullptr };
const char** native_charset_list = blank_list;
@@ -884,7 +890,11 @@ NS_StartupNativeCharsetUtils()
// XXX we assume that we are called early enough that we should
// always be the first to care about the locale's charset.
//
- setlocale(LC_CTYPE, "");
+ if (mozilla::Preferences::GetBool("javascript.use_us_english_locale", false)) {
+ setlocale(LC_CTYPE, "C.UTF-8") || setlocale(LC_CTYPE, "C");
+ } else {
+ setlocale(LC_CTYPE, "");
+ }
nsNativeCharsetConverter::GlobalInit();
}
More information about the tbb-commits
mailing list