MFH: r527890

www/firefox: backport font selection regression fix

Requested by:	Andy New (on gecko@ list)
Approved by:	ports-secteam blanket
This commit is contained in:
Jan Beich 2020-03-07 19:07:20 +00:00
parent 1be80b5578
commit 84e9e400f0
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/branches/2020Q1/; revision=527970
2 changed files with 282 additions and 0 deletions

View File

@ -3,6 +3,7 @@
PORTNAME= firefox
DISTVERSION= 74.0
PORTREVISION= 1
PORTEPOCH= 1
CATEGORIES= www
MASTER_SITES= MOZILLA/${PORTNAME}/releases/${DISTVERSION}/source \

View File

@ -0,0 +1,281 @@
commit 9d26727a4e85
Author: Zibi Braniecki <zbraniecki@mozilla.com>
Date: Fri Feb 21 00:39:18 2020 +0000
Bug 1607052 - Unify language identifier canonicalization in LocaleService and OSPreferences to use unic_langid, and extend GTK's RegionalPrefs reading to fallback on SystemLocales. r=jfkthame
Differential Revision: https://phabricator.services.mozilla.com/D63393
--HG--
extra : moz-landing-system : lando
---
intl/locale/LocaleService.cpp | 53 ++-------------------------
intl/locale/LocaleService.h | 18 +++++++++
intl/locale/OSPreferences.cpp | 18 ++-------
intl/locale/rust/unic-langid-ffi/src/lib.rs | 33 ++++++++++++++---
intl/locale/tests/gtest/TestLocaleService.cpp | 23 ++++++++++++
intl/locale/tests/unit/test_localeService.js | 3 +-
6 files changed, 77 insertions(+), 71 deletions(-)
diff --git intl/locale/LocaleService.cpp intl/locale/LocaleService.cpp
index f7e13e36ccbc7..6708c4af4b5c3 100644
--- intl/locale/LocaleService.cpp
+++ intl/locale/LocaleService.cpp
@@ -39,51 +39,6 @@ NS_IMPL_ISUPPORTS(LocaleService, mozILocaleService, nsIObserver,
mozilla::StaticRefPtr<LocaleService> LocaleService::sInstance;
-/**
- * This function transforms a canonical Mozilla Language Tag, into it's
- * BCP47 compilant form.
- *
- * Example: "ja-JP-mac" -> "ja-JP-macos"
- *
- * The BCP47 form should be used for all calls to ICU/Intl APIs.
- * The canonical form is used for all internal operations.
- */
-static bool SanitizeForBCP47(nsACString& aLocale, bool strict) {
- // Currently, the only locale code we use that's not BCP47-conformant is
- // "ja-JP-mac" on OS X, and ICU canonicalizes it into a mouthfull
- // "ja-JP-x-lvariant-mac", so instead we're hardcoding a conversion
- // of it to "ja-JP-macos".
- if (aLocale.LowerCaseEqualsASCII("ja-jp-mac")) {
- aLocale.AssignLiteral("ja-JP-macos");
- return true;
- }
-
- nsAutoCString locale(aLocale);
- locale.Trim(" ");
-
- // POSIX may bring us locales such as "en-US.UTF8", which
- // ICU converts to `en-US-u-va-posix`. Let's cut out
- // the `.UTF8`, since it doesn't matter for us.
- int32_t pos = locale.FindChar('.');
- if (pos != -1) {
- locale.Cut(pos, locale.Length() - pos);
- }
-
- // The rest of this function will use ICU canonicalization for any other
- // tag that may come this way.
- const int32_t LANG_TAG_CAPACITY = 128;
- char langTag[LANG_TAG_CAPACITY];
- UErrorCode err = U_ZERO_ERROR;
- // This is a fail-safe method that will set langTag to "und" if it cannot
- // match any part of the input locale code.
- int32_t len = uloc_toLanguageTag(locale.get(), langTag, LANG_TAG_CAPACITY,
- strict, &err);
- if (U_SUCCESS(err) && len > 0) {
- aLocale.Assign(langTag, len);
- }
- return U_SUCCESS(err);
-}
-
/**
* This function splits an input string by `,` delimiter, sanitizes the result
* language tags and returns them to the caller.
@@ -93,7 +48,7 @@ static void SplitLocaleListStringIntoArray(nsACString& str,
if (str.Length() > 0) {
for (const nsACString& part : str.Split(',')) {
nsAutoCString locale(part);
- if (SanitizeForBCP47(locale, true)) {
+ if (LocaleService::CanonicalizeLanguageId(locale)) {
if (!aRetVal.Contains(locale)) {
aRetVal.AppendElement(locale);
}
@@ -421,7 +376,7 @@ LocaleService::GetDefaultLocale(nsACString& aRetVal) {
locale.Trim(" \t\n\r");
// This should never be empty.
MOZ_ASSERT(!locale.IsEmpty());
- if (SanitizeForBCP47(locale, true)) {
+ if (CanonicalizeLanguageId(locale)) {
mDefaultLocale.Assign(locale);
}
@@ -617,7 +572,7 @@ LocaleService::SetRequestedLocales(const nsTArray<nsCString>& aRequested) {
for (auto& req : aRequested) {
nsAutoCString locale(req);
- if (!SanitizeForBCP47(locale, true)) {
+ if (!CanonicalizeLanguageId(locale)) {
NS_ERROR("Invalid language tag provided to SetRequestedLocales!");
return NS_ERROR_INVALID_ARG;
}
@@ -667,7 +622,7 @@ LocaleService::SetAvailableLocales(const nsTArray<nsCString>& aAvailable) {
for (auto& avail : aAvailable) {
nsAutoCString locale(avail);
- if (!SanitizeForBCP47(locale, true)) {
+ if (!CanonicalizeLanguageId(locale)) {
NS_ERROR("Invalid language tag provided to SetAvailableLocales!");
return NS_ERROR_INVALID_ARG;
}
diff --git intl/locale/LocaleService.h intl/locale/LocaleService.h
index 2ff428da3e3fd..5f5152c1fbb7a 100644
--- intl/locale/LocaleService.h
+++ intl/locale/LocaleService.h
@@ -10,6 +10,7 @@
#include "nsString.h"
#include "nsTArray.h"
#include "nsWeakReference.h"
+#include "MozLocaleBindings.h"
#include "mozILocaleService.h"
@@ -104,6 +105,23 @@ class LocaleService final : public mozILocaleService,
return RefPtr<LocaleService>(GetInstance()).forget();
}
+ /**
+ * Canonicalize a Unicode Language Identifier string.
+ *
+ * The operation is:
+ * * Normalizing casing (`eN-Us-Windows` -> `en-US-windows`)
+ * * Switching `_` to `-` (`en_US` -> `en-US`)
+ * * Rejecting invalid identifiers (`e21-X` sets aLocale to `und` and
+ * returns false)
+ * * Normalizing Mozilla's `ja-JP-mac` to `ja-JP-macos`
+ * * Cutting off POSIX dot postfix (`en-US.utf8` -> `en-US`)
+ *
+ * This operation should be used on any external input before
+ * it gets used in internal operations.
+ */
+ static bool CanonicalizeLanguageId(nsACString& aLocale) {
+ return ffi::unic_langid_canonicalize(&aLocale);
+ }
/**
* This method should only be called in the client mode.
*
diff --git intl/locale/OSPreferences.cpp intl/locale/OSPreferences.cpp
index 283db96e0d718..f816ca57abfea 100644
--- intl/locale/OSPreferences.cpp
+++ intl/locale/OSPreferences.cpp
@@ -54,19 +54,7 @@ void OSPreferences::Refresh() {
* It returns true if the canonicalization was successful.
*/
bool OSPreferences::CanonicalizeLanguageTag(nsCString& aLoc) {
- char langTag[512];
-
- UErrorCode status = U_ZERO_ERROR;
-
- int32_t langTagLen = uloc_toLanguageTag(aLoc.get(), langTag,
- sizeof(langTag) - 1, false, &status);
-
- if (U_FAILURE(status)) {
- return false;
- }
-
- aLoc.Assign(langTag, langTagLen);
- return true;
+ return LocaleService::CanonicalizeLanguageId(aLoc);
}
/**
@@ -291,7 +279,9 @@ OSPreferences::GetRegionalPrefsLocales(nsTArray<nsCString>& aRetVal) {
return NS_OK;
}
- return NS_ERROR_FAILURE;
+ // If we failed to read regional prefs locales,
+ // use system locales as last fallback.
+ return GetSystemLocales(aRetVal);
}
static OSPreferences::DateTimeFormatStyle ToDateTimeFormatStyle(
diff --git intl/locale/rust/unic-langid-ffi/src/lib.rs intl/locale/rust/unic-langid-ffi/src/lib.rs
index 701d3679c4cec..517e08c1a64c1 100644
--- intl/locale/rust/unic-langid-ffi/src/lib.rs
+++ intl/locale/rust/unic-langid-ffi/src/lib.rs
@@ -5,18 +5,39 @@
use nsstring::nsACString;
use nsstring::nsCString;
use thin_vec::ThinVec;
-pub use unic_langid::LanguageIdentifier;
+pub use unic_langid::{LanguageIdentifier, LanguageIdentifierError};
+
+fn new_langid_for_mozilla(name: &nsACString) -> Result<LanguageIdentifier, LanguageIdentifierError> {
+ if name.eq_ignore_ascii_case(b"ja-jp-mac") {
+ "ja-JP-macos".parse()
+ } else {
+ // Cut out any `.FOO` like `en-US.POSIX`.
+ let mut name: &[u8] = name.as_ref();
+ if let Some(ptr) = name.iter().position(|b| b == &b'.') {
+ name = &name[..ptr];
+ }
+ LanguageIdentifier::from_bytes(name)
+ }
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn unic_langid_canonicalize(name: &mut nsACString) -> bool {
+ let langid = new_langid_for_mozilla(name);
+
+ let result = langid.is_ok();
+
+ name.assign(&langid.unwrap_or_default().to_string());
+
+ result
+}
+
#[no_mangle]
pub unsafe extern "C" fn unic_langid_new(
name: &nsACString,
ret_val: &mut bool,
) -> *mut LanguageIdentifier {
- let langid = if name.eq_ignore_ascii_case(b"ja-jp-mac") {
- "ja-JP-macos".parse()
- } else {
- LanguageIdentifier::from_bytes(name)
- };
+ let langid = new_langid_for_mozilla(name);
*ret_val = langid.is_ok();
Box::into_raw(Box::new(langid.unwrap_or_default()))
diff --git intl/locale/tests/gtest/TestLocaleService.cpp intl/locale/tests/gtest/TestLocaleService.cpp
index b13ecfd237dfa..aaac8615b09fd 100644
--- intl/locale/tests/gtest/TestLocaleService.cpp
+++ intl/locale/tests/gtest/TestLocaleService.cpp
@@ -10,6 +10,29 @@
using namespace mozilla::intl;
+TEST(Intl_Locale_LocaleService, CanonicalizeLanguageId)
+{
+ nsCString locale("en-US.POSIX");
+ ASSERT_TRUE(LocaleService::CanonicalizeLanguageId(locale));
+ ASSERT_TRUE(locale.EqualsLiteral("en-US"));
+
+ locale.AssignLiteral("en-US_POSIX");
+ ASSERT_TRUE(LocaleService::CanonicalizeLanguageId(locale));
+ ASSERT_TRUE(locale.EqualsLiteral("en-US-posix"));
+
+ locale.AssignLiteral("en-US-POSIX");
+ ASSERT_TRUE(LocaleService::CanonicalizeLanguageId(locale));
+ ASSERT_TRUE(locale.EqualsLiteral("en-US-posix"));
+
+ locale.AssignLiteral("C");
+ ASSERT_FALSE(LocaleService::CanonicalizeLanguageId(locale));
+ ASSERT_TRUE(locale.EqualsLiteral("und"));
+
+ locale.AssignLiteral("");
+ ASSERT_FALSE(LocaleService::CanonicalizeLanguageId(locale));
+ ASSERT_TRUE(locale.EqualsLiteral("und"));
+}
+
TEST(Intl_Locale_LocaleService, GetAppLocalesAsBCP47)
{
nsTArray<nsCString> appLocales;
diff --git intl/locale/tests/unit/test_localeService.js intl/locale/tests/unit/test_localeService.js
index 1970ae94b2607..202c2674972a8 100644
--- intl/locale/tests/unit/test_localeService.js
+++ intl/locale/tests/unit/test_localeService.js
@@ -204,8 +204,7 @@ add_test(function test_requestedLocales_sanitize() {
Assert.equal(locales[0], "de");
Assert.equal(locales[1], "pl");
Assert.equal(locales[2], "de-AT");
- Assert.equal(locales[3], "und");
- Assert.equal(locales.length, 4);
+ Assert.equal(locales.length, 3);
Services.prefs.clearUserPref(PREF_REQUESTED_LOCALES);