From f02895b1fe50da134094d8565e29a15bae737d9a Mon Sep 17 00:00:00 2001 From: "Ioanna M. Dimitriou H" Date: Fri, 2 Jan 2026 15:30:07 +0000 Subject: [PATCH] Fix polyfill: Throw RangeError when a timestring has fractional minutes This addresses issue https://github.com/tc39/proposal-temporal/issues/3210 The regex parser falls into a corner case for strings with separators that have fractional minutes and no seconds. It ends up parsing `undefined` minutes and interprets the fraction as seconds. Instead of complicating the regex parser, change ParseISODateTime and ParseTemporalTimeString to throw a RangeError if there a fraction is defined, and either: seconds are undefined (safety measure, the regex parser actually takes care of this) or: minutes are undefined and hours are defined. This takes care of the corner case without complicating the regex parser, for readability. --- polyfill/lib/ecmascript.mjs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/polyfill/lib/ecmascript.mjs b/polyfill/lib/ecmascript.mjs index a653fdb0c..629ac72e4 100644 --- a/polyfill/lib/ecmascript.mjs +++ b/polyfill/lib/ecmascript.mjs @@ -437,6 +437,12 @@ export function ParseISODateTime(isoString) { const month = +(match.groups.monthpart ?? 1); const day = +(match.groups.daypart ?? 1); const hasTime = match.groups.hour !== undefined; + const hasMinute = match.groups.minute !== undefined; + const hasSecond = match.groups.second !== undefined; + const hasFraction = match.groups.fraction !== undefined; + if (hasFraction && (!hasSecond || (!hasMinute && hasTime))) { + throw new RangeErrorCtor(`invalid RFC 9557 string: ${isoString}, only seconds may be fractional`); + } const hour = +(match.groups.hour ?? 0); const minute = +(match.groups.minute ?? 0); let second = +(match.groups.second ?? 0); @@ -492,6 +498,13 @@ export function ParseTemporalTimeString(isoString) { let hour, minute, second, millisecond, microsecond, nanosecond, calendar; if (match) { calendar = processAnnotations(match.groups.annotation); + const hasFraction = match.groups.fraction !== undefined; + const hasSecond = match.groups.second !== undefined; + const hasMinute = match.groups.minute !== undefined; + const hasHour = match.groups.hour !== undefined; + if (hasFraction && (!hasSecond || (!hasMinute && hasHour))) { + throw new RangeErrorCtor(`invalid RFC 9557 string: ${isoString}, only seconds may be fractional`); + } hour = +(match.groups.hour ?? 0); minute = +(match.groups.minute ?? 0); second = +(match.groups.second ?? 0);