Ticket #23016: 0001-Issue-23016-Print-to-File-does-not-create-the-expect.patch

File 0001-Issue-23016-Print-to-File-does-not-create-the-expect.patch, 9.4 KB (added by pospeselr, 3 years ago)

fixed macos build failure and updated commit message explaining the problem and solution

  • intl/locale/nsLocaleService.cpp

    From b70c11e95430d3354c77a17e77a97deb837c669b Mon Sep 17 00:00:00 2001
    From: Richard Pospesel <richard@torproject.org>
    Date: Wed, 15 Nov 2017 10:48:38 -0800
    Subject: [PATCH] Issue 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 base 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, it's printer names will be localized and in the langauge 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 prference 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 occur, 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 b  
    1212#include "nsTArray.h"
    1313#include "nsString.h"
    1414#include "mozilla/UniquePtr.h"
     15#include "mozilla/Preferences.h"
    1516
    1617#include <ctype.h>
    1718
    protected: 
    9394//
    9495nsLocaleService::nsLocaleService(void)
    9596{
     97    // conditionally use us english locale when initialization locale objects
     98    const auto use_us_english_locale =
     99        mozilla::Preferences::GetBool("javascript.use_us_english_locale", false);
     100
    96101#ifdef XP_WIN
    97102    nsAutoString        xpLocale;
     103    // 1033 is default english us locale LCID
     104    // https://msdn.microsoft.com/en-us/library/ms912047(v=winembedded.10).aspx
     105    const LCID          en_US_lcid = 1033;
     106
    98107    //
    99108    // get the system LCID
    100109    //
    101     LCID win_lcid = GetSystemDefaultLCID();
     110    LCID win_lcid = use_us_english_locale ? en_US_lcid : GetSystemDefaultLCID();
    102111    NS_ENSURE_TRUE_VOID(win_lcid);
    103112    nsWin32Locale::GetXPLocale(win_lcid, xpLocale);
    104113    nsresult rv = NewLocale(xpLocale, getter_AddRefs(mSystemLocale));
    nsLocaleService::nsLocaleService(void) 
    107116    //
    108117    // get the application LCID
    109118    //
    110     win_lcid = GetUserDefaultLCID();
     119    win_lcid = use_us_english_locale ? en_US_lcid : GetUserDefaultLCID();
    111120    NS_ENSURE_TRUE_VOID(win_lcid);
    112121    nsWin32Locale::GetXPLocale(win_lcid, xpLocale);
    113122    rv = NewLocale(xpLocale, getter_AddRefs(mApplicationLocale));
    nsLocaleService::nsLocaleService(void) 
    118127    NS_ENSURE_TRUE_VOID(resultLocale);
    119128
    120129    // Get system configuration
    121     const char* lang = getenv("LANG");
     130    const char* lang = use_us_english_locale ? "en-US" : getenv("LANG");
    122131
    123132    nsAutoString xpLocale, platformLocale;
    124133    nsAutoString category, category_platform;
    nsLocaleService::nsLocaleService(void) 
    127136    for( i = 0; i < LocaleListLength; i++ ) {
    128137        nsresult result;
    129138        // setlocale( , "") evaluates LC_* and LANG
    130         char* lc_temp = setlocale(posix_locale_category[i], "");
     139        const auto current_posix_locale_category = posix_locale_category[i];
     140        const char* lc_temp = nullptr;
     141
     142        if (use_us_english_locale) {
     143            lc_temp = setlocale(current_posix_locale_category, "C.UTF-8");
     144            if (lc_temp == nullptr) {
     145                lc_temp = setlocale(current_posix_locale_category, "C");
     146            }
     147        }
     148        else {
     149            lc_temp = setlocale(current_posix_locale_category, "");
     150        }
     151
    131152        CopyASCIItoUTF16(LocaleList[i], category);
    132153        category_platform = category;
    133154        category_platform.AppendLiteral("##PLATFORM");
    nsLocaleService::nsLocaleService(void) 
    163184#endif // XP_UNIX
    164185
    165186#ifdef XP_MACOSX
    166     // Get string representation of user's current locale
    167     CFLocaleRef userLocaleRef = ::CFLocaleCopyCurrent();
    168     CFStringRef userLocaleStr = ::CFLocaleGetIdentifier(userLocaleRef);
    169     ::CFRetain(userLocaleStr);
    170 
    171     AutoTArray<UniChar, 32> buffer;
    172     int size = ::CFStringGetLength(userLocaleStr);
    173     buffer.SetLength(size + 1);
    174     CFRange range = ::CFRangeMake(0, size);
    175     ::CFStringGetCharacters(userLocaleStr, range, buffer.Elements());
    176     buffer[size] = 0;
    177 
    178     // Convert the locale string to the format that Mozilla expects
    179     nsAutoString xpLocale(reinterpret_cast<char16_t*>(buffer.Elements()));
    180     xpLocale.ReplaceChar('_', '-');
     187    nsAutoString xpLocale;
     188
     189    if (use_us_english_locale) {
     190        xpLocale = NS_LITERAL_STRING("en-US").get();
     191    }
     192    else {
     193        // Get string representation of user's current locale
     194        CFLocaleRef userLocaleRef = ::CFLocaleCopyCurrent();
     195        CFStringRef userLocaleStr = ::CFLocaleGetIdentifier(userLocaleRef);
     196        ::CFRetain(userLocaleStr);
     197
     198        AutoTArray<UniChar, 32> buffer;
     199        int size = ::CFStringGetLength(userLocaleStr);
     200        buffer.SetLength(size + 1);
     201        CFRange range = ::CFRangeMake(0, size);
     202        ::CFStringGetCharacters(userLocaleStr, range, buffer.Elements());
     203        buffer[size] = 0;
     204
     205        // Convert the locale string to the format that Mozilla expects
     206        xpLocale = reinterpret_cast<char16_t*>(buffer.Elements());
     207        xpLocale.ReplaceChar('_', '-');
     208
     209        ::CFRelease(userLocaleStr);
     210        ::CFRelease(userLocaleRef);
     211    }
    181212
    182213    nsresult rv = NewLocale(xpLocale, getter_AddRefs(mSystemLocale));
    183214    if (NS_SUCCEEDED(rv)) {
    184215        mApplicationLocale = mSystemLocale;
    185216    }
    186217
    187     ::CFRelease(userLocaleStr);
    188     ::CFRelease(userLocaleRef);
    189 
    190218    NS_ASSERTION(mApplicationLocale, "Failed to create locale objects");
    191219#endif // XP_MACOSX
    192220}
  • xpcom/build/XPCOMInit.cpp

    diff --git a/xpcom/build/XPCOMInit.cpp b/xpcom/build/XPCOMInit.cpp
    index c72ea48d77c8..4fe9c93de2ec 100644
    a b  
    1111#include "mozilla/Poison.h"
    1212#include "mozilla/SharedThreadPool.h"
    1313#include "mozilla/XPCOM.h"
     14#include "mozilla/Preferences.h"
    1415#include "nsXULAppAPI.h"
    1516
    1617#include "nsXPCOMPrivate.h"
    NS_InitXPCOM2(nsIServiceManager** aResult, 
    571572  }
    572573
    573574#ifndef ANDROID
     575
    574576  // If the locale hasn't already been setup by our embedder,
    575   // get us out of the "C" locale and into the system
    576   if (strcmp(setlocale(LC_ALL, nullptr), "C") == 0) {
    577     setlocale(LC_ALL, "");
     577  // get us out of the "C" locale and into the system,
     578  // but only do so if we aren't force using english locale
     579  if (mozilla::Preferences::GetBool("javascript.use_us_english_locale", false)) {
     580    setlocale(LC_ALL, "C.UTF-8") || setlocale(LC_ALL, "C");
     581  } else {
     582    if (strcmp(setlocale(LC_ALL, nullptr), "C") == 0) {
     583      setlocale(LC_ALL, "");
     584    }
    578585  }
     586
    579587#endif
    580588
    581589#if defined(XP_UNIX)
  • xpcom/io/nsNativeCharsetUtils.cpp

    diff --git a/xpcom/io/nsNativeCharsetUtils.cpp b/xpcom/io/nsNativeCharsetUtils.cpp
    index e53307af5628..f81c1179256b 100644
    a b NS_ShutdownNativeCharsetUtils() 
    4848#include <stdlib.h>   // mbtowc, wctomb
    4949#include <locale.h>   // setlocale
    5050#include "mozilla/Mutex.h"
     51#include "mozilla/Preferences.h"
    5152#include "nscore.h"
    5253#include "nsAString.h"
    5354#include "nsReadableUtils.h"
    nsNativeCharsetConverter::LazyInit() 
    316317  // NS_StartupNativeCharsetUtils, assume we are called early enough that
    317318  // we are the first to care about the locale's charset.
    318319  if (!gLock) {
    319     setlocale(LC_CTYPE, "");
     320
     321    if (mozilla::Preferences::GetBool("javascript.use_us_english_locale", false)) {
     322      setlocale(LC_CTYPE, "C.UTF-8") || setlocale(LC_CTYPE, "C");
     323    } else {
     324      setlocale(LC_CTYPE, "");
     325    }
    320326  }
    321327  const char* blank_list[] = { "", nullptr };
    322328  const char** native_charset_list = blank_list;
    NS_StartupNativeCharsetUtils() 
    884890  // XXX we assume that we are called early enough that we should
    885891  // always be the first to care about the locale's charset.
    886892  //
    887   setlocale(LC_CTYPE, "");
     893  if (mozilla::Preferences::GetBool("javascript.use_us_english_locale", false)) {
     894    setlocale(LC_CTYPE, "C.UTF-8") || setlocale(LC_CTYPE, "C");
     895  } else {
     896    setlocale(LC_CTYPE, "");
     897  }
    888898
    889899  nsNativeCharsetConverter::GlobalInit();
    890900}