diff --git a/Libraries/LibJS/Runtime/DateConstructor.cpp b/Libraries/LibJS/Runtime/DateConstructor.cpp index 2acfc149314..1488bb0259a 100644 --- a/Libraries/LibJS/Runtime/DateConstructor.cpp +++ b/Libraries/LibJS/Runtime/DateConstructor.cpp @@ -25,7 +25,7 @@ namespace JS { GC_DEFINE_ALLOCATOR(DateConstructor); // 21.4.3.2 Date.parse ( string ), https://tc39.es/ecma262/#sec-date.parse -static double parse_simplified_iso8601(ByteString const& iso_8601) +static Optional parse_simplified_iso8601(ByteString const& iso_8601) { // 21.4.1.15 Date Time String Format, https://tc39.es/ecma262/#sec-date-time-string-format GenericLexer lexer(iso_8601); @@ -127,9 +127,8 @@ static double parse_simplified_iso8601(ByteString const& iso_8601) }; auto lex_time = [&]() { return lex_hours_minutes(hours, minutes) && (!lexer.consume_specific(':') || lex_seconds_milliseconds()) && lex_timezone(); }; - if (!lex_date() || (lexer.consume_specific('T') && !lex_time()) || !lexer.is_eof()) { - return NAN; - } + if (!lex_date() || (lexer.consume_specific('T') && !lex_time()) || !lexer.is_eof()) + return {}; // We parsed a valid date simplified ISO 8601 string. VERIFY(year.has_value()); // A valid date string always has at least a year. @@ -154,9 +153,8 @@ static double parse_date_string(VM& vm, ByteString const& date_string) if (date_string.is_empty()) return NAN; - auto value = parse_simplified_iso8601(date_string); - if (isfinite(value)) - return value; + if (auto time = parse_simplified_iso8601(date_string); time.has_value()) + return *time; // Date.parse() is allowed to accept an arbitrary number of implementation-defined formats. // FIXME: Exactly what timezone and which additional formats we should support is unclear. diff --git a/Libraries/LibJS/Tests/builtins/Date/Date.parse.js b/Libraries/LibJS/Tests/builtins/Date/Date.parse.js index 2490cefe2bc..b4be2553a8f 100644 --- a/Libraries/LibJS/Tests/builtins/Date/Date.parse.js +++ b/Libraries/LibJS/Tests/builtins/Date/Date.parse.js @@ -67,6 +67,12 @@ test("basic functionality", () => { test("time clip", () => { expect(Date.parse("+999999")).toBeNaN(); expect(Date.parse("-999999")).toBeNaN(); + + const belowMinDate = "-271821-04-19T23:59:59.999Z"; + expect(belowMinDate).toBeNaN(); + + const aboveMaxDate = "+275760-09-13T00:00:00.001Z"; + expect(aboveMaxDate).toBeNaN(); }); test("extra micro seconds extension", () => {