[Intl] Throws exception on grandfather and private locale

Bug: v8:9613
Change-Id: Ie91a5bd39c82b6baf33fd84dee8420d2c4a5f504
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1803783
Commit-Queue: Frank Tang <ftang@chromium.org>
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63815}
This commit is contained in:
Frank Tang 2019-09-16 13:16:21 -07:00 committed by Commit Bot
parent 428c2a383d
commit 133219ad5c
12 changed files with 23 additions and 35 deletions

View File

@ -20,6 +20,7 @@
#include "src/objects/js-collator-inl.h"
#include "src/objects/js-date-time-format-inl.h"
#include "src/objects/js-locale-inl.h"
#include "src/objects/js-locale.h"
#include "src/objects/js-number-format-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/property-descriptor.h"
@ -784,6 +785,11 @@ Maybe<std::string> Intl::CanonicalizeLanguageTag(Isolate* isolate,
}
std::string locale(locale_str->ToCString().get());
if (!IsStructurallyValidLanguageTag(locale)) {
THROW_NEW_ERROR_RETURN_VALUE(
isolate, NewRangeError(MessageTemplate::kLocaleBadParameters),
Nothing<std::string>());
}
return Intl::CanonicalizeLanguageTag(isolate, locale);
}
@ -2096,5 +2102,9 @@ MaybeHandle<String> Intl::FormattedToString(
return Intl::ToString(isolate, result);
}
bool Intl::IsStructurallyValidLanguageTag(const std::string& tag) {
return JSLocale::StartsWithUnicodeLanguageId(tag);
}
} // namespace internal
} // namespace v8

View File

@ -337,6 +337,8 @@ class Intl {
static const std::set<std::string>& GetAvailableLocalesForLocale();
static const std::set<std::string>& GetAvailableLocalesForDateFormat();
static bool IsStructurallyValidLanguageTag(const std::string& tag);
};
} // namespace internal

View File

