]> git.kaiwu.me - njs.git/commitdiff
Fixed Array.prototype.fill() when start object changes "this".
authorDmitry Volyntsev <xeioex@nginx.com>
Mon, 7 Nov 2022 22:22:41 +0000 (14:22 -0800)
committerDmitry Volyntsev <xeioex@nginx.com>
Mon, 7 Nov 2022 22:22:41 +0000 (14:22 -0800)
This fixed #589, #599 issues on Github.

src/njs_array.c
src/njs_object.c
src/test/njs_unit_test.c

index 8bd61c5cd5b9ad2266e138834480c1e1b2676e69..4f6bbd6e3a06c98d37f19a9444d7553623702a2b 100644 (file)
@@ -1832,17 +1832,9 @@ njs_array_prototype_fill(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return ret;
     }
 
-    array = NULL;
-
-    if (njs_is_fast_array(this)) {
-        array = njs_array(this);
-        length = array->length;
-
-    } else {
-        ret = njs_object_length(vm, this, &length);
-        if (njs_slow_path(ret == NJS_ERROR)) {
-            return ret;
-        }
+    ret = njs_object_length(vm, this, &length);
+    if (njs_slow_path(ret == NJS_ERROR)) {
+        return ret;
     }
 
     ret = njs_value_to_integer(vm, njs_arg(args, nargs, 2), &start);
@@ -1866,18 +1858,19 @@ njs_array_prototype_fill(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     value = njs_arg(args, nargs, 1);
 
-    if (array != NULL) {
+    if (njs_is_fast_array(this)) {
+        array = njs_array(this);
+        end = njs_min(end, array->length);
+
         for (i = start; i < end; i++) {
-            array->start[i] = *value;
+            njs_value_assign(&array->start[i], value);
         }
 
-        vm->retval = *this;
+        njs_value_assign(&vm->retval, this);
 
         return NJS_OK;
     }
 
-    value = njs_arg(args, nargs, 1);
-
     while (start < end) {
         ret = njs_value_property_i64_set(vm, this, start++, value);
         if (njs_slow_path(ret == NJS_ERROR)) {
@@ -1885,7 +1878,7 @@ njs_array_prototype_fill(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
     }
 
-    vm->retval = *this;
+    njs_value_assign(&vm->retval, this);
 
     return NJS_OK;
 }
index 0ccbeff01cf63aae0ec5af3842bfbba4d4b078db..7d9cb0953336c8bd47afc2149ff9652a35321031 100644 (file)
@@ -2505,6 +2505,11 @@ njs_object_length(njs_vm_t *vm, njs_value_t *value, int64_t *length)
 
     const njs_value_t  string_length = njs_string("length");
 
+    if (njs_is_fast_array(value)) {
+        *length = njs_array(value)->length;
+        return NJS_OK;
+    }
+
     ret = njs_value_property(vm, value, njs_value_arg(&string_length),
                              &value_length);
     if (njs_slow_path(ret == NJS_ERROR)) {
index 43c2676b3a2943fdba6911e36abd9aeda7212ab7..dc56d7e48322d1e803b2168c3969aab212036000 100644 (file)
@@ -5549,6 +5549,15 @@ static njs_unit_test_t  njs_test[] =
                  "Array.prototype.fill.call(o, 2).a"),
       njs_str("4") },
 
+    { njs_str("var a = (new Array(2**10)).fill(0);"
+              "var start = {valueOf() {"
+              "                 var len = a.length - 2;"
+              "                 for (var i = 0; i < len; i++) { a.shift(); }; "
+              "                 return 0;"
+              "            }};"
+              "a.fill('xxx', start)"),
+      njs_str("xxx,xxx") },
+
     { njs_str("Array.prototype.fill.call(new Int32Array(1))"),
       njs_str("0") },