LibJS: Adjust ad-hoc clamping behavior in RegulateISODate

Instead of clamping to the limits allowed by ISOYearMonthWithinLimits,
clamp to the limits allowed by the type we are converting to (i32). This
allows some callers to then reject years outside that range.
This commit is contained in:
Timothy Flynn 2025-01-16 08:46:49 -05:00 committed by Andreas Kling
parent d5b26183f3
commit 59162c8155
Notes: github-actions[bot] 2025-01-17 09:09:06 +00:00
2 changed files with 13 additions and 6 deletions

View file

@ -2,12 +2,13 @@
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
* Copyright (c) 2021-2023, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2024, Shannon Booth <shannon@serenityos.org>
* Copyright (c) 2024, Tim Flynn <trflynn89@ladybird.org>
* Copyright (c) 2024-2025, Tim Flynn <trflynn89@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Checked.h>
#include <AK/NumericLimits.h>
#include <LibJS/Runtime/AbstractOperations.h>
#include <LibJS/Runtime/Temporal/Calendar.h>
#include <LibJS/Runtime/Temporal/DateEquations.h>
@ -202,9 +203,10 @@ ThrowCompletionOr<ISODate> regulate_iso_date(VM& vm, double year, double month,
// c. Set day to the result of clamping day between 1 and daysInMonth.
day = clamp(day, 1, iso_days_in_month(year, month));
// AD-HOC: We further clamp the year to the range allowed by ISOYearMonthWithinLimits, to ensure we do not
// overflow when we store the year as an integer.
year = clamp(year, -271821, 275760);
// AD-HOC: We further clamp the year to the range allowed by ISODate.year, to ensure we do not overflow when we
// store the year as an integer.
using YearType = decltype(declval<ISODate>().year);
year = clamp(year, static_cast<double>(NumericLimits<YearType>::min()), static_cast<double>(NumericLimits<YearType>::max()));
break;

View file

@ -87,10 +87,15 @@ describe("errors", () => {
});
test("relativeTo with invalid date", () => {
const duration = new Temporal.Duration(0, 0, 0, 31);
expect(() => {
const duration = new Temporal.Duration(0, 0, 0, 31);
duration.total({ unit: "minute", relativeTo: "-271821-04-19" });
}).toThrowWithMessage(RangeError, "Invalid ISO date time");
expect(() => {
const duration = new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
const relativeTo = new Temporal.ZonedDateTime(864n * 10n ** 19n - 1n, "UTC");
duration.total({ unit: "years", relativeTo: relativeTo });
}).toThrowWithMessage(RangeError, "Invalid ISO date");
});
});