Skip to content

Commit

Permalink
Backed out changeset 4f406ca4f899 (bug 1607052) for causing xpcshell …
Browse files Browse the repository at this point in the history
…failures in test_localeService.js CLOSED TREE

--HG--
extra : rebase_source : c91f40748db91ac3563bd0215f4e707912553502
  • Loading branch information
nerli1 committed Feb 21, 2020
1 parent 71b1d98 commit 04fcf27
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 76 deletions.
53 changes: 49 additions & 4 deletions intl/locale/LocaleService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,51 @@ 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.
Expand All @@ -48,7 +93,7 @@ static void SplitLocaleListStringIntoArray(nsACString& str,
if (str.Length() > 0) {
for (const nsACString& part : str.Split(',')) {
nsAutoCString locale(part);
if (LocaleService::CanonicalizeLanguageId(locale)) {
if (SanitizeForBCP47(locale, true)) {
if (!aRetVal.Contains(locale)) {
aRetVal.AppendElement(locale);
}
Expand Down Expand Up @@ -376,7 +421,7 @@ LocaleService::GetDefaultLocale(nsACString& aRetVal) {
locale.Trim(" \t\n\r");
// This should never be empty.
MOZ_ASSERT(!locale.IsEmpty());
if (CanonicalizeLanguageId(locale)) {
if (SanitizeForBCP47(locale, true)) {
mDefaultLocale.Assign(locale);
}

Expand Down Expand Up @@ -572,7 +617,7 @@ LocaleService::SetRequestedLocales(const nsTArray<nsCString>& aRequested) {

for (auto& req : aRequested) {
nsAutoCString locale(req);
if (!CanonicalizeLanguageId(locale)) {
if (!SanitizeForBCP47(locale, true)) {
NS_ERROR("Invalid language tag provided to SetRequestedLocales!");
return NS_ERROR_INVALID_ARG;
}
Expand Down Expand Up @@ -622,7 +667,7 @@ LocaleService::SetAvailableLocales(const nsTArray<nsCString>& aAvailable) {

for (auto& avail : aAvailable) {
nsAutoCString locale(avail);
if (!CanonicalizeLanguageId(locale)) {
if (!SanitizeForBCP47(locale, true)) {
NS_ERROR("Invalid language tag provided to SetAvailableLocales!");
return NS_ERROR_INVALID_ARG;
}
Expand Down
18 changes: 0 additions & 18 deletions intl/locale/LocaleService.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include "nsString.h"
#include "nsTArray.h"
#include "nsWeakReference.h"
#include "MozLocaleBindings.h"

#include "mozILocaleService.h"

Expand Down Expand Up @@ -105,23 +104,6 @@ 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.
*
Expand Down
18 changes: 14 additions & 4 deletions intl/locale/OSPreferences.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,19 @@ void OSPreferences::Refresh() {
* It returns true if the canonicalization was successful.
*/
bool OSPreferences::CanonicalizeLanguageTag(nsCString& aLoc) {
return LocaleService::CanonicalizeLanguageId(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;
}

/**
Expand Down Expand Up @@ -279,9 +291,7 @@ OSPreferences::GetRegionalPrefsLocales(nsTArray<nsCString>& aRetVal) {
return NS_OK;
}

// If we failed to read regional prefs locales,
// use system locales as last fallback.
return GetSystemLocales(aRetVal);
return NS_ERROR_FAILURE;
}

static OSPreferences::DateTimeFormatStyle ToDateTimeFormatStyle(
Expand Down
33 changes: 6 additions & 27 deletions intl/locale/rust/unic-langid-ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,18 @@
use nsstring::nsACString;
use nsstring::nsCString;
use thin_vec::ThinVec;
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
}

pub use unic_langid::LanguageIdentifier;

#[no_mangle]
pub unsafe extern "C" fn unic_langid_new(
name: &nsACString,
ret_val: &mut bool,
) -> *mut LanguageIdentifier {
let langid = new_langid_for_mozilla(name);
let langid = if name.eq_ignore_ascii_case(b"ja-jp-mac") {
"ja-JP-macos".parse()
} else {
LanguageIdentifier::from_bytes(name)
};

*ret_val = langid.is_ok();
Box::into_raw(Box::new(langid.unwrap_or_default()))
Expand Down
23 changes: 0 additions & 23 deletions intl/locale/tests/gtest/TestLocaleService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,6 @@

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;
Expand Down

0 comments on commit 04fcf27

Please sign in to comment.