зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset c3e43b7b1376 (bug 1607052) for causing leaks CLOSED TREE
This commit is contained in:
Родитель
3d7d919746
Коммит
27e963773a
|
@ -45,15 +45,43 @@ mozilla::StaticRefPtr<LocaleService> LocaleService::sInstance;
|
|||
*
|
||||
* Example: "ja-JP-mac" -> "ja-JP-macos"
|
||||
*
|
||||
* The canonical Unicode Language Identifier form should be used for
|
||||
* all calls to Intl APIs.
|
||||
* The BCP47 form should be used for all calls to ICU/Intl APIs.
|
||||
* The canonical form is used for all internal operations.
|
||||
*/
|
||||
bool LocaleService::CanonicalizeLanguageId(nsACString& aLocale) {
|
||||
bool result;
|
||||
auto loc = unic_langid_new(&aLocale, &result);
|
||||
unic_langid_as_string(loc, &aLocale);
|
||||
return result;
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -65,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);
|
||||
}
|
||||
|
@ -393,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);
|
||||
}
|
||||
|
||||
|
@ -589,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;
|
||||
}
|
||||
|
@ -639,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;
|
||||
}
|
||||
|
|
|
@ -104,21 +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);
|
||||
/**
|
||||
* This method should only be called in the client mode.
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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(
|
||||
|
|
|
@ -15,11 +15,6 @@ pub unsafe extern "C" fn unic_langid_new(
|
|||
let langid = 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)
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче