Diff
Modified: trunk/JSTests/ChangeLog (259940 => 259941)
--- trunk/JSTests/ChangeLog 2020-04-12 04:32:41 UTC (rev 259940)
+++ trunk/JSTests/ChangeLog 2020-04-12 07:42:34 UTC (rev 259941)
@@ -1,3 +1,16 @@
+2020-04-12 Ross Kirsling <[email protected]>
+
+ [ECMA-402] WebKit Intl does not allow calendar and numberingSystem options
+ https://bugs.webkit.org/show_bug.cgi?id=209784
+
+ Reviewed by Myles C. Maxfield.
+
+ * stress/intl-datetimeformat.js:
+ Fix two test cases for old behavior.
+
+ * test262/expectations.yaml:
+ Mark 16 test cases as passing.
+
2020-04-10 Ross Kirsling <[email protected]>
[ECMA-402] Properly implement BigInt.prototype.toLocaleString
Modified: trunk/JSTests/stress/intl-datetimeformat.js (259940 => 259941)
--- trunk/JSTests/stress/intl-datetimeformat.js 2020-04-12 04:32:41 UTC (rev 259940)
+++ trunk/JSTests/stress/intl-datetimeformat.js 2020-04-12 07:42:34 UTC (rev 259941)
@@ -280,7 +280,7 @@
shouldBe(Intl.DateTimeFormat('fa-IR').resolvedOptions().calendar, 'persian');
shouldBe(Intl.DateTimeFormat('ar').resolvedOptions().numberingSystem, 'arab');
-shouldBe(Intl.DateTimeFormat('en', { calendar:'dangi' }).resolvedOptions().calendar, 'gregory');
+shouldBe(Intl.DateTimeFormat('en', { calendar: 'dangi' }).resolvedOptions().calendar, 'dangi');
shouldBe(Intl.DateTimeFormat('en-u-ca-bogus').resolvedOptions().locale, 'en');
shouldBe(Intl.DateTimeFormat('en-u-ca-bogus').resolvedOptions().calendar, 'gregory');
shouldBe(Intl.DateTimeFormat('en-u-ca-buddhist').resolvedOptions().locale, 'en-u-ca-buddhist');
@@ -327,7 +327,7 @@
shouldBe(Intl.DateTimeFormat('en-u-ca-islamic-civil', { timeZone: 'America/Los_Angeles' }).format(1451099872641), '3/13/1437');
shouldBe(Intl.DateTimeFormat('en-u-ca-islamic-rgsa', { timeZone: 'America/Los_Angeles' }).format(1451099872641), '3/14/1437');
-shouldBe(Intl.DateTimeFormat('en', { numberingSystem:'gujr' }).resolvedOptions().numberingSystem, 'latn');
+shouldBe(Intl.DateTimeFormat('en', { numberingSystem: 'gujr' }).resolvedOptions().numberingSystem, 'gujr');
shouldBe(Intl.DateTimeFormat('en-u-nu-bogus').resolvedOptions().locale, 'en');
shouldBe(Intl.DateTimeFormat('en-u-nu-bogus').resolvedOptions().numberingSystem, 'latn');
shouldBe(Intl.DateTimeFormat('en-u-nu-latn').resolvedOptions().numberingSystem, 'latn');
Modified: trunk/JSTests/test262/expectations.yaml (259940 => 259941)
--- trunk/JSTests/test262/expectations.yaml 2020-04-12 04:32:41 UTC (rev 259940)
+++ trunk/JSTests/test262/expectations.yaml 2020-04-12 07:42:34 UTC (rev 259941)
@@ -1920,18 +1920,6 @@
test/intl402/Collator/usage-de.js:
default: 'Test262Error: Expected [Ä, AE] and [AE, Ä] to have the same contents. search'
strict mode: 'Test262Error: Expected [Ä, AE] and [AE, Ä] to have the same contents. search'
-test/intl402/DateTimeFormat/constructor-calendar-numberingSystem-order.js:
- default: 'Test262Error: Expected [localeMatcher, hour12] and [localeMatcher, calendar, numberingSystem, hour12] to have the same contents. '
- strict mode: 'Test262Error: Expected [localeMatcher, hour12] and [localeMatcher, calendar, numberingSystem, hour12] to have the same contents. '
-test/intl402/DateTimeFormat/constructor-options-calendar-invalid.js:
- default: 'Test262Error: new Intl.DateTimeFormat("en", {calendar: ""}) throws RangeError Expected a RangeError to be thrown but no exception was thrown at all'
- strict mode: 'Test262Error: new Intl.DateTimeFormat("en", {calendar: ""}) throws RangeError Expected a RangeError to be thrown but no exception was thrown at all'
-test/intl402/DateTimeFormat/constructor-options-numberingSystem-invalid.js:
- default: 'Test262Error: new Intl.DateTimeFormat("en", {numberingSystem: ""}) throws RangeError Expected a RangeError to be thrown but no exception was thrown at all'
- strict mode: 'Test262Error: new Intl.DateTimeFormat("en", {numberingSystem: ""}) throws RangeError Expected a RangeError to be thrown but no exception was thrown at all'
-test/intl402/DateTimeFormat/numbering-system-calendar-options.js:
- default: "Test262Error: Options value for property numberingSystem doesn't override locale extension key nu. Expected SameValue(«arab», «latn») to be true"
- strict mode: "Test262Error: Options value for property numberingSystem doesn't override locale extension key nu. Expected SameValue(«arab», «latn») to be true"
test/intl402/DateTimeFormat/proto-from-ctor-realm.js:
default: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«[object Object]», «[object Object]») to be true'
strict mode: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«[object Object]», «[object Object]») to be true'
@@ -1968,18 +1956,6 @@
test/intl402/Intl/getCanonicalLocales/preferred-variant.js:
default: 'Test262Error: Expected SameValue(«ja-Latn-alalc97», «ja-Latn-hepburn-heploc») to be true'
strict mode: 'Test262Error: Expected SameValue(«ja-Latn-alalc97», «ja-Latn-hepburn-heploc») to be true'
-test/intl402/NumberFormat/constructor-numberingSystem-order.js:
- default: 'Test262Error: Expected [localeMatcher, style] and [localeMatcher, numberingSystem, style] to have the same contents. '
- strict mode: 'Test262Error: Expected [localeMatcher, style] and [localeMatcher, numberingSystem, style] to have the same contents. '
-test/intl402/NumberFormat/constructor-options-numberingSystem-invalid.js:
- default: 'Test262Error: new Intl.NumberFormat("en", {numberingSystem: ""}) throws RangeError Expected a RangeError to be thrown but no exception was thrown at all'
- strict mode: 'Test262Error: new Intl.NumberFormat("en", {numberingSystem: ""}) throws RangeError Expected a RangeError to be thrown but no exception was thrown at all'
-test/intl402/NumberFormat/constructor-options-throwing-getters.js:
- default: 'Test262Error: Exception from numberingSystem getter should be propagated Expected a CustomError to be thrown but no exception was thrown at all'
- strict mode: 'Test262Error: Exception from numberingSystem getter should be propagated Expected a CustomError to be thrown but no exception was thrown at all'
-test/intl402/NumberFormat/numbering-system-options.js:
- default: "Test262Error: Options value for property numberingSystem doesn't override locale extension key nu. Expected SameValue(«arab», «latn») to be true"
- strict mode: "Test262Error: Options value for property numberingSystem doesn't override locale extension key nu. Expected SameValue(«arab», «latn») to be true"
test/intl402/NumberFormat/proto-from-ctor-realm.js:
default: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«[object Object]», «[object Object]») to be true'
strict mode: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«[object Object]», «[object Object]») to be true'
Modified: trunk/Source/_javascript_Core/ChangeLog (259940 => 259941)
--- trunk/Source/_javascript_Core/ChangeLog 2020-04-12 04:32:41 UTC (rev 259940)
+++ trunk/Source/_javascript_Core/ChangeLog 2020-04-12 07:42:34 UTC (rev 259941)
@@ -1,3 +1,28 @@
+2020-04-12 Ross Kirsling <[email protected]>
+
+ [ECMA-402] WebKit Intl does not allow calendar and numberingSystem options
+ https://bugs.webkit.org/show_bug.cgi?id=209784
+
+ Reviewed by Myles C. Maxfield.
+
+ As an alternative to using `ca` and `nu` extensions in the locale string:
+ - the Intl.DateTimeFormat constructor needs to be able to take `calendar` and `numberingSystem` options
+ https://tc39.es/ecma402/#sec-initializedatetimeformat
+ - the Intl.NumberFormat needs to be able to take a `numberingSystem` option
+ https://tc39.es/ecma402/#sec-initializenumberformat
+
+ Since we already support `ca` and `nu`, this is a very simple addition.
+ The only interesting part is that we must verify that values for these options are 3-8 alphanumeric characters.
+
+ * runtime/IntlDateTimeFormat.cpp:
+ (JSC::IntlDateTimeFormat::initializeDateTimeFormat):
+ * runtime/IntlNumberFormat.cpp:
+ (JSC::IntlNumberFormat::initializeNumberFormat):
+ (JSC::IntlNumberFormat::resolvedOptions):
+ * runtime/IntlObject.cpp:
+ (JSC::isUnicodeLocaleIdentifierType):
+ * runtime/IntlObject.h:
+
2020-04-10 Ross Kirsling <[email protected]>
[ECMA-402] Properly implement BigInt.prototype.toLocaleString
Modified: trunk/Source/_javascript_Core/runtime/IntlDateTimeFormat.cpp (259940 => 259941)
--- trunk/Source/_javascript_Core/runtime/IntlDateTimeFormat.cpp 2020-04-12 04:32:41 UTC (rev 259940)
+++ trunk/Source/_javascript_Core/runtime/IntlDateTimeFormat.cpp 2020-04-12 07:42:34 UTC (rev 259941)
@@ -449,6 +449,26 @@
RETURN_IF_EXCEPTION(scope, void());
opt.add(vm.propertyNames->localeMatcher.string(), localeMatcher);
+ String calendar = intlStringOption(globalObject, options, vm.propertyNames->calendar, { }, nullptr, nullptr);
+ RETURN_IF_EXCEPTION(scope, void());
+ if (!calendar.isNull()) {
+ if (!isUnicodeLocaleIdentifierType(calendar)) {
+ throwRangeError(globalObject, scope, "calendar is not a well-formed calendar value"_s);
+ return;
+ }
+ opt.add("ca"_s, calendar);
+ }
+
+ String numberingSystem = intlStringOption(globalObject, options, vm.propertyNames->numberingSystem, { }, nullptr, nullptr);
+ RETURN_IF_EXCEPTION(scope, void());
+ if (!numberingSystem.isNull()) {
+ if (!isUnicodeLocaleIdentifierType(numberingSystem)) {
+ throwRangeError(globalObject, scope, "numberingSystem is not a well-formed numbering system value"_s);
+ return;
+ }
+ opt.add("nu"_s, numberingSystem);
+ }
+
bool isHour12Undefined;
bool hour12 = intlBooleanOption(globalObject, options, vm.propertyNames->hour12, isHour12Undefined);
RETURN_IF_EXCEPTION(scope, void());
Modified: trunk/Source/_javascript_Core/runtime/IntlNumberFormat.cpp (259940 => 259941)
--- trunk/Source/_javascript_Core/runtime/IntlNumberFormat.cpp 2020-04-12 04:32:41 UTC (rev 259940)
+++ trunk/Source/_javascript_Core/runtime/IntlNumberFormat.cpp 2020-04-12 07:42:34 UTC (rev 259941)
@@ -174,6 +174,16 @@
RETURN_IF_EXCEPTION(scope, void());
opt.add("localeMatcher"_s, matcher);
+ String numberingSystem = intlStringOption(globalObject, options, vm.propertyNames->numberingSystem, { }, nullptr, nullptr);
+ RETURN_IF_EXCEPTION(scope, void());
+ if (!numberingSystem.isNull()) {
+ if (!isUnicodeLocaleIdentifierType(numberingSystem)) {
+ throwRangeError(globalObject, scope, "numberingSystem is not a well-formed numbering system value"_s);
+ return;
+ }
+ opt.add("nu"_s, numberingSystem);
+ }
+
auto& availableLocales = intlNumberFormatAvailableLocales();
auto result = resolveLocale(globalObject, availableLocales, requestedLocales, opt, relevantNumberExtensionKeys, WTF_ARRAY_LENGTH(relevantNumberExtensionKeys), IntlNFInternal::localeData);
@@ -430,7 +440,7 @@
JSObject* options = constructEmptyObject(globalObject);
options->putDirect(vm, vm.propertyNames->locale, jsString(vm, m_locale));
- options->putDirect(vm, Identifier::fromString(vm, "numberingSystem"), jsString(vm, m_numberingSystem));
+ options->putDirect(vm, vm.propertyNames->numberingSystem, jsString(vm, m_numberingSystem));
options->putDirect(vm, Identifier::fromString(vm, "style"), jsNontrivialString(vm, styleString(m_style)));
if (m_style == Style::Currency) {
options->putDirect(vm, Identifier::fromString(vm, "currency"), jsNontrivialString(vm, m_currency));
Modified: trunk/Source/_javascript_Core/runtime/IntlObject.cpp (259940 => 259941)
--- trunk/Source/_javascript_Core/runtime/IntlObject.cpp 2020-04-12 04:32:41 UTC (rev 259940)
+++ trunk/Source/_javascript_Core/runtime/IntlObject.cpp 2020-04-12 07:42:34 UTC (rev 259941)
@@ -323,6 +323,23 @@
return fallback;
}
+// http://www.unicode.org/reports/tr35/#Unicode_locale_identifier
+bool isUnicodeLocaleIdentifierType(StringView string)
+{
+ ASSERT(!string.isNull());
+
+ auto length = string.length();
+ if (length < 3 || length > 8)
+ return false;
+
+ for (auto character : string.codeUnits()) {
+ if (!isASCIIAlphanumeric(character))
+ return false;
+ }
+
+ return true;
+}
+
static String privateUseLangTag(const Vector<String>& parts, size_t startIndex)
{
size_t numParts = parts.size();
Modified: trunk/Source/_javascript_Core/runtime/IntlObject.h (259940 => 259941)
--- trunk/Source/_javascript_Core/runtime/IntlObject.h 2020-04-12 04:32:41 UTC (rev 259940)
+++ trunk/Source/_javascript_Core/runtime/IntlObject.h 2020-04-12 07:42:34 UTC (rev 259941)
@@ -78,4 +78,6 @@
String bestAvailableLocale(const HashSet<String>& availableLocales, const String& requestedLocale);
Vector<String> numberingSystemsForLocale(const String& locale);
+bool isUnicodeLocaleIdentifierType(StringView);
+
} // namespace JSC