Commit 3059138b authored by littledan's avatar littledan Committed by Commit bot

[intl] Fall back on an invalid default locale to "und"

The default locale can be changed in some environments with environment
variables. These environment variables used to allow the system to get
into an invalid state, where the default locale was unsupported. This
patch detects that case and falls back to "und" as the default locale
if there is an Intl service which does not support the locale that ICU
reports as the default. It also has a slight cleanup of surrounding code.

I haven't gone through the work to set up an automated test, as triggering
the case requires setting environment variables, which our tests don't tend
to do, but I tested interactively as follows:

dehrenberg@dehrenberg:~/v8/v8$ LC_ALL="tlh-FR" rlwrap out/Release/d8
V8 version 5.7.0 (candidate)
d8> new Intl.NumberFormat("foo").resolvedOptions().locale
"und"
d8> new Intl.NumberFormat().resolvedOptions().locale
"und"
d8>

dehrenberg@dehrenberg:~/v8/v8$ LC_ALL="de" rlwrap out/Release/d8
V8 version 5.7.0 (candidate)
d8> new Intl.NumberFormat().resolvedOptions().locale
"de"
d8> new Intl.NumberFormat("foo").resolvedOptions().locale
"de"
d8>

BUG=v8:4216

Review-Url: https://codereview.chromium.org/2646593002
Cr-Commit-Position: refs/heads/master@{#43253}
parent ae8f2820
......@@ -153,6 +153,13 @@ var DEFAULT_ICU_LOCALE = UNDEFINED;
function GetDefaultICULocaleJS() {
if (IS_UNDEFINED(DEFAULT_ICU_LOCALE)) {
DEFAULT_ICU_LOCALE = %GetDefaultICULocale();
// Check that this is a valid default, otherwise fall back to "und"
for (let service in AVAILABLE_LOCALES) {
if (IS_UNDEFINED(getAvailableLocalesOf(service)[DEFAULT_ICU_LOCALE])) {
DEFAULT_ICU_LOCALE = "und";
break;
}
}
}
return DEFAULT_ICU_LOCALE;
}
......@@ -298,19 +305,16 @@ function supportedLocalesOf(service, locales, options) {
var requestedLocales = initializeLocaleList(locales);
// Cache these, they don't ever change per service.
if (IS_UNDEFINED(AVAILABLE_LOCALES[service])) {
AVAILABLE_LOCALES[service] = getAvailableLocalesOf(service);
}
var availableLocales = getAvailableLocalesOf(service);
// Use either best fit or lookup algorithm to match locales.
if (matcher === 'best fit') {
return initializeLocaleList(bestFitSupportedLocalesOf(
requestedLocales, AVAILABLE_LOCALES[service]));
requestedLocales, availableLocales));
}
return initializeLocaleList(lookupSupportedLocalesOf(
requestedLocales, AVAILABLE_LOCALES[service]));
requestedLocales, availableLocales));
}
......@@ -437,17 +441,14 @@ function lookupMatcher(service, requestedLocales) {
throw %make_error(kWrongServiceType, service);
}
// Cache these, they don't ever change per service.
if (IS_UNDEFINED(AVAILABLE_LOCALES[service])) {
AVAILABLE_LOCALES[service] = getAvailableLocalesOf(service);
}
var availableLocales = getAvailableLocalesOf(service);
for (var i = 0; i < requestedLocales.length; ++i) {
// Remove all extensions.
var locale = %RegExpInternalReplace(
GetAnyExtensionRE(), requestedLocales[i], '');
do {
if (!IS_UNDEFINED(AVAILABLE_LOCALES[service][locale])) {
if (!IS_UNDEFINED(availableLocales[locale])) {
// Return the resolved locale and extension.
var extensionMatch = %regexp_internal_match(
GetUnicodeExtensionRE(), requestedLocales[i]);
......@@ -658,6 +659,11 @@ function getOptimalLanguageTag(original, resolved) {
* that is supported. This is required by the spec.
*/
function getAvailableLocalesOf(service) {
// Cache these, they don't ever change per service.
if (!IS_UNDEFINED(AVAILABLE_LOCALES[service])) {
return AVAILABLE_LOCALES[service];
}
var available = %AvailableLocalesOf(service);
for (var i in available) {
......@@ -672,6 +678,8 @@ function getAvailableLocalesOf(service) {
}
}
AVAILABLE_LOCALES[service] = available;
return available;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment