From 69da8125d010b67c4e71509fa06cd80777bae0d9 Mon Sep 17 00:00:00 2001 From: Jesse Alama Date: Thu, 5 Mar 2026 15:55:12 +0100 Subject: [PATCH 1/3] Polyfill: Replace unreachable overshoot with assertion in calendarToIsoDate --- polyfill/lib/calendar.mjs | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/polyfill/lib/calendar.mjs b/polyfill/lib/calendar.mjs index 52a17254b..63de87011 100644 --- a/polyfill/lib/calendar.mjs +++ b/polyfill/lib/calendar.mjs @@ -987,7 +987,6 @@ const nonIsoHelperBase = { let increment = 8; while (sign) { isoEstimate = ES.AddDaysToISODate(isoEstimate, sign * increment); - const oldRoundtripEstimate = roundtripEstimate; roundtripEstimate = this.isoToCalendarDate(isoEstimate, cache); const oldSign = sign; sign = this.compareCalendarDates(date, roundtripEstimate); @@ -998,25 +997,10 @@ const nonIsoHelperBase = { // Signal the loop condition that there's a match. sign = 0; } else if (oldSign && sign !== oldSign) { - if (increment > 1) { - // If the estimate overshot the target, try again with a smaller increment - // in the reverse direction. - increment /= 2; - } else { - // Increment is 1, and neither the previous estimate nor the new - // estimate is correct. The only way that can happen is if the - // original date was an invalid value that will be constrained or - // rejected here. - if (overflow === 'reject') { - throw new RangeErrorCtor(`Can't find ISO date from calendar date: ${JSONStringify({ ...originalDate })}`); - } else { - // To constrain, pick the earliest value - const order = this.compareCalendarDates(roundtripEstimate, oldRoundtripEstimate); - // If current value is larger, then back up to the previous value. - if (order > 0) isoEstimate = ES.AddDaysToISODate(isoEstimate, -1); - sign = 0; - } - } + /* c8 ignore next */ + assertNotReached( + `calendarToIsoDate binary search should not overshoot (increment ${increment} cannot skip a month)` + ); } } } From 501d4ae1c7f636c103d1e02449e3d4f35f114997 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Thu, 5 Mar 2026 12:15:03 -0800 Subject: [PATCH 2/3] (fixup) Convert assertNotReached into assert --- polyfill/lib/calendar.mjs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/polyfill/lib/calendar.mjs b/polyfill/lib/calendar.mjs index 63de87011..b9af42fb3 100644 --- a/polyfill/lib/calendar.mjs +++ b/polyfill/lib/calendar.mjs @@ -996,9 +996,9 @@ const nonIsoHelperBase = { isoEstimate = calculateSameMonthResult(diff.days); // Signal the loop condition that there's a match. sign = 0; - } else if (oldSign && sign !== oldSign) { - /* c8 ignore next */ - assertNotReached( + } else { + assert( + !oldSign || sign === oldSign, `calendarToIsoDate binary search should not overshoot (increment ${increment} cannot skip a month)` ); } From faf750a8c21366f89e64f221716a146c26045e19 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Thu, 5 Mar 2026 12:29:22 -0800 Subject: [PATCH 3/3] (fixup) Simplify and update comments --- polyfill/lib/calendar.mjs | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/polyfill/lib/calendar.mjs b/polyfill/lib/calendar.mjs index b9af42fb3..d50ece6df 100644 --- a/polyfill/lib/calendar.mjs +++ b/polyfill/lib/calendar.mjs @@ -982,27 +982,22 @@ const nonIsoHelperBase = { sign = this.compareCalendarDates(date, roundtripEstimate); } } - // If the initial guess is not in the same month, then bisect the - // distance to the target, starting with 8 days per step. - let increment = 8; + // If the initial guess is not in the same month, search in 8-day increments + // towards the target, until we get into the same month. From there we can + // calculate the number of days directly. + const increment = 8; + const oldSign = sign; while (sign) { isoEstimate = ES.AddDaysToISODate(isoEstimate, sign * increment); roundtripEstimate = this.isoToCalendarDate(isoEstimate, cache); - const oldSign = sign; sign = this.compareCalendarDates(date, roundtripEstimate); - if (sign) { - diff = simpleDateDiff(date, roundtripEstimate); - if (diff.years === 0 && diff.months === 0) { - isoEstimate = calculateSameMonthResult(diff.days); - // Signal the loop condition that there's a match. - sign = 0; - } else { - assert( - !oldSign || sign === oldSign, - `calendarToIsoDate binary search should not overshoot (increment ${increment} cannot skip a month)` - ); - } + if (sign === 0) break; + diff = simpleDateDiff(date, roundtripEstimate); + if (diff.years === 0 && diff.months === 0) { + isoEstimate = calculateSameMonthResult(diff.days); + break; } + assert(sign === oldSign, 'calendarToIsoDate search should not overshoot a month entirely'); } cache.set(key, isoEstimate); if (keyOriginal) cache.set(keyOriginal, isoEstimate);