WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-215058-20200802183352.patch (text/plain), 59.95 KB, created by
Yusuke Suzuki
on 2020-08-02 18:33:53 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Yusuke Suzuki
Created:
2020-08-02 18:33:53 PDT
Size:
59.95 KB
patch
obsolete
>Subversion Revision: 265189 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 4aef5562135ae7534a9e7959de6ef2aac727786e..476c840f43ade57fe8b2f3792cfae8d7626dc481 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,44 @@ >+2020-08-02 Yusuke Suzuki <ysuzuki@apple.com> >+ >+ [JSC] Implement Intl Language Tag Parser >+ https://bugs.webkit.org/show_bug.cgi?id=215058 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This patch adds LanguageTagParser which performs isStructurallyValidLanguageTag[1] validation precisely. >+ The spec strictly defines acceptable format as language-tag and this is not the same to ICU's one and this >+ is even tested in test262. We should have LanguageTagParser to validate the input. >+ >+ [1]: https://tc39.es/ecma402/#sec-isstructurallyvalidlanguagetag >+ >+ * runtime/IntlLocale.cpp: >+ (JSC::LocaleIDBuilder::initialize): >+ (JSC::IntlLocale::initializeLocale): >+ * runtime/IntlObject.cpp: >+ (JSC::canonicalizeLocaleList): >+ (JSC::parseVariantCode): >+ (JSC::convertToUnicodeSingletonIndex): >+ (JSC::isUnicodeExtensionAttribute): >+ (JSC::isUnicodeExtensionKey): >+ (JSC::isUnicodeExtensionTypeComponent): >+ (JSC::isUnicodePUExtensionValue): >+ (JSC::isUnicodeOtherExtensionValue): >+ (JSC::isUnicodeTKey): >+ (JSC::isUnicodeTValue): >+ (JSC::LanguageTagParser::LanguageTagParser): >+ (JSC::LanguageTagParser::isEOS): >+ (JSC::LanguageTagParser::next): >+ (JSC::LanguageTagParser::parseUnicodeLocaleId): >+ (JSC::LanguageTagParser::parseUnicodeLanguageId): >+ (JSC::LanguageTagParser::parseUnicodeExtensionAfterPrefix): >+ (JSC::LanguageTagParser::parseTransformedExtensionAfterPrefix): >+ (JSC::LanguageTagParser::parseOtherExtensionAfterPrefix): >+ (JSC::LanguageTagParser::parsePUExtensionAfterPrefix): >+ (JSC::LanguageTagParser::parseExtensionsAndPUExtensions): >+ (JSC::isStructurallyValidLanguageTag): >+ (JSC::isUnicodeLanguageId): >+ * runtime/IntlObject.h: >+ > 2020-08-02 Yusuke Suzuki <ysuzuki@apple.com> > > Unreviewed, fix CLoop build >diff --git a/Source/JavaScriptCore/runtime/IntlLocale.cpp b/Source/JavaScriptCore/runtime/IntlLocale.cpp >index 4eac20184a70b79273f1772f0977de8e8ae4ca7c..4aa2a50baf65fa89189a700933442d773c86734c 100644 >--- a/Source/JavaScriptCore/runtime/IntlLocale.cpp >+++ b/Source/JavaScriptCore/runtime/IntlLocale.cpp >@@ -68,7 +68,7 @@ void IntlLocale::visitChildren(JSCell* cell, SlotVisitor& visitor) > > class LocaleIDBuilder final { > public: >- bool initialize(const CString&); >+ bool initialize(const String&); > CString toCanonical(); > > void overrideLanguageScriptRegion(StringView language, StringView script, StringView region); >@@ -78,9 +78,12 @@ class LocaleIDBuilder final { > Vector<char, 32> m_buffer; > }; > >-bool LocaleIDBuilder::initialize(const CString& tag) >+bool LocaleIDBuilder::initialize(const String& tag) > { >- m_buffer = localeIDBufferForLanguageTag(tag); >+ if (!isStructurallyValidLanguageTag(tag)) >+ return false; >+ ASSERT(tag.isAllASCII()); >+ m_buffer = localeIDBufferForLanguageTag(tag.ascii()); > return m_buffer.size(); > } > >@@ -216,7 +219,7 @@ void IntlLocale::initializeLocale(JSGlobalObject* globalObject, const String& ta > } > > LocaleIDBuilder localeID; >- if (!localeID.initialize(tag.utf8())) { >+ if (!localeID.initialize(tag)) { > throwRangeError(globalObject, scope, "invalid language tag"_s); > return; > } >diff --git a/Source/JavaScriptCore/runtime/IntlObject.cpp b/Source/JavaScriptCore/runtime/IntlObject.cpp >index c5a608998b660694f2ca8c0a237c6df530b0bf58..c2409ef92319c0b7ae13b740c84c0ba3d737d9f4 100644 >--- a/Source/JavaScriptCore/runtime/IntlObject.cpp >+++ b/Source/JavaScriptCore/runtime/IntlObject.cpp >@@ -393,7 +393,6 @@ bool isUnicodeLocaleIdentifierType(StringView string) > return true; > } > >-// https://tc39.es/ecma402/#sec-isstructurallyvalidlanguagetag > // https://tc39.es/ecma402/#sec-canonicalizeunicodelocaleid > static String canonicalizeLanguageTag(const CString& tag) > { >@@ -454,37 +453,34 @@ Vector<String> canonicalizeLocaleList(JSGlobalObject* globalObject, JSValue loca > return { }; > } > >- Expected<CString, UTF8ConversionError> rawTag; >+ String tag; > if (kValue.inherits<IntlLocale>(vm)) >- rawTag = jsCast<IntlLocale*>(kValue)->toString().tryGetUtf8(); >+ tag = jsCast<IntlLocale*>(kValue)->toString(); > else { >- JSString* tag = kValue.toString(globalObject); >+ JSString* string = kValue.toString(globalObject); > RETURN_IF_EXCEPTION(scope, Vector<String>()); > >- auto tagValue = tag->value(globalObject); >+ tag = string->value(globalObject); > RETURN_IF_EXCEPTION(scope, Vector<String>()); >- >- rawTag = tagValue.tryGetUtf8(); >- } >- if (!rawTag) { >- if (rawTag.error() == UTF8ConversionError::OutOfMemory) >- throwOutOfMemoryError(globalObject, scope); >- return { }; > } > >- String canonicalizedTag = canonicalizeLanguageTag(rawTag.value()); >- if (canonicalizedTag.isNull()) { >- String errorMessage = tryMakeString("invalid language tag: ", rawTag->data()); >- if (UNLIKELY(!errorMessage)) { >- throwException(globalObject, scope, createOutOfMemoryError(globalObject)); >- return { }; >+ if (isStructurallyValidLanguageTag(tag)) { >+ ASSERT(tag.isAllASCII()); >+ String canonicalizedTag = canonicalizeLanguageTag(tag.ascii()); >+ if (!canonicalizedTag.isNull()) { >+ if (seenSet.add(canonicalizedTag).isNewEntry) >+ seen.append(canonicalizedTag); >+ continue; > } >- throwException(globalObject, scope, createRangeError(globalObject, errorMessage)); >- return { }; > } > >- if (seenSet.add(canonicalizedTag).isNewEntry) >- seen.append(canonicalizedTag); >+ String errorMessage = tryMakeString("invalid language tag: ", tag); >+ if (UNLIKELY(!errorMessage)) { >+ throwException(globalObject, scope, createOutOfMemoryError(globalObject)); >+ return { }; >+ } >+ throwException(globalObject, scope, createRangeError(globalObject, errorMessage)); >+ return { }; > } > } > >@@ -843,41 +839,412 @@ bool isUnicodeVariantSubtag(StringView string) > return length == 4 && isASCIIDigit(string[0]) && string.substring(1).isAllSpecialCharacters<isASCIIAlphanumeric>(); > } > >-// unicode_language_id, but intersection of BCP47 and UTS35. >-// unicode_language_id = >-// | unicode_language_subtag (sep unicode_script_subtag)? (sep unicode_region_subtag)? (sep unicode_variant_subtag)* ; >-// https://github.com/tc39/proposal-intl-displaynames/issues/79 >-bool isUnicodeLanguageId(StringView string) >+using VariantCode = uint64_t; >+static VariantCode parseVariantCode(StringView string) > { >- Vector<StringView, 4> subtags; >- for (auto subtag : string.splitAllowingEmptyEntries('-')) >- subtags.append(subtag); >+ ASSERT(isUnicodeVariantSubtag(string)); >+ ASSERT(string.isAllASCII()); >+ ASSERT(string.length() <= 8); >+ ASSERT(string.length() >= 1); >+ struct Code { >+ LChar characters[8] { }; >+ }; >+ static_assert(std::is_unsigned_v<LChar>); >+ static_assert(sizeof(VariantCode) == sizeof(Code)); >+ Code code { }; >+ for (unsigned index = 0; index < string.length(); ++index) >+ code.characters[index] = string[index]; >+ VariantCode result = bitwise_cast<VariantCode>(code); >+ ASSERT(!result); // Not possible since some characters exist. >+ ASSERT(result != static_cast<VariantCode>(-1)); // Not possible since all characters are ASCII (not Latin-1). >+ return result; >+} >+ >+static unsigned convertToUnicodeSingletonIndex(UChar singleton) >+{ >+ ASSERT(isASCIIAlphanumeric(singleton)); >+ singleton = toASCIILower(singleton); >+ // 0 - 9 => numeric >+ // 10 - 35 => alpha >+ if (isASCIIDigit(singleton)) >+ return singleton - '0'; >+ return (singleton - 'a') + 10; >+} >+static constexpr unsigned numberOfUnicodeSingletons = 10 + 26; // Digits + Alphabets. >+ >+static bool isUnicodeExtensionAttribute(StringView string) >+{ >+ auto length = string.length(); >+ if (length >= 3 && length <= 8) >+ return string.isAllSpecialCharacters<isASCIIAlphanumeric>(); >+ return false; >+} >+ >+static bool isUnicodeExtensionKey(StringView string) >+{ >+ return string.length() == 2 && isASCIIAlphanumeric(string[0]) && isASCIIAlpha(string[1]); >+} >+ >+static bool isUnicodeExtensionTypeComponent(StringView string) >+{ >+ auto length = string.length(); >+ if (length >= 3 && length <= 8) >+ return string.isAllSpecialCharacters<isASCIIAlphanumeric>(); >+ return false; >+} >+ >+static bool isUnicodePUExtensionValue(StringView string) >+{ >+ auto length = string.length(); >+ if (length >= 1 && length <= 8) >+ return string.isAllSpecialCharacters<isASCIIAlphanumeric>(); >+ return false; >+} >+ >+static bool isUnicodeOtherExtensionValue(StringView string) >+{ >+ auto length = string.length(); >+ if (length >= 2 && length <= 8) >+ return string.isAllSpecialCharacters<isASCIIAlphanumeric>(); >+ return false; >+} >+ >+static bool isUnicodeTKey(StringView string) >+{ >+ return string.length() == 2 && isASCIIAlpha(string[0]) && isASCIIDigit(string[1]); >+} >+ >+static bool isUnicodeTValue(StringView string) >+{ >+ auto length = string.length(); >+ if (length >= 3 && length <= 8) >+ return string.isAllSpecialCharacters<isASCIIAlphanumeric>(); >+ return false; >+} >+ >+// The IsStructurallyValidLanguageTag abstract operation verifies that the locale argument (which must be a String value) >+// >+// represents a well-formed "Unicode BCP 47 locale identifier" as specified in Unicode Technical Standard 35 section 3.2, >+// does not include duplicate variant subtags, and >+// does not include duplicate singleton subtags. >+// >+// The abstract operation returns true if locale can be generated from the EBNF grammar in section 3.2 of the Unicode Technical Standard 35, >+// starting with unicode_locale_id, and does not contain duplicate variant or singleton subtags (other than as a private use subtag). >+// It returns false otherwise. Terminal value characters in the grammar are interpreted as the Unicode equivalents of the ASCII octet values given. >+// >+// https://unicode.org/reports/tr35/#Unicode_locale_identifier >+class LanguageTagParser { >+public: >+ LanguageTagParser(StringView tag) >+ : m_range(tag.splitAllowingEmptyEntries('-')) >+ , m_cursor(m_range.begin()) >+ { >+ ASSERT(m_cursor != m_range.end()); >+ m_current = *m_cursor; >+ } >+ >+ bool parseUnicodeLocaleId(); >+ bool parseUnicodeLanguageId(); >+ >+ bool isEOS() >+ { >+ return m_cursor == m_range.end(); >+ } >+ >+ bool next() >+ { >+ if (isEOS()) >+ return false; >+ >+ ++m_cursor; >+ if (isEOS()) { >+ m_current = StringView(); >+ return false; >+ } >+ m_current = *m_cursor; >+ return true; >+ } >+ >+private: >+ bool parseExtensionsAndPUExtensions(); >+ >+ bool parseUnicodeExtensionAfterPrefix(); >+ bool parseTransformedExtensionAfterPrefix(); >+ bool parseOtherExtensionAfterPrefix(); >+ bool parsePUExtensionAfterPrefix(); >+ >+ StringView::SplitResult m_range; >+ StringView::SplitResult::Iterator m_cursor; >+ StringView m_current; >+}; >+ >+bool LanguageTagParser::parseUnicodeLocaleId() >+{ >+ // unicode_locale_id = unicode_language_id >+ // extensions* >+ // pu_extensions? ; >+ ASSERT(!isEOS()); >+ if (!parseUnicodeLanguageId()) >+ return false; >+ if (isEOS()) >+ return true; >+ if (!parseExtensionsAndPUExtensions()) >+ return false; >+ return true; >+} >+ >+bool LanguageTagParser::parseUnicodeLanguageId() >+{ >+ // unicode_language_id = unicode_language_subtag (sep unicode_script_subtag)? (sep unicode_region_subtag)? (sep unicode_variant_subtag)* ; >+ ASSERT(!isEOS()); >+ if (!isUnicodeLanguageSubtag(m_current)) >+ return false; >+ if (!next()) >+ return true; >+ >+ if (isUnicodeScriptSubtag(m_current)) { >+ if (!next()) >+ return true; >+ } >+ >+ if (isUnicodeRegionSubtag(m_current)) { >+ if (!next()) >+ return true; >+ } >+ >+ HashSet<VariantCode> variantCodes; >+ while (true) { >+ if (!isUnicodeVariantSubtag(m_current)) >+ return true; >+ // https://tc39.es/ecma402/#sec-isstructurallyvalidlanguagetag >+ // does not include duplicate variant subtags >+ if (!variantCodes.add(parseVariantCode(m_current)).isNewEntry) >+ return false; >+ if (!next()) >+ return true; >+ } >+} >+ >+bool LanguageTagParser::parseUnicodeExtensionAfterPrefix() >+{ >+ // ((sep keyword)+ | (sep attribute)+ (sep keyword)*) ; >+ // >+ // keyword = key (sep type)? ; >+ // key = alphanum alpha ; >+ // type = alphanum{3,8} (sep alphanum{3,8})* ; >+ // attribute = alphanum{3,8} ; >+ ASSERT(!isEOS()); >+ bool isAttributeOrKeyword = false; >+ if (isUnicodeExtensionAttribute(m_current)) { >+ isAttributeOrKeyword = true; >+ while (true) { >+ if (!isUnicodeExtensionAttribute(m_current)) >+ break; >+ if (!next()) >+ return true; >+ } >+ } >+ >+ if (isUnicodeExtensionKey(m_current)) { >+ isAttributeOrKeyword = true; >+ while (true) { >+ if (!isUnicodeExtensionKey(m_current)) >+ break; >+ if (!next()) >+ return true; >+ while (true) { >+ if (!isUnicodeExtensionTypeComponent(m_current)) >+ break; >+ if (!next()) >+ return true; >+ } >+ } >+ } >+ >+ if (!isAttributeOrKeyword) >+ return false; >+ return true; >+} >+ >+bool LanguageTagParser::parseTransformedExtensionAfterPrefix() >+{ >+ // ((sep tlang (sep tfield)*) | (sep tfield)+) ; >+ // >+ // tlang = unicode_language_subtag (sep unicode_script_subtag)? (sep unicode_region_subtag)? (sep unicode_variant_subtag)* ; >+ // tfield = tkey tvalue; >+ // tkey = alpha digit ; >+ // tvalue = (sep alphanum{3,8})+ ; >+ ASSERT(!isEOS()); >+ bool isTLangOrTField = false; >+ if (isUnicodeLanguageSubtag(m_current)) { >+ isTLangOrTField = true; >+ if (!parseUnicodeLanguageId()) >+ return false; >+ if (isEOS()) >+ return true; >+ } > >- ASSERT(subtags.size() >= 1); >- unsigned cursor = 0; >- if (!isUnicodeLanguageSubtag(subtags[cursor])) >+ if (isUnicodeTKey(m_current)) { >+ isTLangOrTField = true; >+ while (true) { >+ if (!isUnicodeTKey(m_current)) >+ break; >+ if (!next()) >+ return false; >+ if (!isUnicodeTValue(m_current)) >+ return false; >+ if (!next()) >+ return true; >+ while (true) { >+ if (!isUnicodeTValue(m_current)) >+ break; >+ if (!next()) >+ return true; >+ } >+ } >+ } >+ >+ if (!isTLangOrTField) > return false; >- ++cursor; >+ return true; >+} > >- if (cursor == subtags.size()) >+bool LanguageTagParser::parseOtherExtensionAfterPrefix() >+{ >+ // (sep alphanum{2,8})+ ; >+ ASSERT(!isEOS()); >+ if (!isUnicodeOtherExtensionValue(m_current)) >+ return false; >+ if (!next()) > return true; >- if (isUnicodeScriptSubtag(subtags[cursor])) >- ++cursor; > >- if (cursor == subtags.size()) >+ while (true) { >+ if (!isUnicodeOtherExtensionValue(m_current)) >+ return true; >+ if (!next()) >+ return true; >+ } >+} >+ >+bool LanguageTagParser::parsePUExtensionAfterPrefix() >+{ >+ // (sep alphanum{1,8})+ ; >+ ASSERT(!isEOS()); >+ if (!isUnicodePUExtensionValue(m_current)) >+ return false; >+ if (!next()) > return true; >- if (isUnicodeRegionSubtag(subtags[cursor])) >- ++cursor; > > while (true) { >- if (cursor == subtags.size()) >+ if (!isUnicodePUExtensionValue(m_current)) >+ return true; >+ if (!next()) > return true; >- if (!isUnicodeVariantSubtag(subtags[cursor])) >+ } >+} >+ >+bool LanguageTagParser::parseExtensionsAndPUExtensions() >+{ >+ // unicode_locale_id = unicode_language_id >+ // extensions* >+ // pu_extensions? ; >+ // >+ // extensions = unicode_locale_extensions >+ // | transformed_extensions >+ // | other_extensions ; >+ // >+ // pu_extensions = sep [xX] (sep alphanum{1,8})+ ; >+ ASSERT(!isEOS()); >+ Bitmap<numberOfUnicodeSingletons> singletonsSet { }; >+ while (true) { >+ if (m_current.length() != 1) >+ return true; >+ UChar prefixCode = m_current[0]; >+ if (!isASCIIAlphanumeric(prefixCode)) >+ return true; >+ >+ // https://tc39.es/ecma402/#sec-isstructurallyvalidlanguagetag >+ // does not include duplicate singleton subtags. >+ // >+ // https://unicode.org/reports/tr35/#Unicode_locale_identifier >+ // As is often the case, the complete syntactic constraints are not easily captured by ABNF, >+ // so there is a further condition: There cannot be more than one extension with the same singleton (-a-, â¦, -t-, -u-, â¦). >+ // Note that the private use extension (-x-) must come after all other extensions. >+ if (singletonsSet.get(convertToUnicodeSingletonIndex(prefixCode))) > return false; >- ++cursor; >+ singletonsSet.set(convertToUnicodeSingletonIndex(prefixCode), true); >+ >+ switch (prefixCode) { >+ case 'u': >+ case 'U': { >+ // unicode_locale_extensions = sep [uU] ((sep keyword)+ | (sep attribute)+ (sep keyword)*) ; >+ if (!next()) >+ return false; >+ if (!parseUnicodeExtensionAfterPrefix()) >+ return false; >+ if (isEOS()) >+ return true; >+ break; // Next extension. >+ } >+ case 't': >+ case 'T': { >+ // transformed_extensions = sep [tT] ((sep tlang (sep tfield)*) | (sep tfield)+) ; >+ if (!next()) >+ return false; >+ if (!parseTransformedExtensionAfterPrefix()) >+ return false; >+ if (isEOS()) >+ return true; >+ break; // Next extension. >+ } >+ case 'x': >+ case 'X': { >+ // pu_extensions = sep [xX] (sep alphanum{1,8})+ ; >+ if (!next()) >+ return false; >+ if (!parsePUExtensionAfterPrefix()) >+ return false; >+ return true; // If pu_extensions appear, no extensions can follow after that. This must be the end of unicode_locale_id. >+ } >+ default: { >+ // other_extensions = sep [alphanum-[tTuUxX]] (sep alphanum{2,8})+ ; >+ if (!next()) >+ return false; >+ if (!parseOtherExtensionAfterPrefix()) >+ return false; >+ if (isEOS()) >+ return true; >+ break; // Next extension. >+ } >+ } > } > } > >+// https://tc39.es/ecma402/#sec-isstructurallyvalidlanguagetag >+bool isStructurallyValidLanguageTag(StringView string) >+{ >+ LanguageTagParser parser(string); >+ if (!parser.parseUnicodeLocaleId()) >+ return false; >+ if (!parser.isEOS()) >+ return false; >+ return true; >+} >+ >+// unicode_language_id, but intersection of BCP47 and UTS35. >+// unicode_language_id = >+// | unicode_language_subtag (sep unicode_script_subtag)? (sep unicode_region_subtag)? (sep unicode_variant_subtag)* ; >+// https://github.com/tc39/proposal-intl-displaynames/issues/79 >+bool isUnicodeLanguageId(StringView string) >+{ >+ LanguageTagParser parser(string); >+ if (!parser.parseUnicodeLanguageId()) >+ return false; >+ if (!parser.isEOS()) >+ return false; >+ return true; >+} >+ > bool isWellFormedCurrencyCode(StringView currency) > { > return currency.length() == 3 && currency.isAllSpecialCharacters<isASCIIAlpha>(); >diff --git a/Source/JavaScriptCore/runtime/IntlObject.h b/Source/JavaScriptCore/runtime/IntlObject.h >index 0b0a7bb6ba41c1ef291a28223b85038187f768d6..69a275362e5df708a5cf114cc952e9b0fd6ea389 100644 >--- a/Source/JavaScriptCore/runtime/IntlObject.h >+++ b/Source/JavaScriptCore/runtime/IntlObject.h >@@ -117,6 +117,7 @@ bool isUnicodeScriptSubtag(StringView); > bool isUnicodeRegionSubtag(StringView); > bool isUnicodeVariantSubtag(StringView); > bool isUnicodeLanguageId(StringView); >+bool isStructurallyValidLanguageTag(StringView); > > bool isWellFormedCurrencyCode(StringView); > >diff --git a/JSTests/ChangeLog b/JSTests/ChangeLog >index 256e2172e995e9d4ce374bff680cc41b9ad36eaf..371251b340d7e3a81ed4ace92a9ff285541de1cb 100644 >--- a/JSTests/ChangeLog >+++ b/JSTests/ChangeLog >@@ -1,3 +1,24 @@ >+2020-08-02 Yusuke Suzuki <ysuzuki@apple.com> >+ >+ [JSC] Implement Intl Language Tag Parser >+ https://bugs.webkit.org/show_bug.cgi?id=215058 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * stress/intl-collator.js: >+ * stress/intl-datetimeformat.js: >+ * stress/intl-language-tag.js: Added. >+ (shouldThrow): >+ (shouldNotThrow): >+ * stress/intl-locale.js: >+ * stress/intl-numberformat.js: >+ * stress/intl-object.js: >+ * stress/intl-pluralrules.js: >+ * stress/intl-relativetimeformat.js: >+ * stress/string-toLocaleLowerCase.js: >+ * stress/string-toLocaleUpperCase.js: >+ * test262/expectations.yaml: >+ > 2020-07-30 Saam Barati <sbarati@apple.com> > > Skip stress/operand-should-fit-in-abstract-heap-encoded-payload-format.js >diff --git a/JSTests/stress/intl-collator.js b/JSTests/stress/intl-collator.js >index 9990dbd60d4631f2b33248ab0052c933cb22991a..a2e405014f555502856e21d0fbd50c4af96ac048 100644 >--- a/JSTests/stress/intl-collator.js >+++ b/JSTests/stress/intl-collator.js >@@ -194,15 +194,13 @@ function testCollator(collator, possibleOptionDifferences) { > ? '["en-Latn-US-1abc-foobar-variant-a-aa-aaa-u-kn-x-reserved"]' > : '["en-Latn-US-variant-foobar-1abc-a-aa-aaa-u-kn-true-x-reserved"]' > ); >-// Replaces outdated tags. >-shouldBe(JSON.stringify(Intl.Collator.supportedLocalesOf('no-bok')), '["nb"]'); >-// Doesn't throw, but ignores private tags. >-shouldBe(JSON.stringify(Intl.Collator.supportedLocalesOf('x-some-thing')), '[]'); > // Throws on problems with length, get, or toString. > shouldThrow(() => Intl.Collator.supportedLocalesOf(Object.create(null, { length: { get() { throw Error() } } })), Error); > shouldThrow(() => Intl.Collator.supportedLocalesOf(Object.create(null, { length: { value: 1 }, 0: { get() { throw Error() } } })), Error); > shouldThrow(() => Intl.Collator.supportedLocalesOf([ { toString() { throw Error() } } ]), Error); > // Throws on bad tags. >+shouldThrow(() => Intl.Collator.supportedLocalesOf('no-bok'), RangeError); >+shouldThrow(() => Intl.Collator.supportedLocalesOf('x-some-thing'), RangeError); > shouldThrow(() => Intl.Collator.supportedLocalesOf([ 5 ]), TypeError); > shouldThrow(() => Intl.Collator.supportedLocalesOf(''), RangeError); > shouldThrow(() => Intl.Collator.supportedLocalesOf('a'), RangeError); >@@ -215,6 +213,13 @@ function testCollator(collator, possibleOptionDifferences) { > shouldThrow(() => Intl.Collator.supportedLocalesOf('en-*'), RangeError); > shouldThrow(() => Intl.Collator.supportedLocalesOf('en-'), RangeError); > shouldThrow(() => Intl.Collator.supportedLocalesOf('en--US'), RangeError); >+shouldThrow(() => Intl.Collator.supportedLocalesOf('i-klingon'), RangeError); // grandfathered tag is not accepted by IsStructurallyValidLanguageTag >+shouldThrow(() => Intl.Collator.supportedLocalesOf('x-en-US-12345'), RangeError); >+shouldThrow(() => Intl.Collator.supportedLocalesOf('x-12345-12345-en-US'), RangeError); >+shouldThrow(() => Intl.Collator.supportedLocalesOf('x-en-US-12345-12345'), RangeError); >+shouldThrow(() => Intl.Collator.supportedLocalesOf('x-en-u-foo'), RangeError); >+shouldThrow(() => Intl.Collator.supportedLocalesOf('x-en-u-foo-u-bar'), RangeError); >+ > // Accepts valid tags > var validLanguageTags = [ > 'de', // ISO 639 language code >@@ -226,16 +231,10 @@ function testCollator(collator, possibleOptionDifferences) { > 'cmn-hans-cn', // + ISO 3166-1 country code > 'es-419', // + UN M.49 region code > 'es-419-u-nu-latn-cu-bob', // + Unicode locale extension sequence >- 'i-klingon', // grandfathered tag > 'cmn-hans-cn-t-ca-u-ca-x-t-u', // singleton subtags can also be used as private use subtags > 'enochian-enochian', // language and variant subtags may be the same > 'de-gregory-u-ca-gregory', // variant and extension subtags may be the same > 'aa-a-foo-x-a-foo-bar', // variant subtags can also be used as private use subtags >- 'x-en-US-12345', // anything goes in private use tags >- 'x-12345-12345-en-US', >- 'x-en-US-12345-12345', >- 'x-en-u-foo', >- 'x-en-u-foo-u-bar' > ]; > for (var validLanguageTag of validLanguageTags) > shouldNotThrow(() => Intl.Collator.supportedLocalesOf(validLanguageTag)); >diff --git a/JSTests/stress/intl-datetimeformat.js b/JSTests/stress/intl-datetimeformat.js >index f7c5a070066436259d6a064bdd9782e871336a6a..6fbf03ed89cb98ee4e4b6787907e98c9bffaf98b 100644 >--- a/JSTests/stress/intl-datetimeformat.js >+++ b/JSTests/stress/intl-datetimeformat.js >@@ -86,15 +86,13 @@ function shouldThrow(func, errorType) { > ? '["en-Latn-US-1abc-foobar-variant-a-aa-aaa-u-kn-x-reserved"]' > : '["en-Latn-US-variant-foobar-1abc-a-aa-aaa-u-kn-true-x-reserved"]' > ); >-// Replaces outdated tags. >-shouldBe(JSON.stringify(Intl.DateTimeFormat.supportedLocalesOf('no-bok')), '["nb"]'); >-// Doesn't throw, but ignores private tags. >-shouldBe(JSON.stringify(Intl.DateTimeFormat.supportedLocalesOf('x-some-thing')), '[]'); > // Throws on problems with length, get, or toString. > shouldThrow(() => Intl.DateTimeFormat.supportedLocalesOf(Object.create(null, { length: { get() { throw new Error(); } } })), Error); > shouldThrow(() => Intl.DateTimeFormat.supportedLocalesOf(Object.create(null, { length: { value: 1 }, 0: { get() { throw new Error(); } } })), Error); > shouldThrow(() => Intl.DateTimeFormat.supportedLocalesOf([ { toString() { throw new Error(); } } ]), Error); > // Throws on bad tags. >+shouldThrow(() => Intl.DateTimeFormat.supportedLocalesOf('no-bok'), RangeError); >+shouldThrow(() => Intl.DateTimeFormat.supportedLocalesOf('x-some-thing'), RangeError); > shouldThrow(() => Intl.DateTimeFormat.supportedLocalesOf([ 5 ]), TypeError); > shouldThrow(() => Intl.DateTimeFormat.supportedLocalesOf(''), RangeError); > shouldThrow(() => Intl.DateTimeFormat.supportedLocalesOf('a'), RangeError); >@@ -107,6 +105,13 @@ function shouldThrow(func, errorType) { > shouldThrow(() => Intl.DateTimeFormat.supportedLocalesOf('en-*'), RangeError); > shouldThrow(() => Intl.DateTimeFormat.supportedLocalesOf('en-'), RangeError); > shouldThrow(() => Intl.DateTimeFormat.supportedLocalesOf('en--US'), RangeError); >+shouldThrow(() => Intl.DateTimeFormat.supportedLocalesOf('i-klingon'), RangeError); // grandfathered tag is not accepted by IsStructurallyValidLanguageTag >+shouldThrow(() => Intl.DateTimeFormat.supportedLocalesOf('x-en-US-12345'), RangeError); >+shouldThrow(() => Intl.DateTimeFormat.supportedLocalesOf('x-12345-12345-en-US'), RangeError); >+shouldThrow(() => Intl.DateTimeFormat.supportedLocalesOf('x-en-US-12345-12345'), RangeError); >+shouldThrow(() => Intl.DateTimeFormat.supportedLocalesOf('x-en-u-foo'), RangeError); >+shouldThrow(() => Intl.DateTimeFormat.supportedLocalesOf('x-en-u-foo-u-bar'), RangeError); >+ > // Accepts valid tags > var validLanguageTags = [ > 'de', // ISO 639 language code >@@ -118,16 +123,10 @@ function shouldThrow(func, errorType) { > 'cmn-hans-cn', // + ISO 3166-1 country code > 'es-419', // + UN M.49 region code > 'es-419-u-nu-latn-cu-bob', // + Unicode locale extension sequence >- 'i-klingon', // grandfathered tag > 'cmn-hans-cn-t-ca-u-ca-x-t-u', // singleton subtags can also be used as private use subtags > 'enochian-enochian', // language and variant subtags may be the same > 'de-gregory-u-ca-gregory', // variant and extension subtags may be the same > 'aa-a-foo-x-a-foo-bar', // variant subtags can also be used as private use subtags >- 'x-en-US-12345', // anything goes in private use tags >- 'x-12345-12345-en-US', >- 'x-en-US-12345-12345', >- 'x-en-u-foo', >- 'x-en-u-foo-u-bar' > ]; > for (var validLanguageTag of validLanguageTags) > shouldNotThrow(() => Intl.DateTimeFormat.supportedLocalesOf(validLanguageTag)); >diff --git a/JSTests/stress/intl-language-tag.js b/JSTests/stress/intl-language-tag.js >new file mode 100644 >index 0000000000000000000000000000000000000000..01270e94efeedf42a8e5d173381a63b6aa8796a1 >--- /dev/null >+++ b/JSTests/stress/intl-language-tag.js >@@ -0,0 +1,58 @@ >+function shouldThrow(func, errorType) { >+ let error; >+ try { >+ func(); >+ } catch (e) { >+ error = e; >+ } >+ >+ if (!(error instanceof errorType)) >+ throw new Error(`Expected ${errorType.name}!`); >+} >+ >+function shouldNotThrow(func) { >+ func(); >+} >+ >+shouldThrow(() => Intl.getCanonicalLocales("en-US-u-ca-u-nu"), RangeError); >+shouldThrow(() => Intl.getCanonicalLocales("en-US-a-ok1-a-ok2"), RangeError); >+shouldNotThrow(() => Intl.getCanonicalLocales("en-US-a-ok1")); >+shouldNotThrow(() => Intl.getCanonicalLocales("de")); >+shouldNotThrow(() => Intl.getCanonicalLocales("fr")); >+shouldNotThrow(() => Intl.getCanonicalLocales("ja")); >+shouldThrow(() => Intl.getCanonicalLocales("i-enochian"), RangeError); >+shouldNotThrow(() => Intl.getCanonicalLocales("zh-Hant")); >+shouldNotThrow(() => Intl.getCanonicalLocales("zh-Hans")); >+shouldNotThrow(() => Intl.getCanonicalLocales("sr-Cyrl")); >+shouldNotThrow(() => Intl.getCanonicalLocales("sr-Latn")); >+shouldThrow(() => Intl.getCanonicalLocales("zh-cmn-Hans-CN"), RangeError); >+shouldNotThrow(() => Intl.getCanonicalLocales("cmn-Hans-CN")); >+shouldThrow(() => Intl.getCanonicalLocales("zh-yue-HK"), RangeError); >+shouldNotThrow(() => Intl.getCanonicalLocales("yue-HK")); >+shouldNotThrow(() => Intl.getCanonicalLocales("zh-Hans-CN")); >+shouldNotThrow(() => Intl.getCanonicalLocales("sr-Latn-RS")); >+shouldNotThrow(() => Intl.getCanonicalLocales("sl-rozaj")); >+shouldNotThrow(() => Intl.getCanonicalLocales("sl-rozaj-biske")); >+shouldThrow(() => Intl.getCanonicalLocales("sl-rozaj-biske-biske"), RangeError); >+shouldNotThrow(() => Intl.getCanonicalLocales("sl-nedis")); >+shouldNotThrow(() => Intl.getCanonicalLocales("de-CH-1901")); >+shouldNotThrow(() => Intl.getCanonicalLocales("sl-IT-nedis")); >+shouldNotThrow(() => Intl.getCanonicalLocales("hy-Latn-IT-arevela")); >+shouldNotThrow(() => Intl.getCanonicalLocales("de-DE")); >+shouldNotThrow(() => Intl.getCanonicalLocales("en-US")); >+shouldNotThrow(() => Intl.getCanonicalLocales("es-419")); >+shouldNotThrow(() => Intl.getCanonicalLocales("de-CH-x-phonebk")); >+shouldNotThrow(() => Intl.getCanonicalLocales("az-Arab-x-AZE-derbend")); >+shouldThrow(() => Intl.getCanonicalLocales("x-whatever"), RangeError); >+shouldNotThrow(() => Intl.getCanonicalLocales("qaa-Qaaa-QM-x-southern")); >+shouldNotThrow(() => Intl.getCanonicalLocales("de-Qaaa")); >+shouldNotThrow(() => Intl.getCanonicalLocales("sr-Latn-QM")); >+shouldNotThrow(() => Intl.getCanonicalLocales("sr-Qaaa-RS")); >+shouldNotThrow(() => Intl.getCanonicalLocales("en-US-u-islamcal")); >+shouldNotThrow(() => Intl.getCanonicalLocales("zh-CN-a-myext-x-private")); >+shouldNotThrow(() => Intl.getCanonicalLocales("en-a-myext-b-another")); >+shouldNotThrow(() => Intl.getCanonicalLocales("en-US-u-nu-fullwide")); >+shouldThrow(() => Intl.getCanonicalLocales("de-419-DE"), RangeError); >+shouldThrow(() => Intl.getCanonicalLocales("a-DE"), RangeError); >+shouldThrow(() => Intl.getCanonicalLocales("ar-a-aaa-b-bbb-a-ccc"), RangeError); >+shouldThrow(() => Intl.getCanonicalLocales(""), RangeError); >diff --git a/JSTests/stress/intl-locale.js b/JSTests/stress/intl-locale.js >index f48741f39a38f7bd600645c7f84e6b3788bdfc5e..04e525979fdc0c4844d1330be6d54d3d35c0c51d 100644 >--- a/JSTests/stress/intl-locale.js >+++ b/JSTests/stress/intl-locale.js >@@ -45,6 +45,12 @@ function shouldThrow(func, errorType) { > shouldThrow(() => new Intl.Locale({}), RangeError); > shouldThrow(() => new Intl.Locale({ toString() { throw new Error(); } }), Error); > shouldThrow(() => new Intl.Locale([]), RangeError); >+shouldThrow(() => new Intl.Locale('i-klingon'), RangeError); // grandfathered tag is not accepted by IsStructurallyValidLanguageTag >+shouldThrow(() => new Intl.Locale('x-en-US-12345'), RangeError); >+shouldThrow(() => new Intl.Locale('x-12345-12345-en-US'), RangeError); >+shouldThrow(() => new Intl.Locale('x-en-US-12345-12345'), RangeError); >+shouldThrow(() => new Intl.Locale('x-en-u-foo'), RangeError); >+shouldThrow(() => new Intl.Locale('x-en-u-foo-u-bar'), RangeError); > shouldNotThrow(() => new Intl.Locale({ toString() { return 'en'; } })); > > shouldThrow(() => new Intl.Locale('en', null), TypeError); >@@ -72,16 +78,10 @@ function shouldThrow(func, errorType) { > 'cmn-hans-cn', // + ISO 3166-1 country code > 'es-419', // + UN M.49 region code > 'es-419-u-nu-latn-cu-bob', // + Unicode locale extension sequence >- 'i-klingon', // grandfathered tag > 'cmn-hans-cn-t-ca-u-ca-x-t-u', // singleton subtags can also be used as private use subtags > 'enochian-enochian', // language and variant subtags may be the same > 'de-gregory-u-ca-gregory', // variant and extension subtags may be the same > 'aa-a-foo-x-a-foo-bar', // variant subtags can also be used as private use subtags >- 'x-en-US-12345', // anything goes in private use tags >- 'x-12345-12345-en-US', >- 'x-en-US-12345-12345', >- 'x-en-u-foo', >- 'x-en-u-foo-u-bar' > ]; > for (let validLanguageTag of validLanguageTags) > shouldNotThrow(() => new Intl.Locale(validLanguageTag)); >diff --git a/JSTests/stress/intl-numberformat.js b/JSTests/stress/intl-numberformat.js >index 31bbc4a25c34a1bd47a5f3f00053176918c1e561..2e965e7daeaf0b234c1d818ac4760e1f733276ba 100644 >--- a/JSTests/stress/intl-numberformat.js >+++ b/JSTests/stress/intl-numberformat.js >@@ -1,5 +1,3 @@ >-//@ runBigIntEnabled >- > function shouldBe(actual, expected) { > if (actual !== expected) > throw new Error(`expected ${expected} but got ${actual}`); >@@ -226,15 +224,13 @@ function testNumberFormat(numberFormat, possibleDifferences) { > ? '["en-Latn-US-1abc-foobar-variant-a-aa-aaa-u-kn-x-reserved"]' > : '["en-Latn-US-variant-foobar-1abc-a-aa-aaa-u-kn-true-x-reserved"]' > ); >-// Replaces outdated tags. >-shouldBe(JSON.stringify(Intl.NumberFormat.supportedLocalesOf('no-bok')), '["nb"]'); >-// Doesn't throw, but ignores private tags. >-shouldBe(JSON.stringify(Intl.NumberFormat.supportedLocalesOf('x-some-thing')), '[]'); > // Throws on problems with length, get, or toString. > shouldThrow(() => Intl.NumberFormat.supportedLocalesOf(Object.create(null, { length: { get() { throw new Error(); } } })), Error); > shouldThrow(() => Intl.NumberFormat.supportedLocalesOf(Object.create(null, { length: { value: 1 }, 0: { get() { throw new Error(); } } })), Error); > shouldThrow(() => Intl.NumberFormat.supportedLocalesOf([ { toString() { throw new Error(); } } ]), Error); > // Throws on bad tags. >+shouldThrow(() => Intl.NumberFormat.supportedLocalesOf('no-bok'), RangeError); >+shouldThrow(() => Intl.NumberFormat.supportedLocalesOf('x-some-thing'), RangeError); > shouldThrow(() => Intl.NumberFormat.supportedLocalesOf([ 5 ]), TypeError); > shouldThrow(() => Intl.NumberFormat.supportedLocalesOf(''), RangeError); > shouldThrow(() => Intl.NumberFormat.supportedLocalesOf('a'), RangeError); >@@ -247,6 +243,13 @@ function testNumberFormat(numberFormat, possibleDifferences) { > shouldThrow(() => Intl.NumberFormat.supportedLocalesOf('en-*'), RangeError); > shouldThrow(() => Intl.NumberFormat.supportedLocalesOf('en-'), RangeError); > shouldThrow(() => Intl.NumberFormat.supportedLocalesOf('en--US'), RangeError); >+shouldThrow(() => Intl.NumberFormat.supportedLocalesOf('i-klingon'), RangeError); // grandfathered tag is not accepted by IsStructurallyValidLanguageTag >+shouldThrow(() => Intl.NumberFormat.supportedLocalesOf('x-en-US-12345'), RangeError); >+shouldThrow(() => Intl.NumberFormat.supportedLocalesOf('x-12345-12345-en-US'), RangeError); >+shouldThrow(() => Intl.NumberFormat.supportedLocalesOf('x-en-US-12345-12345'), RangeError); >+shouldThrow(() => Intl.NumberFormat.supportedLocalesOf('x-en-u-foo'), RangeError); >+shouldThrow(() => Intl.NumberFormat.supportedLocalesOf('x-en-u-foo-u-bar'), RangeError); >+ > // Accepts valid tags > var validLanguageTags = [ > 'de', // ISO 639 language code >@@ -258,16 +261,10 @@ function testNumberFormat(numberFormat, possibleDifferences) { > 'cmn-hans-cn', // + ISO 3166-1 country code > 'es-419', // + UN M.49 region code > 'es-419-u-nu-latn-cu-bob', // + Unicode locale extension sequence >- 'i-klingon', // grandfathered tag > 'cmn-hans-cn-t-ca-u-ca-x-t-u', // singleton subtags can also be used as private use subtags > 'enochian-enochian', // language and variant subtags may be the same > 'de-gregory-u-ca-gregory', // variant and extension subtags may be the same > 'aa-a-foo-x-a-foo-bar', // variant subtags can also be used as private use subtags >- 'x-en-US-12345', // anything goes in private use tags >- 'x-12345-12345-en-US', >- 'x-en-US-12345-12345', >- 'x-en-u-foo', >- 'x-en-u-foo-u-bar' > ]; > for (var validLanguageTag of validLanguageTags) > shouldNotThrow(() => Intl.NumberFormat.supportedLocalesOf(validLanguageTag)); >diff --git a/JSTests/stress/intl-object.js b/JSTests/stress/intl-object.js >index a6711685a1b1f7c6f43615d58c0019d7aef84a34..353394ea0c3ba8ff969049900081d4d07d6662d0 100644 >--- a/JSTests/stress/intl-object.js >+++ b/JSTests/stress/intl-object.js >@@ -74,15 +74,13 @@ function shouldThrow(func, errorType) { > ? '["en-Latn-US-1abc-foobar-variant-a-aa-aaa-u-kn-x-reserved"]' > : '["en-Latn-US-variant-foobar-1abc-a-aa-aaa-u-kn-true-x-reserved"]' > ); >-// Replaces outdated tags. >-shouldBe(JSON.stringify(Intl.getCanonicalLocales('no-bok')), '["nb"]'); >-// Canonicalizes private tags. >-shouldBe(JSON.stringify(Intl.getCanonicalLocales('X-some-thing')), '["x-some-thing"]'); > // Throws on problems with length, get, or toString. > shouldThrow(() => Intl.getCanonicalLocales(Object.create(null, { length: { get() { throw new Error(); } } })), Error); > shouldThrow(() => Intl.getCanonicalLocales(Object.create(null, { length: { value: 1 }, 0: { get() { throw new Error(); } } })), Error); > shouldThrow(() => Intl.getCanonicalLocales([ { toString() { throw new Error(); } } ]), Error); > // Throws on bad tags. >+shouldThrow(() => Intl.getCanonicalLocales('no-bok'), RangeError); >+shouldThrow(() => Intl.getCanonicalLocales('x-some-thing'), RangeError); > shouldThrow(() => Intl.getCanonicalLocales([ 5 ]), TypeError); > shouldThrow(() => Intl.getCanonicalLocales(''), RangeError); > shouldThrow(() => Intl.getCanonicalLocales('a'), RangeError); >@@ -95,6 +93,13 @@ function shouldThrow(func, errorType) { > shouldThrow(() => Intl.getCanonicalLocales('en-*'), RangeError); > shouldThrow(() => Intl.getCanonicalLocales('en-'), RangeError); > shouldThrow(() => Intl.getCanonicalLocales('en--US'), RangeError); >+shouldThrow(() => Intl.getCanonicalLocales('i-klingon'), RangeError); // grandfathered tag is not accepted by IsStructurallyValidLanguageTag >+shouldThrow(() => Intl.getCanonicalLocales('x-en-US-12345'), RangeError); >+shouldThrow(() => Intl.getCanonicalLocales('x-12345-12345-en-US'), RangeError); >+shouldThrow(() => Intl.getCanonicalLocales('x-en-US-12345-12345'), RangeError); >+shouldThrow(() => Intl.getCanonicalLocales('x-en-u-foo'), RangeError); >+shouldThrow(() => Intl.getCanonicalLocales('x-en-u-foo-u-bar'), RangeError); >+ > // Accepts valid tags > var validLanguageTags = [ > 'de', // ISO 639 language code >@@ -106,16 +111,10 @@ function shouldThrow(func, errorType) { > 'cmn-hans-cn', // + ISO 3166-1 country code > 'es-419', // + UN M.49 region code > 'es-419-u-nu-latn-cu-bob', // + Unicode locale extension sequence >- 'i-klingon', // grandfathered tag > 'cmn-hans-cn-t-ca-u-ca-x-t-u', // singleton subtags can also be used as private use subtags > 'enochian-enochian', // language and variant subtags may be the same > 'de-gregory-u-ca-gregory', // variant and extension subtags may be the same > 'aa-a-foo-x-a-foo-bar', // variant subtags can also be used as private use subtags >- 'x-en-US-12345', // anything goes in private use tags >- 'x-12345-12345-en-US', >- 'x-en-US-12345-12345', >- 'x-en-u-foo', >- 'x-en-u-foo-u-bar' > ]; > for (var validLanguageTag of validLanguageTags) > shouldNotThrow(() => Intl.getCanonicalLocales(validLanguageTag)); >diff --git a/JSTests/stress/intl-pluralrules.js b/JSTests/stress/intl-pluralrules.js >index 84d6868a7166eb4f56f1ff7d26716224bb64d299..a136d46f41ad427e5ddbc1aaa644a11f512543bc 100644 >--- a/JSTests/stress/intl-pluralrules.js >+++ b/JSTests/stress/intl-pluralrules.js >@@ -85,15 +85,13 @@ function shouldThrow(func, errorType) { > ? '["en-Latn-US-1abc-foobar-variant-a-aa-aaa-u-kn-x-reserved"]' > : '["en-Latn-US-variant-foobar-1abc-a-aa-aaa-u-kn-true-x-reserved"]' > ); >-// Replaces outdated tags. >-shouldBe(JSON.stringify(Intl.PluralRules.supportedLocalesOf('no-bok')), '["nb"]'); >-// Doesn't throw, but ignores private tags. >-shouldBe(JSON.stringify(Intl.PluralRules.supportedLocalesOf('x-some-thing')), '[]'); > // Throws on problems with length, get, or toString. > shouldThrow(() => Intl.PluralRules.supportedLocalesOf(Object.create(null, { length: { get() { throw new Error(); } } })), Error); > shouldThrow(() => Intl.PluralRules.supportedLocalesOf(Object.create(null, { length: { value: 1 }, 0: { get() { throw new Error(); } } })), Error); > shouldThrow(() => Intl.PluralRules.supportedLocalesOf([ { toString() { throw new Error(); } } ]), Error); > // Throws on bad tags. >+shouldThrow(() => Intl.PluralRules.supportedLocalesOf('no-bok'), RangeError); >+shouldThrow(() => Intl.PluralRules.supportedLocalesOf('x-some-thing'), RangeError); > shouldThrow(() => Intl.PluralRules.supportedLocalesOf([ 5 ]), TypeError); > shouldThrow(() => Intl.PluralRules.supportedLocalesOf(''), RangeError); > shouldThrow(() => Intl.PluralRules.supportedLocalesOf('a'), RangeError); >@@ -106,6 +104,13 @@ function shouldThrow(func, errorType) { > shouldThrow(() => Intl.PluralRules.supportedLocalesOf('en-*'), RangeError); > shouldThrow(() => Intl.PluralRules.supportedLocalesOf('en-'), RangeError); > shouldThrow(() => Intl.PluralRules.supportedLocalesOf('en--US'), RangeError); >+shouldThrow(() => Intl.PluralRules.supportedLocalesOf('i-klingon'), RangeError); // grandfathered tag is not accepted by IsStructurallyValidLanguageTag >+shouldThrow(() => Intl.PluralRules.supportedLocalesOf('x-en-US-12345'), RangeError); >+shouldThrow(() => Intl.PluralRules.supportedLocalesOf('x-12345-12345-en-US'), RangeError); >+shouldThrow(() => Intl.PluralRules.supportedLocalesOf('x-en-US-12345-12345'), RangeError); >+shouldThrow(() => Intl.PluralRules.supportedLocalesOf('x-en-u-foo'), RangeError); >+shouldThrow(() => Intl.PluralRules.supportedLocalesOf('x-en-u-foo-u-bar'), RangeError); >+ > // Accepts valid tags > var validLanguageTags = [ > 'de', // ISO 639 language code >@@ -117,16 +122,10 @@ function shouldThrow(func, errorType) { > 'cmn-hans-cn', // + ISO 3166-1 country code > 'es-419', // + UN M.49 region code > 'es-419-u-nu-latn-cu-bob', // + Unicode locale extension sequence >- 'i-klingon', // grandfathered tag > 'cmn-hans-cn-t-ca-u-ca-x-t-u', // singleton subtags can also be used as private use subtags > 'enochian-enochian', // language and variant subtags may be the same > 'de-gregory-u-ca-gregory', // variant and extension subtags may be the same > 'aa-a-foo-x-a-foo-bar', // variant subtags can also be used as private use subtags >- 'x-en-US-12345', // anything goes in private use tags >- 'x-12345-12345-en-US', >- 'x-en-US-12345-12345', >- 'x-en-u-foo', >- 'x-en-u-foo-u-bar' > ]; > for (var validLanguageTag of validLanguageTags) > shouldNotThrow(() => Intl.PluralRules.supportedLocalesOf(validLanguageTag)); >diff --git a/JSTests/stress/intl-relativetimeformat.js b/JSTests/stress/intl-relativetimeformat.js >index 3f3a87a1f22c0bcd9a495ab4ac41c8c532283208..f91c1abce05506a04ef0f3ddb3a70851b27bc934 100644 >--- a/JSTests/stress/intl-relativetimeformat.js >+++ b/JSTests/stress/intl-relativetimeformat.js >@@ -69,9 +69,9 @@ function shouldThrow(func, errorType) { > ? '["en-Latn-US-1abc-foobar-variant-a-aa-aaa-u-kn-x-reserved"]' > : '["en-Latn-US-variant-foobar-1abc-a-aa-aaa-u-kn-true-x-reserved"]' > ); >-shouldBe(JSON.stringify(Intl.RelativeTimeFormat.supportedLocalesOf('no-bok')), '["nb"]'); >-shouldBe(JSON.stringify(Intl.RelativeTimeFormat.supportedLocalesOf('x-some-thing')), '[]'); > >+shouldThrow(() => Intl.RelativeTimeFormat.supportedLocalesOf('no-bok'), RangeError); >+shouldThrow(() => Intl.RelativeTimeFormat.supportedLocalesOf('x-some-thing'), RangeError); > shouldThrow(() => Intl.RelativeTimeFormat.supportedLocalesOf(Object.create(null, { length: { get() { throw new Error(); } } })), Error); > shouldThrow(() => Intl.RelativeTimeFormat.supportedLocalesOf(Object.create(null, { length: { value: 1 }, 0: { get() { throw new Error(); } } })), Error); > shouldThrow(() => Intl.RelativeTimeFormat.supportedLocalesOf([{ toString() { throw new Error(); } }]), Error); >@@ -87,6 +87,12 @@ function shouldThrow(func, errorType) { > shouldThrow(() => Intl.RelativeTimeFormat.supportedLocalesOf('en-*'), RangeError); > shouldThrow(() => Intl.RelativeTimeFormat.supportedLocalesOf('en-'), RangeError); > shouldThrow(() => Intl.RelativeTimeFormat.supportedLocalesOf('en--US'), RangeError); >+shouldThrow(() => Intl.RelativeTimeFormat.supportedLocalesOf('i-klingon'), RangeError); // grandfathered tag is not accepted by IsStructurallyValidLanguageTag >+shouldThrow(() => Intl.RelativeTimeFormat.supportedLocalesOf('x-en-US-12345'), RangeError); >+shouldThrow(() => Intl.RelativeTimeFormat.supportedLocalesOf('x-12345-12345-en-US'), RangeError); >+shouldThrow(() => Intl.RelativeTimeFormat.supportedLocalesOf('x-en-US-12345-12345'), RangeError); >+shouldThrow(() => Intl.RelativeTimeFormat.supportedLocalesOf('x-en-u-foo'), RangeError); >+shouldThrow(() => Intl.RelativeTimeFormat.supportedLocalesOf('x-en-u-foo-u-bar'), RangeError); > > const validLanguageTags = [ > 'de', // ISO 639 language code >@@ -98,16 +104,10 @@ function shouldThrow(func, errorType) { > 'cmn-hans-cn', // + ISO 3166-1 country code > 'es-419', // + UN M.49 region code > 'es-419-u-nu-latn-cu-bob', // + Unicode locale extension sequence >- 'i-klingon', // grandfathered tag > 'cmn-hans-cn-t-ca-u-ca-x-t-u', // singleton subtags can also be used as private use subtags > 'enochian-enochian', // language and variant subtags may be the same > 'de-gregory-u-ca-gregory', // variant and extension subtags may be the same > 'aa-a-foo-x-a-foo-bar', // variant subtags can also be used as private use subtags >- 'x-en-US-12345', // anything goes in private use tags >- 'x-12345-12345-en-US', >- 'x-en-US-12345-12345', >- 'x-en-u-foo', >- 'x-en-u-foo-u-bar' > ]; > for (let validLanguageTag of validLanguageTags) > shouldNotThrow(() => Intl.RelativeTimeFormat.supportedLocalesOf(validLanguageTag)); >diff --git a/JSTests/stress/string-toLocaleLowerCase.js b/JSTests/stress/string-toLocaleLowerCase.js >index ca7704e0dab731f5f678008cf262a9c1041b5136..acdf6cad2832b5b19b5c84382b47649301e91d47 100644 >--- a/JSTests/stress/string-toLocaleLowerCase.js >+++ b/JSTests/stress/string-toLocaleLowerCase.js >@@ -30,8 +30,6 @@ function shouldThrow(func, errorType) { > shouldBe('A'.toLocaleLowerCase(9), 'a'); > // Handles array-like objects with holes. > shouldBe('\u0130'.toLocaleLowerCase({ length: 4, 1: 'az', 3: 'en' }), 'i'); >-// Doesn't throw, but ignores private tags. >-shouldBe('A'.toLocaleLowerCase('x-some-thing'), 'a'); > // Throws on problems with length, get, or toString. > shouldThrow(() => 'A'.toLocaleLowerCase(Object.create(null, { length: { get() { throw new Error() } } })), Error); > shouldThrow(() => 'A'.toLocaleLowerCase(Object.create(null, { length: { value: 1 }, 0: { get() { throw new Error() } } })), Error); >@@ -49,6 +47,14 @@ function shouldThrow(func, errorType) { > shouldThrow(() => 'A'.toLocaleLowerCase('en-*'), RangeError); > shouldThrow(() => 'A'.toLocaleLowerCase('en-'), RangeError); > shouldThrow(() => 'A'.toLocaleLowerCase('en--US'), RangeError); >+shouldThrow(() => 'A'.toLocaleLowerCase('no-bok'), RangeError); >+shouldThrow(() => 'A'.toLocaleLowerCase('x-some-thing'), RangeError); >+shouldThrow(() => 'A'.toLocaleLowerCase('i-klingon'), RangeError); // grandfathered tag is not accepted by IsStructurallyValidLanguageTag >+shouldThrow(() => 'A'.toLocaleLowerCase('x-en-US-12345'), RangeError); >+shouldThrow(() => 'A'.toLocaleLowerCase('x-12345-12345-en-US'), RangeError); >+shouldThrow(() => 'A'.toLocaleLowerCase('x-en-US-12345-12345'), RangeError); >+shouldThrow(() => 'A'.toLocaleLowerCase('x-en-u-foo'), RangeError); >+shouldThrow(() => 'A'.toLocaleLowerCase('x-en-u-foo-u-bar'), RangeError); > > // Check ascii and accents. > shouldBe('AbCdEfGhIjKlMnOpQRStuvWXyZ0123456789'.toLocaleLowerCase(), 'abcdefghijklmnopqrstuvwxyz0123456789'); >diff --git a/JSTests/stress/string-toLocaleUpperCase.js b/JSTests/stress/string-toLocaleUpperCase.js >index 0c867ba9fce2a84bff4740fde3a9d26729d01177..3f86296fc0e186cd644186596655f4e873668243 100644 >--- a/JSTests/stress/string-toLocaleUpperCase.js >+++ b/JSTests/stress/string-toLocaleUpperCase.js >@@ -30,8 +30,6 @@ function shouldThrow(func, errorType) { > shouldBe('a'.toLocaleUpperCase(9), 'A'); > // Handles array-like objects with holes. > shouldBe('i'.toLocaleUpperCase({ length: 4, 1: 'az', 3: 'en' }), '\u0130'); >-// Doesn't throw, but ignores private tags. >-shouldBe('a'.toLocaleUpperCase('x-some-thing'), 'A'); > // Throws on problems with length, get, or toString. > shouldThrow(() => 'a'.toLocaleUpperCase(Object.create(null, { length: { get() { throw new Error() } } })), Error); > shouldThrow(() => 'a'.toLocaleUpperCase(Object.create(null, { length: { value: 1 }, 0: { get() { throw new Error() } } })), Error); >@@ -49,6 +47,14 @@ function shouldThrow(func, errorType) { > shouldThrow(() => 'a'.toLocaleUpperCase('en-*'), RangeError); > shouldThrow(() => 'a'.toLocaleUpperCase('en-'), RangeError); > shouldThrow(() => 'a'.toLocaleUpperCase('en--US'), RangeError); >+shouldThrow(() => 'A'.toLocaleUpperCase('no-bok'), RangeError); >+shouldThrow(() => 'A'.toLocaleUpperCase('x-some-thing'), RangeError); >+shouldThrow(() => 'A'.toLocaleUpperCase('i-klingon'), RangeError); // grandfathered tag is not accepted by IsStructurallyValidLanguageTag >+shouldThrow(() => 'A'.toLocaleUpperCase('x-en-US-12345'), RangeError); >+shouldThrow(() => 'A'.toLocaleUpperCase('x-12345-12345-en-US'), RangeError); >+shouldThrow(() => 'A'.toLocaleUpperCase('x-en-US-12345-12345'), RangeError); >+shouldThrow(() => 'A'.toLocaleUpperCase('x-en-u-foo'), RangeError); >+shouldThrow(() => 'A'.toLocaleUpperCase('x-en-u-foo-u-bar'), RangeError); > > // Check ascii and accents. > shouldBe('AbCdEfGhIjKlMnOpQRStuvWXyZ0123456789'.toLocaleUpperCase(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'); >diff --git a/JSTests/test262/expectations.yaml b/JSTests/test262/expectations.yaml >index 79a93dd894d877cce7a7281e1c52d097405956af..6745163e259665312462d464dbd9d685783f339a 100644 >--- a/JSTests/test262/expectations.yaml >+++ b/JSTests/test262/expectations.yaml >@@ -1584,9 +1584,6 @@ test/intl402/Intl/getCanonicalLocales/complex-region-subtag-replacement.js: > test/intl402/Intl/getCanonicalLocales/grandfathered.js: > default: 'Test262Error: Expected SameValue(«cmn», «zh») to be true' > strict mode: 'Test262Error: Expected SameValue(«cmn», «zh») to be true' >-test/intl402/Intl/getCanonicalLocales/invalid-tags.js: >- default: 'Test262Error: Language tag: no-nyn Expected a RangeError to be thrown but no exception was thrown at all' >- strict mode: 'Test262Error: Language tag: no-nyn Expected a RangeError to be thrown but no exception was thrown at all' > test/intl402/Intl/getCanonicalLocales/non-iana-canon.js: > default: 'Test262Error: The value of Intl.getCanonicalLocales(tag)[0] equals the value of `canonical` Expected SameValue(«en-US-u-va-posix», «posix») to be true' > strict mode: 'Test262Error: The value of Intl.getCanonicalLocales(tag)[0] equals the value of `canonical` Expected SameValue(«en-US-u-va-posix», «posix») to be true' >@@ -1599,9 +1596,6 @@ test/intl402/Intl/getCanonicalLocales/preferred-variant.js: > test/intl402/Intl/getCanonicalLocales/transformed-ext-canonical.js: > default: 'Test262Error: Expected SameValue(«sl-t-sl-rozaj-biske-1994», «sl-t-sl-1994-biske-rozaj») to be true' > strict mode: 'Test262Error: Expected SameValue(«sl-t-sl-rozaj-biske-1994», «sl-t-sl-1994-biske-rozaj») to be true' >-test/intl402/Intl/getCanonicalLocales/transformed-ext-invalid.js: >- default: 'Test262Error: en-t-root Expected a RangeError to be thrown but no exception was thrown at all' >- strict mode: 'Test262Error: en-t-root Expected a RangeError to be thrown but no exception was thrown at all' > test/intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-region.js: > default: 'Test262Error: Expected SameValue(«und-u-rg-no23», «und-u-rg-no50») to be true' > strict mode: 'Test262Error: Expected SameValue(«und-u-rg-no23», «und-u-rg-no50») to be true' >@@ -1612,20 +1606,14 @@ test/intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-yes-to-true.js: > default: 'Test262Error: Expected SameValue(«und-u-kb-true», «und-u-kb») to be true' > strict mode: 'Test262Error: Expected SameValue(«und-u-kb-true», «und-u-kb») to be true' > test/intl402/Intl/getCanonicalLocales/unicode-ext-key-with-digit.js: >- default: 'Test262Error: Expected a RangeError to be thrown but no exception was thrown at all' >- strict mode: 'Test262Error: Expected a RangeError to be thrown but no exception was thrown at all' >+ default: 'Test262Error: Expected SameValue(«en-u-0c-yes», «en-u-0c») to be true' >+ strict mode: 'Test262Error: Expected SameValue(«en-u-0c-yes», «en-u-0c») to be true' > test/intl402/Locale/constructor-apply-options-canonicalizes-twice.js: > default: 'Test262Error: Expected SameValue(«ru-Armn-SU», «ru-Armn-AM») to be true' > strict mode: 'Test262Error: Expected SameValue(«ru-Armn-SU», «ru-Armn-AM») to be true' > test/intl402/Locale/constructor-non-iana-canon.js: > default: 'Test262Error: new Intl.Locale("mo").maximize().toString() returns "ro-Latn-RO" Expected SameValue(«ro», «ro-Latn-RO») to be true' > strict mode: 'Test262Error: new Intl.Locale("mo").maximize().toString() returns "ro-Latn-RO" Expected SameValue(«ro», «ro-Latn-RO») to be true' >-test/intl402/Locale/constructor-options-language-valid-undefined.js: >- default: 'Test262Error: Expected a RangeError to be thrown but no exception was thrown at all' >- strict mode: 'Test262Error: Expected a RangeError to be thrown but no exception was thrown at all' >-test/intl402/Locale/constructor-options-language-valid.js: >- default: 'Test262Error: Expected a RangeError to be thrown but no exception was thrown at all' >- strict mode: 'Test262Error: Expected a RangeError to be thrown but no exception was thrown at all' > test/intl402/Locale/constructor-options-numeric-undefined.js: > default: 'Test262Error: new Intl.Locale("en-u-kn-true", {numeric: undefined}).toString() returns "en-u-kn" Expected SameValue(«en-u-kn-true», «en-u-kn») to be true' > strict mode: 'Test262Error: new Intl.Locale("en-u-kn-true", {numeric: undefined}).toString() returns "en-u-kn" Expected SameValue(«en-u-kn-true», «en-u-kn») to be true' >@@ -1635,42 +1623,21 @@ test/intl402/Locale/constructor-options-numeric-valid.js: > test/intl402/Locale/constructor-options-region-valid.js: > default: "Test262Error: new Intl.Locale('en', {region: \"554\"}).toString() returns \"en-NZ\" Expected SameValue(«en-554», «en-NZ») to be true" > strict mode: "Test262Error: new Intl.Locale('en', {region: \"554\"}).toString() returns \"en-NZ\" Expected SameValue(«en-554», «en-NZ») to be true" >-test/intl402/Locale/constructor-parse-twice.js: >- default: 'Test262Error: Expected a RangeError to be thrown but no exception was thrown at all' >- strict mode: 'Test262Error: Expected a RangeError to be thrown but no exception was thrown at all' > test/intl402/Locale/constructor-tag.js: > default: 'Test262Error: new Intl.Locale("sl-ROZAJ-BISKE-1994").toString() returns "sl-1994-biske-rozaj" Expected SameValue(«sl-rozaj-biske-1994», «sl-1994-biske-rozaj») to be true' > strict mode: 'Test262Error: new Intl.Locale("sl-ROZAJ-BISKE-1994").toString() returns "sl-1994-biske-rozaj" Expected SameValue(«sl-rozaj-biske-1994», «sl-1994-biske-rozaj») to be true' >-test/intl402/Locale/extensions-grandfathered.js: >- default: 'Test262Error: Expected a RangeError to be thrown but no exception was thrown at all' >- strict mode: 'Test262Error: Expected a RangeError to be thrown but no exception was thrown at all' >-test/intl402/Locale/extensions-private.js: >- default: 'Test262Error: Expected a RangeError to be thrown but no exception was thrown at all' >- strict mode: 'Test262Error: Expected a RangeError to be thrown but no exception was thrown at all' >-test/intl402/Locale/getters-grandfathered.js: >- default: 'Test262Error: Expected a RangeError to be thrown but no exception was thrown at all' >- strict mode: 'Test262Error: Expected a RangeError to be thrown but no exception was thrown at all' > test/intl402/Locale/getters.js: > default: 'Test262Error: Expected SameValue(«de-Latn-DE-u-ca-gregory-co-phonebk-hc-h23-kf-true-kn-false-nu-latn», «de-Latn-DE-u-ca-gregory-co-phonebk-hc-h23-kf-kn-false-nu-latn») to be true' > strict mode: 'Test262Error: Expected SameValue(«de-Latn-DE-u-ca-gregory-co-phonebk-hc-h23-kf-true-kn-false-nu-latn», «de-Latn-DE-u-ca-gregory-co-phonebk-hc-h23-kf-kn-false-nu-latn») to be true' >-test/intl402/Locale/invalid-tag-throws.js: >- default: 'Test262Error: no-nyn is an invalid tag value Expected a RangeError to be thrown but no exception was thrown at all' >- strict mode: 'Test262Error: no-nyn is an invalid tag value Expected a RangeError to be thrown but no exception was thrown at all' > test/intl402/Locale/likely-subtags-grandfathered.js: >- default: 'Test262Error: Expected a RangeError to be thrown but no exception was thrown at all' >- strict mode: 'Test262Error: Expected a RangeError to be thrown but no exception was thrown at all' >+ default: 'Test262Error: Expected SameValue(«cmn», «zh») to be true' >+ strict mode: 'Test262Error: Expected SameValue(«cmn», «zh») to be true' > test/intl402/Locale/likely-subtags.js: > default: 'Test262Error: "en-u-co".maximize() should be "en-Latn-US-u-co" Expected SameValue(«en-Latn-US-u-co-yes», «en-Latn-US-u-co») to be true' > strict mode: 'Test262Error: "en-u-co".maximize() should be "en-Latn-US-u-co" Expected SameValue(«en-Latn-US-u-co-yes», «en-Latn-US-u-co») to be true' > test/intl402/Locale/prototype/minimize/removing-likely-subtags-first-adds-likely-subtags.js: > default: 'Test262Error: "und".minimize() should be "en" Expected SameValue(«en-u-va-posix», «en») to be true' > strict mode: 'Test262Error: "und".minimize() should be "en" Expected SameValue(«en-u-va-posix», «en») to be true' >-test/intl402/RelativeTimeFormat/constructor/constructor/locales-valid.js: >- default: 'Test262Error: Grandfathered Expected a RangeError to be thrown but no exception was thrown at all' >- strict mode: 'Test262Error: Grandfathered Expected a RangeError to be thrown but no exception was thrown at all' >-test/intl402/language-tags-invalid.js: >- default: 'Test262Error: Invalid language tag no-nyn was not rejected. Expected a RangeError to be thrown but no exception was thrown at all (Testing with Collator.)' >- strict mode: 'Test262Error: Invalid language tag no-nyn was not rejected. Expected a RangeError to be thrown but no exception was thrown at all (Testing with Collator.)' > test/language/arguments-object/mapped/nonconfigurable-nonenumerable-nonwritable-descriptors-set-by-arguments.js: > default: 'Test262Error: Expected obj[0] to have enumerable:false.' > test/language/arguments-object/mapped/nonconfigurable-nonenumerable-nonwritable-descriptors-set-by-param.js:
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
ross.kirsling
:
review+
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 215058
:
405783
|
405784
| 405815 |
407058