Skip to content

Commit

Permalink
Fix: Fix calendar validation in ToTemporal___ operations
Browse files Browse the repository at this point in the history
In ToRelativeTemporalObject, ToTemporalDateTime, ToTemporalMonthDay,
ToTemporalYearMonth, and ToTemporalZonedDateTime, PR #2482 mistakenly left
out the validation of the calendar name when parsing a string.

The validation in ToTemporalDate was incorrect, because it should not have
accepted ISO strings as calendar identifiers, which
ToTemporalCalendarSlotValue would have, e.g.:

    Temporal.PlainDate.from('2023-04-13[u-ca=2023-04-13]')

(would return a PlainDate with the iso8601 calendar, instead of throwing)

Closes: #2546

UPSTREAM_COMMIT=8e9a39835836cb255a702459a2af9adf75c792c0
  • Loading branch information
ptomato authored and justingrant committed Apr 26, 2023
1 parent 16669e8 commit 72e72a1
Showing 1 changed file with 16 additions and 9 deletions.
25 changes: 16 additions & 9 deletions lib/ecmascript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1217,7 +1217,8 @@ export function ToRelativeTemporalObject(options: {
);
}
if (!calendar) calendar = 'iso8601';
calendar = ToTemporalCalendarSlotValue(calendar);
if (!IsBuiltinCalendar(calendar)) throw new RangeError(`invalid calendar identifier ${calendar}`);
calendar = ASCIILowercase(calendar);
}
if (timeZone === undefined) return CreateTemporalDate(year, month, day, calendar);
// If offset is missing here, then offsetBehavior will never be be 'option'.
Expand Down Expand Up @@ -1460,10 +1461,12 @@ export function ToTemporalDate(
return CalendarDateFromFields(calendar, fields, options);
}
ToTemporalOverflow(options); // validate and ignore
const { year, month, day, calendar, z } = ParseTemporalDateString(ToString(item));
let { year, month, day, calendar, z } = ParseTemporalDateString(ToString(item));
if (z) throw new RangeError('Z designator not supported for PlainDate');
const TemporalPlainDate = GetIntrinsic('%Temporal.PlainDate%');
return new TemporalPlainDate(year, month, day, calendar); // include validation
if (!calendar) calendar = 'iso8601';
if (!IsBuiltinCalendar(calendar)) throw new RangeError(`invalid calendar identifier ${calendar}`);
calendar = ASCIILowercase(calendar);
return CreateTemporalDate(year, month, day, calendar);
}

export function InterpretTemporalDateTimeFields(
Expand Down Expand Up @@ -1548,8 +1551,9 @@ export function ToTemporalDateTime(item: PlainDateTimeParams['from'][0], options
ParseTemporalDateTimeString(ToString(item)));
if (z) throw new RangeError('Z designator not supported for PlainDateTime');
RejectDateTime(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond);
if (calendar === undefined) calendar = 'iso8601';
calendar = ToTemporalCalendarSlotValue(calendar);
if (!calendar) calendar = 'iso8601';
if (!IsBuiltinCalendar(calendar)) throw new RangeError(`invalid calendar identifier ${calendar}`);
calendar = ASCIILowercase(calendar);
}
return CreateTemporalDateTime(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond, calendar);
}
Expand Down Expand Up @@ -1618,7 +1622,8 @@ export function ToTemporalMonthDay(
ToTemporalOverflow(options); // validate and ignore
let { month, day, referenceISOYear, calendar } = ParseTemporalMonthDayString(ToString(item));
if (calendar === undefined) calendar = 'iso8601';
calendar = ToTemporalCalendarSlotValue(calendar);
if (!IsBuiltinCalendar(calendar)) throw new RangeError(`invalid calendar identifier ${calendar}`);
calendar = ASCIILowercase(calendar);

if (referenceISOYear === undefined) {
RejectISODate(1972, month, day);
Expand Down Expand Up @@ -1683,7 +1688,8 @@ export function ToTemporalYearMonth(
ToTemporalOverflow(options); // validate and ignore
let { year, month, referenceISODay, calendar } = ParseTemporalYearMonthString(ToString(item));
if (calendar === undefined) calendar = 'iso8601';
calendar = ToTemporalCalendarSlotValue(calendar);
if (!IsBuiltinCalendar(calendar)) throw new RangeError(`invalid calendar identifier ${calendar}`);
calendar = ASCIILowercase(calendar);

if (referenceISODay === undefined) {
RejectISODate(year, month, 1);
Expand Down Expand Up @@ -1830,7 +1836,8 @@ export function ToTemporalZonedDateTime(
offsetBehaviour = 'wall';
}
if (!calendar) calendar = 'iso8601';
calendar = ToTemporalCalendarSlotValue(calendar);
if (!IsBuiltinCalendar(calendar)) throw new RangeError(`invalid calendar identifier ${calendar}`);
calendar = ASCIILowercase(calendar);
matchMinute = true; // ISO strings may specify offset with less precision
disambiguation = ToTemporalDisambiguation(options);
offsetOpt = ToTemporalOffset(options, 'reject');
Expand Down

0 comments on commit 72e72a1

Please sign in to comment.