[njs] Improved arguments parsing in Date constructor.

Dmitry Volyntsev xeioex at nginx.com
Wed Jun 2 14:10:21 UTC 2021


details:   https://hg.nginx.org/njs/rev/687d9eacbe33
branches:  
changeset: 1649:687d9eacbe33
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Wed Jun 02 14:10:03 2021 +0000
description:
Improved arguments parsing in Date constructor.

diffstat:

 src/njs_date.c           |  123 +++++++++++++++++++---------------------------
 src/test/njs_unit_test.c |    9 +++
 2 files changed, 60 insertions(+), 72 deletions(-)

diffs (197 lines):

diff -r befc2827d2d2 -r 687d9eacbe33 src/njs_date.c
--- a/src/njs_date.c	Wed Jun 02 13:25:32 2021 +0000
+++ b/src/njs_date.c	Wed Jun 02 14:10:03 2021 +0000
@@ -311,12 +311,47 @@ njs_destruct_date(double time, int64_t t
 
 
 static njs_int_t
+njs_date_args(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
+    int64_t tm[])
+{
+    double      num;
+    njs_int_t   ret;
+    njs_uint_t  i, n;
+
+    njs_memzero(tm, NJS_DATE_MAX_FIELDS * sizeof(int64_t));
+
+    tm[NJS_DATE_DAY] = 1;
+
+    n = njs_min(8, nargs);
+
+    for (i = 1; i < n; i++) {
+        ret = njs_value_to_number(vm, &args[i], &num);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return ret;
+        }
+
+        if (!isfinite(num)) {
+            tm[NJS_DATE_YR] = INT64_MIN;
+            continue;
+        }
+
+        tm[i] = njs_number_to_integer(num);
+    }
+
+    if (tm[NJS_DATE_YR] >= 0 && tm[NJS_DATE_YR] < 100) {
+        tm[NJS_DATE_YR] += 1900;
+    }
+
+    return NJS_OK;
+}
+
+
+static njs_int_t
 njs_date_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double      num, time;
+    double      time;
     njs_int_t   ret;
-    njs_uint_t  i, n;
     njs_date_t  *date;
     int64_t     tm[NJS_DATE_MAX_FIELDS];
 
@@ -350,40 +385,14 @@ njs_date_constructor(njs_vm_t *vm, njs_v
 
     } else {
 
-        time = NAN;
-
-        njs_memzero(tm, NJS_DATE_MAX_FIELDS * sizeof(int64_t));
-
-        tm[NJS_DATE_DAY] = 1;
-
-        n = njs_min(8, nargs);
-
-        for (i = 1; i < n; i++) {
-            if (!njs_is_numeric(&args[i])) {
-                ret = njs_value_to_numeric(vm, &args[i], &args[i]);
-                if (njs_slow_path(ret != NJS_OK)) {
-                    return ret;
-                }
-            }
-
-            num = njs_number(&args[i]);
-
-            if (isnan(num) || isinf(num)) {
-                goto done;
-            }
-
-            tm[i] = num;
-        }
-
-        if (tm[NJS_DATE_YR] >= 0 && tm[NJS_DATE_YR] < 100) {
-            tm[NJS_DATE_YR] += 1900;
+        ret = njs_date_args(vm, args, nargs, tm);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return ret;
         }
 
         time = njs_make_date(tm, 1);
     }
 
-done:
-
     date = njs_mp_alloc(vm->mem_pool, sizeof(njs_date_t));
     if (njs_slow_path(date == NULL)) {
         njs_memory_error(vm);
@@ -412,47 +421,21 @@ static njs_int_t
 njs_date_utc(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double      num, time;
+    double      time;
     njs_int_t   ret;
-    njs_uint_t  i, n;
     int64_t     tm[NJS_DATE_MAX_FIELDS];
 
     time = NAN;
 
     if (nargs > 1) {
-        njs_memzero(tm, NJS_DATE_MAX_FIELDS * sizeof(int64_t));
-
-        tm[NJS_DATE_DAY] = 1;
-
-        n = njs_min(8, nargs);
-
-        for (i = 1; i < n; i++) {
-            if (!njs_is_numeric(&args[i])) {
-                ret = njs_value_to_numeric(vm, &args[i], &args[i]);
-                if (ret != NJS_OK) {
-                    return ret;
-                }
-            }
-
-            num = njs_number(&args[i]);
-
-            if (isnan(num) || isinf(num)) {
-                goto done;
-            }
-
-            tm[i] = num;
-        }
-
-        /* Year. */
-        if (tm[NJS_DATE_YR] >= 0 && tm[NJS_DATE_YR] < 100) {
-            tm[NJS_DATE_YR] += 1900;
+        ret = njs_date_args(vm, args, nargs, tm);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return ret;
         }
 
         time = njs_make_date(tm, 0);
     }
 
-done:
-
     njs_set_number(&vm->retval, time);
 
     return NJS_OK;
@@ -1385,21 +1368,17 @@ njs_date_prototype_set_fields(njs_vm_t *
     njs_destruct_date(time, tm, 0, magic & 0x40);
 
     do {
-        if (njs_slow_path(!njs_is_number(&args[i]))) {
-            ret = njs_value_to_numeric(vm, &args[i], &args[i]);
-            if (njs_slow_path(ret != NJS_OK)) {
-                return ret;
-            }
+        ret = njs_value_to_number(vm, &args[i++], &num);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return ret;
         }
 
-        num = njs_number(&args[i++]);
-
-        if (isnan(num) || isinf(num)) {
-            time = NAN;
-            goto done;
+        if (!isfinite(num)) {
+            tm[NJS_DATE_YR] = INT64_MIN;
+            continue;
         }
 
-        tm[since++] = num;
+        tm[since++] = njs_number_to_integer(num);
 
     } while (--left);
 
diff -r befc2827d2d2 -r 687d9eacbe33 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c	Wed Jun 02 13:25:32 2021 +0000
+++ b/src/test/njs_unit_test.c	Wed Jun 02 14:10:03 2021 +0000
@@ -14655,6 +14655,15 @@ static njs_unit_test_t  njs_test[] =
     { njs_str("new Date(NaN)"),
       njs_str("Invalid Date") },
 
+    { njs_str("new Date(1,undefined)"),
+      njs_str("Invalid Date") },
+
+    { njs_str("new Date(1,Infinity)"),
+      njs_str("Invalid Date") },
+
+    { njs_str("new Date(1,NaN)"),
+      njs_str("Invalid Date") },
+
     { njs_str("new Date(8.65e15)"),
       njs_str("Invalid Date") },
 


More information about the nginx-devel mailing list