Skip to content

Commit 2ae0560

Browse files
committed
Fix parsing dates with more than 9 contiguous digits
Most engines like v8, and current versions of spidermonkey versions (128 at least) return NaN while QuickJS parses up to 9 digits at a time, then tries to parse the rest. Trying to parse extra digits can sometimes produce random garbage. To fix it, when parsing the initial integer parse as many digits as we can (max = 0) instead of just 9. Add a few tests, including uncommenting some previous ones, and ensure they pass on v8 version 11. Fixes: #384
1 parent 6e2e68f commit 2ae0560

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

quickjs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50245,7 +50245,7 @@ static BOOL js_date_parse_otherstring(const uint8_t *sp,
5024550245
*is_local = FALSE;
5024650246
} else {
5024750247
p++;
50248-
if (string_get_digits(sp, &p, &val, 1, 9)) {
50248+
if (string_get_digits(sp, &p, &val, 1, 0)) {
5024950249
if (c == '-') {
5025050250
if (val == 0)
5025150251
return FALSE;
@@ -50256,7 +50256,7 @@ static BOOL js_date_parse_otherstring(const uint8_t *sp,
5025650256
}
5025750257
}
5025850258
} else
50259-
if (string_get_digits(sp, &p, &val, 1, 9)) {
50259+
if (string_get_digits(sp, &p, &val, 1, 0)) {
5026050260
if (string_skip_char(sp, &p, ':')) {
5026150261
/* time part */
5026250262
fields[3] = val;

tests/test_builtin.js

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -540,12 +540,40 @@ function test_date()
540540
// is not a valid instance of this format.
541541
// Hence the fractional part after . should have 3 digits and how
542542
// a different number of digits is handled is implementation defined.
543+
// As of March, 2025 these tests match the results of v8 11.3
543544
assert(Date.parse(""), NaN);
545+
assert(Date.parse("0"), 946702800000);
546+
assert(Date.parse("1"), 978325200000);
547+
assert(Date.parse("10"), 1001908800000);
548+
assert(Date.parse("12"), 1007182800000);
549+
assert(Date.parse("13"), NaN);
550+
assert(Date.parse("31"), NaN);
551+
assert(Date.parse("32"), 1956546000000);
552+
assert(Date.parse("49"), 2493090000000);
553+
assert(Date.parse("50"), -631134000000);
554+
assert(Date.parse("69"), -31518000000);
555+
assert(Date.parse("70"), 18000000);
556+
assert(Date.parse("71"), 31554000000);
557+
assert(Date.parse("99"), 915166800000);
558+
assert(Date.parse("1000"), -30610224000000);
559+
assert(Date.parse("1969"), -31536000000);
560+
assert(Date.parse("1970"), 0);
544561
assert(Date.parse("2000"), 946684800000);
562+
assert(Date.parse("9999"), 253370764800000);
563+
assert(Date.parse("99999"), 3093496462800000);
564+
assert(Date.parse("275760"), 8639977899600000);
565+
assert(Date.parse("275761"), NaN);
566+
assert(Date.parse("999999"), NaN);
567+
assert(Date.parse("-271821"), NaN);
568+
assert(Date.parse("-271820"), -8639977881600000);
569+
assert(Date.parse("-100000"), -3217862419200000);
570+
assert(Date.parse("+100000"), 3093527980800000);
571+
assert(Date.parse("+275760"), 8639977881600000);
572+
assert(Date.parse("+275761"), NaN);
545573
assert(Date.parse("2000-01"), 946684800000);
546574
assert(Date.parse("2000-01-01"), 946684800000);
547-
//assert(Date.parse("2000-01-01T"), NaN);
548-
//assert(Date.parse("2000-01-01T00Z"), NaN);
575+
assert(Date.parse("2000-01-01T"), NaN);
576+
assert(Date.parse("2000-01-01T00Z"), NaN);
549577
assert(Date.parse("2000-01-01T00:00Z"), 946684800000);
550578
assert(Date.parse("2000-01-01T00:00:00Z"), 946684800000);
551579
assert(Date.parse("2000-01-01T00:00:00.1Z"), 946684800100);

0 commit comments

Comments
 (0)