]> git.kaiwu.me - quickjs.git/commitdiff
fixed argument evaluation order in Date constructor and Date.UTC()
authorFabrice Bellard <fabrice@bellard.org>
Mon, 13 Oct 2025 12:11:47 +0000 (14:11 +0200)
committerFabrice Bellard <fabrice@bellard.org>
Mon, 13 Oct 2025 12:11:47 +0000 (14:11 +0200)
TODO
quickjs.c
test262_errors.txt

diff --git a/TODO b/TODO
index 3e47f55874e8a1bc4312cddd57cb00c4968fe0e3..d6618cfa08da2a2c62c22687655ba829178b513e 100644 (file)
--- a/TODO
+++ b/TODO
@@ -63,4 +63,4 @@ Test262o:   0/11262 errors, 463 excluded
 Test262o commit: 7da91bceb9ce7613f87db47ddd1292a2dda58b42 (es5-tests branch)
 
 Test262:
-Result: 67/83149 errors, 1645 excluded, 5538 skipped
+Result: 63/83149 errors, 1645 excluded, 5538 skipped
index d1c5ed8135a299e1e5b0441d7ece207b1b2afb72..3c28cf70e0f64ecf20528914244e067de8e3e71c 100644 (file)
--- a/quickjs.c
+++ b/quickjs.c
@@ -53236,6 +53236,21 @@ static double set_date_fields(double fields[minimum_length(7)], int is_local) {
     return time_clip(tv);
 }
 
+static double set_date_fields_checked(double fields[minimum_length(7)], int is_local)
+{
+    int i;
+    double a;
+    for(i = 0; i < 7; i++) {
+        a = fields[i];
+        if (!isfinite(a))
+            return NAN;
+        fields[i] = trunc(a);
+        if (i == 0 && fields[0] >= 0 && fields[0] < 100)
+            fields[0] += 1900;
+    }
+    return set_date_fields(fields, is_local);
+}
+
 static JSValue get_date_field(JSContext *ctx, JSValueConst this_val,
                               int argc, JSValueConst *argv, int magic)
 {
@@ -53421,7 +53436,7 @@ static JSValue js_date_constructor(JSContext *ctx, JSValueConst new_target,
     // Date(y, mon, d, h, m, s, ms)
     JSValue rv;
     int i, n;
-    double a, val;
+    double val;
 
     if (JS_IsUndefined(new_target)) {
         /* invoked as function */
@@ -53459,15 +53474,10 @@ static JSValue js_date_constructor(JSContext *ctx, JSValueConst new_target,
         if (n > 7)
             n = 7;
         for(i = 0; i < n; i++) {
-            if (JS_ToFloat64(ctx, &a, argv[i]))
+            if (JS_ToFloat64(ctx, &fields[i], argv[i]))
                 return JS_EXCEPTION;
-            if (!isfinite(a))
-                break;
-            fields[i] = trunc(a);
-            if (i == 0 && fields[0] >= 0 && fields[0] < 100)
-                fields[0] += 1900;
         }
-        val = (i == n) ? set_date_fields(fields, 1) : NAN;
+        val = set_date_fields_checked(fields, 1);
     }
 has_val:
 #if 0
@@ -53497,7 +53507,6 @@ static JSValue js_Date_UTC(JSContext *ctx, JSValueConst this_val,
     // UTC(y, mon, d, h, m, s, ms)
     double fields[] = { 0, 0, 1, 0, 0, 0, 0 };
     int i, n;
-    double a;
 
     n = argc;
     if (n == 0)
@@ -53505,15 +53514,10 @@ static JSValue js_Date_UTC(JSContext *ctx, JSValueConst this_val,
     if (n > 7)
         n = 7;
     for(i = 0; i < n; i++) {
-        if (JS_ToFloat64(ctx, &a, argv[i]))
+        if (JS_ToFloat64(ctx, &fields[i], argv[i]))
             return JS_EXCEPTION;
-        if (!isfinite(a))
-            return JS_NAN;
-        fields[i] = trunc(a);
-        if (i == 0 && fields[0] >= 0 && fields[0] < 100)
-            fields[0] += 1900;
     }
-    return JS_NewFloat64(ctx, set_date_fields(fields, 0));
+    return JS_NewFloat64(ctx, set_date_fields_checked(fields, 0));
 }
 
 /* Date string parsing */
index 223b23286a68ae4a6450dc894b4c8792dadefef3..df0e8fefd12b1c2e4f592ad27d65c54a972317f3 100644 (file)
@@ -7,10 +7,6 @@ test262/test/annexB/language/expressions/assignmenttargettype/callexpression.js:
 test262/test/annexB/language/expressions/assignmenttargettype/cover-callexpression-and-asyncarrowhead.js:20: SyntaxError: invalid assignment left-hand side
 test262/test/language/identifier-resolution/assign-to-global-undefined.js:20: strict mode: expected error
 test262/test/language/module-code/top-level-await/rejection-order.js:20: TypeError: $DONE() not called
-test262/test/staging/sm/Date/UTC-convert-all-arguments.js:13: Test262Error: index 1: expected 42, got Error: didn't throw Expected SameValue(«Error: didn't throw», «42») to be true
-test262/test/staging/sm/Date/UTC-convert-all-arguments.js:13: strict mode: Test262Error: index 1: expected 42, got Error: didn't throw Expected SameValue(«Error: didn't throw», «42») to be true
-test262/test/staging/sm/Date/constructor-convert-all-arguments.js:13: Test262Error: index undefined: expected 42, got Error: didn't throw Expected SameValue(«Error: didn't throw», «42») to be true
-test262/test/staging/sm/Date/constructor-convert-all-arguments.js:13: strict mode: Test262Error: index undefined: expected 42, got Error: didn't throw Expected SameValue(«Error: didn't throw», «42») to be true
 test262/test/staging/sm/Date/two-digit-years.js:26: Test262Error: Expected SameValue(«915177600000», «NaN») to be true
 test262/test/staging/sm/Date/two-digit-years.js:26: strict mode: Test262Error: Expected SameValue(«915177600000», «NaN») to be true
 test262/test/staging/sm/Function/arguments-parameter-shadowing.js:14: Test262Error: Expected SameValue(«true», «false») to be true