LibJS+LibWeb: Avoid out of range time values in <input> value strings

This commit is contained in:
Tim Ledbetter 2026-04-07 10:51:00 +01:00 committed by Shannon Booth
parent e1e73d485a
commit e2e401d0e0
4 changed files with 26 additions and 4 deletions

View file

@ -64,6 +64,10 @@ constexpr inline double ms_per_day = 86'400'000;
constexpr inline double ns_per_day = 86'400'000'000'000;
extern Crypto::SignedBigInteger const ns_per_day_bigint;
// https://tc39.es/ecma262/#sec-time-values-and-time-range
// A time value supports a [...] range of -8,640,000,000,000,000 to 8,640,000,000,000,000 milliseconds
constexpr inline double max_time_value = 8.64E15;
double day(double);
double time_within_day(double);
u16 days_in_year(i32);

View file

@ -2567,6 +2567,10 @@ static Utf16String convert_number_to_week_string(double input)
// that represents the week that, in UTC, is current input milliseconds after midnight UTC on the morning of
// 1970-01-01 (the time represented by the value "1970-01-01T00:00:00.0Z").
// AD-HOC: Values outside the valid ECMSScript time value range cannot produce valid date strings.
if (!isfinite(input) || fabs(input) > JS::max_time_value)
return {};
auto year = JS::year_from_time(input);
auto month = JS::month_from_time(input) + 1; // Adjust for zero-based month
auto day = JS::date_from_time(input);
@ -2614,6 +2618,11 @@ static Utf16String convert_number_to_local_date_and_time_string(double input)
// The algorithm to convert a number to a string, given a number input, is as follows: Return a valid
// normalized local date and time string that represents the date and time that is input milliseconds
// after midnight on the morning of 1970-01-01 (the time represented by the value "1970-01-01T00:00:00.0").
// AD-HOC: Values outside the valid ECMSScript time value range cannot produce valid date strings.
if (!isfinite(input) || fabs(input) > JS::max_time_value)
return {};
auto year = JS::year_from_time(input);
auto month = JS::month_from_time(input) + 1; // Adjust for zero-based month
auto day = JS::date_from_time(input);

View file

@ -1,8 +1,9 @@
Harness status: OK
Found 60 tests
Found 64 tests
60 Pass
63 Pass
1 Fail
Pass valueAsNumber getter on type date (actual value: , expected valueAsNumber: NaN)
Pass valueAsNumber getter on type date (actual value: 0000-12-10, expected valueAsNumber: NaN)
Pass valueAsNumber getter on type date (actual value: 2019-00-12, expected valueAsNumber: NaN)
@ -39,11 +40,15 @@ Pass valueAsNumber getter on type time (actual value: 23:59, expected valueAsNum
Pass valueAsNumber setter on type time (actual valueAsNumber: 0, expected value: 00:00)
Pass valueAsNumber setter on type time (actual valueAsNumber: 43200000, expected value: 12:00)
Pass valueAsNumber setter on type time (actual valueAsNumber: 86340000, expected value: 23:59)
Fail valueAsNumber setter on type time (actual valueAsNumber: 2.734333707189448e+26, expected value: 10:54:10.944)
Pass valueAsNumber setter on type time (actual valueAsNumber: -3600000, expected value: 23:00)
Pass valueAsNumber getter on type datetime-local (actual value: , expected valueAsNumber: NaN)
Pass valueAsNumber getter on type datetime-local (actual value: 2019-12-10T00:00, expected valueAsNumber: 1575936000000)
Pass valueAsNumber getter on type datetime-local (actual value: 2019-12-10T12:00, expected valueAsNumber: 1575979200000)
Pass valueAsNumber setter on type datetime-local (actual valueAsNumber: 1575936000000, expected value: 2019-12-10T00:00)
Pass valueAsNumber setter on type datetime-local (actual valueAsNumber: 1575979200000, expected value: 2019-12-10T12:00)
Pass valueAsNumber setter on type datetime-local (actual valueAsNumber: -86400000, expected value: 1969-12-31T00:00)
Pass valueAsNumber setter on type datetime-local (actual valueAsNumber: 2.734333707189448e+26, expected value: )
Pass valueAsNumber getter on type number (actual value: , expected valueAsNumber: NaN)
Pass valueAsNumber getter on type number (actual value: 123, expected valueAsNumber: 123)
Pass valueAsNumber getter on type number (actual value: 123.456, expected valueAsNumber: 123.456)

View file

@ -108,7 +108,9 @@
testValueAsNumberSetter("time", timeInput, [
[0, "00:00"],
[12 * 3600 * 1000, "12:00"],
[((23 * 3600) + (59 * 60)) * 1000, "23:59"]
[((23 * 3600) + (59 * 60)) * 1000, "23:59"],
[2.7343337071894478e26, "10:54:10.944"],
[-3600 * 1000, "23:00"]
]);
const dateTimeLocalInput = document.getElementById("input_datetime-local");
@ -119,7 +121,9 @@
]);
testValueAsNumberSetter("datetime-local", dateTimeLocalInput, [
[1575936000000, "2019-12-10T00:00"],
[1575979200000, "2019-12-10T12:00"]
[1575979200000, "2019-12-10T12:00"],
[-1000 * 3600 * 24, "1969-12-31T00:00"],
[2.7343337071894478e26, ""]
]);
const numberInput = document.getElementById("input_number");