return value;
}
+/* CanonicalizeUValue (ecma402): ASCII-lowercase the value, then canonicalize
+ it as a value of key per UTS35 Annex C. A value which canonicalizes to
+ "true" is removed, i.e. the empty String is returned.
+ Returns a newly allocated string. */
+static char *canonicalize_u_value(JSContext *ctx, const char *key, const char *value)
+{
+ char *lower = js_strdup(ctx, value);
+ const char *canon;
+ if (!lower)
+ return NULL;
+ to_lower_case(lower);
+ canon = canonicalize_keyword_value(key, lower);
+ if (canon != lower) {
+ js_free(ctx, lower);
+ lower = js_strdup(ctx, canon);
+ if (!lower)
+ return NULL;
+ }
+ if (!strcmp(lower, "true")) {
+ js_free(ctx, lower);
+ lower = js_strdup(ctx, "");
+ }
+ return lower;
+}
+
static int locale_parse_u_keywords(JSContext *ctx, const char *u_ext, int u_len,
UKeyword *keywords, int max_kw,
char **attributes)
int j = i;
while (j < u_len && u_ext[j] != '-') j++;
int slen = j - i;
- if (slen == 2 && isalpha((unsigned char)u_ext[i]) &&
- (isalpha((unsigned char)u_ext[i+1]) || isdigit((unsigned char)u_ext[i+1]))) {
+ if (slen == 2 && isalnum((unsigned char)u_ext[i]) &&
+ isalpha((unsigned char)u_ext[i+1])) {
/* keyword key */
char key[3] = {u_ext[i], u_ext[i+1], '\0'};
i = j + 1;
goto fail;
}
{
- const char *cal_val = canonicalize_keyword_value("ca", str);
+ const char *cal_val_raw = canonicalize_keyword_value("ca", str);
+ char *cal_val = canonicalize_u_value(ctx, "ca", cal_val_raw);
+ if (!cal_val) {
+ JS_FreeCString(ctx, str);
+ goto fail;
+ }
/* replace or add keyword */
for (i = 0; i < num_u_keywords; i++) {
if (!strcmp(u_keywords[i].key, "ca")) {
u_keywords[num_u_keywords].value = js_strdup(ctx, cal_val);
num_u_keywords++;
}
+ js_free(ctx, out->calendar);
out->calendar = js_strdup(ctx, cal_val);
+ js_free(ctx, cal_val);
JS_FreeCString(ctx, str);
}
}
JS_ThrowRangeError(ctx, "invalid collation");
goto fail;
}
- for (i = 0; i < num_u_keywords; i++) {
- if (!strcmp(u_keywords[i].key, "co")) {
- js_free(ctx, u_keywords[i].value);
- u_keywords[i].value = js_strdup(ctx, str);
- break;
- }
+ if (!is_valid_type(str)) {
+ JS_FreeCString(ctx, str);
+ JS_ThrowRangeError(ctx, "invalid collation");
+ goto fail;
}
- if (i == num_u_keywords && num_u_keywords < 16) {
- u_keywords[num_u_keywords].key = js_strdup(ctx, "co");
- u_keywords[num_u_keywords].value = js_strdup(ctx, str);
- num_u_keywords++;
+ {
+ char *co_val = canonicalize_u_value(ctx, "co", str);
+ if (!co_val) {
+ JS_FreeCString(ctx, str);
+ goto fail;
+ }
+ for (i = 0; i < num_u_keywords; i++) {
+ if (!strcmp(u_keywords[i].key, "co")) {
+ js_free(ctx, u_keywords[i].value);
+ u_keywords[i].value = js_strdup(ctx, co_val);
+ break;
+ }
+ }
+ if (i == num_u_keywords && num_u_keywords < 16) {
+ u_keywords[num_u_keywords].key = js_strdup(ctx, "co");
+ u_keywords[num_u_keywords].value = js_strdup(ctx, co_val);
+ num_u_keywords++;
+ }
+ js_free(ctx, out->collation);
+ out->collation = js_strdup(ctx, co_val);
+ js_free(ctx, co_val);
}
- out->collation = js_strdup(ctx, str);
JS_FreeCString(ctx, str);
}
if (!str) goto fail;
{
const char *fw_val = weekday_to_u_value(str);
+ char *fw_canon = NULL;
if (!fw_val) {
/* not a weekday name, validate as type */
if (!is_valid_type(str)) {
JS_ThrowRangeError(ctx, "invalid firstDayOfWeek");
goto fail;
}
- fw_val = str;
+ fw_canon = canonicalize_u_value(ctx, "fw", str);
+ if (!fw_canon) {
+ JS_FreeCString(ctx, str);
+ goto fail;
+ }
+ fw_val = fw_canon;
}
for (i = 0; i < num_u_keywords; i++) {
if (!strcmp(u_keywords[i].key, "fw")) {
u_keywords[num_u_keywords].value = js_strdup(ctx, fw_val);
num_u_keywords++;
}
+ js_free(ctx, out->firstDayOfWeek);
out->firstDayOfWeek = js_strdup(ctx, fw_val);
+ js_free(ctx, fw_canon);
}
JS_FreeCString(ctx, str);
}
JS_ThrowRangeError(ctx, "invalid numberingSystem");
goto fail;
}
- for (i = 0; i < num_u_keywords; i++) {
- if (!strcmp(u_keywords[i].key, "nu")) {
- js_free(ctx, u_keywords[i].value);
- u_keywords[i].value = js_strdup(ctx, str);
- break;
- }
+ if (!is_valid_type(str)) {
+ JS_FreeCString(ctx, str);
+ JS_ThrowRangeError(ctx, "invalid numberingSystem");
+ goto fail;
}
- if (i == num_u_keywords && num_u_keywords < 16) {
- u_keywords[num_u_keywords].key = js_strdup(ctx, "nu");
- u_keywords[num_u_keywords].value = js_strdup(ctx, str);
- num_u_keywords++;
+ {
+ char *nu_val = canonicalize_u_value(ctx, "nu", str);
+ if (!nu_val) {
+ JS_FreeCString(ctx, str);
+ goto fail;
+ }
+ for (i = 0; i < num_u_keywords; i++) {
+ if (!strcmp(u_keywords[i].key, "nu")) {
+ js_free(ctx, u_keywords[i].value);
+ u_keywords[i].value = js_strdup(ctx, nu_val);
+ break;
+ }
+ }
+ if (i == num_u_keywords && num_u_keywords < 16) {
+ u_keywords[num_u_keywords].key = js_strdup(ctx, "nu");
+ u_keywords[num_u_keywords].value = js_strdup(ctx, nu_val);
+ num_u_keywords++;
+ }
+ js_free(ctx, out->numberingSystem);
+ out->numberingSystem = js_strdup(ctx, nu_val);
+ js_free(ctx, nu_val);
}
- out->numberingSystem = js_strdup(ctx, str);
JS_FreeCString(ctx, str);
}
}
-test262/test/intl402/Locale/constructor-unicode-extension-uvalue-true.js:20: Test262Error: new Intl.Locale("en-u-0a-true").toString() must be "en-u-0a" Expected SameValue(«"en-u-true"», «"en-u-0a"») to be true
-test262/test/intl402/Locale/constructor-unicode-extension-uvalue-yes.js:20: Test262Error: new Intl.Locale("en-u-0a-yes").toString() must be "en-u-0a-yes" Expected SameValue(«"en-u-yes"», «"en-u-0a-yes"») to be true
-test262/test/intl402/Locale/prototype/calendar/canonicalize-case.js:26: Test262Error: new Intl.Locale("de", {calendar: "GREGORY"}).calendar Expected SameValue(«"GREGORY"», «"gregory"») to be true
-test262/test/intl402/Locale/prototype/collation/canonicalize-case.js:26: Test262Error: new Intl.Locale("de", {collation: "PHONEBK"}).collation Expected SameValue(«"PHONEBK"», «"phonebk"») to be true
-test262/test/intl402/Locale/prototype/firstDayOfWeek/valid-options.js:15: Test262Error: new Intl.Locale("en", { firstDayOfWeek: MON }).firstDayOfWeek returns "mon" Expected SameValue(«"MON"», «"mon"») to be true
test262/test/intl402/Locale/prototype/getCalendars/likely-subtags-region.js:42: Test262Error: No suitable test data found in this implementation. Consider updating the candidate list
test262/test/intl402/Locale/prototype/getCalendars/region-override.js:41: Test262Error: No suitable test data found in this implementation. Consider updating the candidate list
test262/test/intl402/Locale/prototype/getCalendars/region-priority.js:60: Test262Error: Inconclusive: the "rg" region override and the region subtag select regions with identical calendars in this implementation. Consider updating the test data
test262/test/intl402/Locale/prototype/getWeekInfo/region-override.js:45: Test262Error: No suitable test data found in this implementation. Consider updating the candidate list
test262/test/intl402/Locale/prototype/getWeekInfo/region-priority.js:59: Test262Error: Inconclusive: the "rg" region override and the region subtag selected regions with identical week info in this implementation. Consider updating the test data
test262/test/intl402/Locale/prototype/getWeekInfo/subdivision-region.js:39: Test262Error: No suitable test data found in this implementation. Consider updating the candidate list
-test262/test/intl402/Locale/prototype/numberingSystem/canonicalize-case.js:26: Test262Error: new Intl.Locale("de", {numberingSystem: "LATN"}).numberingSystem Expected SameValue(«"LATN"», «"latn"») to be true
test262/test/language/statements/await-using/initializer-Symbol.asyncDispose-disposed-at-end-of-imported-module.js:11: SyntaxError: exported variable 'resource' does not exist
test262/test/language/statements/await-using/initializer-Symbol.dispose-disposed-at-end-of-imported-module.js:11: SyntaxError: exported variable 'resource' does not exist
test262/test/language/statements/using/initializer-disposed-at-end-of-imported-module.js:11: SyntaxError: exported variable 'resource' does not exist