@ -168,10 +168,11 @@ bool IsUnicodeVariantSubtag(const std::string& value) {
bool IsExtensionSingleton(const std::string& value) {
return IsAlphanum(value, 1, 1);
}
} // namespace
// TODO(ftang) Replace the following check w/ icu::LocaleBuilder
// once ICU64 land in March 2019.
bool StartsWithUnicodeLanguageId(const std::string& value) {
bool JSLocale::StartsWithUnicodeLanguageId(const std::string& value) {
// unicode_language_id =
// unicode_language_subtag (sep unicode_script_subtag)?
// (sep unicode_region_subtag)? (sep unicode_variant_subtag)* ;
@ -207,6 +208,7 @@ bool StartsWithUnicodeLanguageId(const std::string& value) {
return true;
}
namespace {
Maybe<bool> ApplyOptionsToTag(Isolate* isolate, Handle<String> tag,
Handle<JSReceiver> options,
icu::LocaleBuilder* builder) {
@ -223,7 +225,7 @@ Maybe<bool> ApplyOptionsToTag(Isolate* isolate, Handle<String> tag,
CHECK_NOT_NULL(*bcp47_tag);
// 2. If IsStructurallyValidLanguageTag(tag) is false, throw a RangeError
// exception.
if (!StartsWithUnicodeLanguageId(*bcp47_tag)) {
if (!JSLocale::StartsWithUnicodeLanguageId(*bcp47_tag)) {
return Just(false);
}
UErrorCode status = U_ZERO_ERROR;

View File

@ -49,6 +49,9 @@ class JSLocale : public JSObject {
static Handle<String> ToString(Isolate* isolate, Handle<JSLocale> locale);
static std::string ToString(Handle<JSLocale> locale);
// Help function to validate locale by other Intl objects.
static bool StartsWithUnicodeLanguageId(const std::string& value);
DECL_CAST(JSLocale)
DECL_ACCESSORS(icu_locale, Managed<icu::Locale>)

View File

@ -125,9 +125,6 @@ assertEquals("abci\u0307", "aBcI\u0307".toLowerCase());
// Anything other than 'tr' and 'az' behave like root for U+0307.
assertEquals("abci\u0307", "aBcI\u0307".toLocaleLowerCase("fil"));
assertEquals("abci\u0307", "aBcI\u0307".toLocaleLowerCase("zh-Hant-TW"));
assertEquals("abci\u0307", "aBcI\u0307".toLocaleLowerCase("i-klingon"));
assertEquals("abci\u0307", "aBcI\u0307".toLocaleLowerCase("i-enochian"));
assertEquals("abci\u0307", "aBcI\u0307".toLocaleLowerCase("x-foobar"));
// Up to 8 chars are allowed for the primary language tag in BCP 47.
assertEquals("abci\u0307", "aBcI\u0307".toLocaleLowerCase("longlang"));

View File

@ -8,18 +8,8 @@
// v8 works around that ICU issue.
// See https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry .
["cel-gaulish", "cel-gaulish"],
["i-default", "i-default"],
["i-mingo", "i-mingo"],
["i-enochian", "i-enochian"],
["zh-min", "zh-min"],
// Matching should be case-insensitive.
["I-default", "i-default"],
["i-DEFAULT", "i-default"],
["I-DEFAULT", "i-default"],
["i-DEfauLT", "i-default"],
["zh-Min", "zh-min"],
["Zh-min", "zh-min"],
].forEach(([inputLocale, expectedLocale]) => {
const canonicalLocales = Intl.getCanonicalLocales(inputLocale);
assertEquals(canonicalLocales.length, 1);

View File

@ -9,8 +9,6 @@
// Matching should be case-insensitive.
["sgn-De", "gsg"],
["sgn-BE-FR", "sfb"],
["Sgn-bE-Fr", "sfb"],
// deprecated region tag
["und-Latn-dd", "und-Latn-DE"],

View File

@ -83,16 +83,15 @@ for (const service of services) {
privateuseLocale = service.supportedLocalesOf("en-US-x-twain");
assertEquals("en-US-x-twain", privateuseLocale[0]);
privateuseLocale2 = service.supportedLocalesOf("x-twain");
assertEquals(undefined, privateuseLocale2[0]);
assertThrows(() => service.supportedLocalesOf("x-twain"), RangeError);
if (service != Intl.PluralRules) {
grandfatheredLocale = service.supportedLocalesOf("art-lojban");
assertEquals(undefined, grandfatheredLocale[0]);
}
grandfatheredLocale2 = service.supportedLocalesOf("i-pwn");
assertEquals(undefined, grandfatheredLocale2[0]);
assertThrows(() => service.supportedLocalesOf("x-pwn"), RangeError);
unicodeInPrivateuseLocale = service.supportedLocalesOf(
"en-US-x-u-co-phonebk"

View File

@ -144,7 +144,3 @@ assertEquals(
assertEquals(
'ar',
(new Intl.ListFormat(['xyz', 'ar'])).resolvedOptions().locale);
assertEquals(
'ar',
(new Intl.ListFormat(['i-default', 'ar'])).resolvedOptions().locale);

View File

@ -6,5 +6,5 @@ Object.prototype.__defineGetter__('x', function () {
return -2147483648;
});
var f = ["x-u-foo"];
var f = ["en-US"];
Intl.NumberFormat(f);

View File

@ -156,7 +156,3 @@ assertEquals(
assertThrows(() =>
Intl.RelativeTimeFormat.prototype.resolvedOptions.call(receiver), TypeError);
}
assertEquals(
'ar',
(new Intl.RelativeTimeFormat(['i-default', 'ar'])).resolvedOptions().locale);

View File

@ -530,20 +530,15 @@
# https://bugs.chromium.org/p/v8/issues/detail?id=9613
'intl402/Intl/getCanonicalLocales/canonicalized-tags': [FAIL],
'intl402/Intl/getCanonicalLocales/grandfathered': [FAIL],
'intl402/Intl/getCanonicalLocales/invalid-tags': [FAIL],
'intl402/Intl/getCanonicalLocales/non-iana-canon': [FAIL],
'intl402/Intl/getCanonicalLocales/preferred-grandfathered': [FAIL],
'intl402/Intl/getCanonicalLocales/preferred-variant': [FAIL],
'intl402/language-tags-invalid': [FAIL],
'intl402/ListFormat/constructor/constructor/locales-valid': [FAIL],
'intl402/Locale/constructor-non-iana-canon': [FAIL],
'intl402/Locale/constructor-options-region-valid': [FAIL],
'intl402/Locale/constructor-tag': [FAIL],
'intl402/Locale/getters': [FAIL],
'intl402/Locale/likely-subtags-grandfathered': [FAIL],
'intl402/PluralRules/prototype/resolvedOptions/order': [FAIL],
'intl402/RelativeTimeFormat/constructor/constructor/locales-valid': [FAIL],
'intl402/Segmenter/constructor/constructor/locales-valid': [FAIL],
######################## NEEDS INVESTIGATION ###########################