[njs] Fixed typed-array ctor when source array is changed while iterating.

Dmitry Volyntsev xeioex at nginx.com
Sat Jun 4 07:20:59 UTC 2022


details:   https://hg.nginx.org/njs/rev/317fae74dc2f
branches:  
changeset: 1874:317fae74dc2f
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Fri Jun 03 23:24:08 2022 -0700
description:
Fixed typed-array ctor when source array is changed while iterating.

Previously, the function used optimization for ordinary arrays with no
gaps (so called fast arrays).  For a fast array code took elements
directly from internal flat C array. The direct pointer may become
invalid as side-effect of custom valueOf() method for an element.

The fix is to eliminate the micro-optimization which uses direct
pointers.

The problem is similar to the 9578cc729205 (0.7.2) commit.

This closes #523 issue on Github.

diffstat:

 src/njs_typed_array.c |  26 +++-----------------------
 1 files changed, 3 insertions(+), 23 deletions(-)

diffs (57 lines):

diff -r e99d83c24517 -r 317fae74dc2f src/njs_typed_array.c
--- a/src/njs_typed_array.c	Thu Jun 02 16:32:38 2022 -0700
+++ b/src/njs_typed_array.c	Fri Jun 03 23:24:08 2022 -0700
@@ -34,7 +34,6 @@ njs_typed_array_alloc(njs_vm_t *vm, njs_
     uint64_t            size, offset;
     njs_int_t           ret;
     njs_value_t         *value, prop;
-    njs_array_t         *src_array;
     njs_typed_array_t   *array, *src_tarray;
     njs_array_buffer_t  *buffer;
 
@@ -43,7 +42,6 @@ njs_typed_array_alloc(njs_vm_t *vm, njs_
     offset = 0;
 
     buffer = NULL;
-    src_array = NULL;
     src_tarray = NULL;
 
     element_size = njs_typed_array_element_size(type);
@@ -115,15 +113,9 @@ njs_typed_array_alloc(njs_vm_t *vm, njs_
         size = (uint64_t) njs_typed_array_length(src_tarray) * element_size;
 
     } else if (njs_is_object(value)) {
-        if (njs_is_fast_array(value)) {
-            src_array = njs_array(value);
-            length = src_array->length;
-
-        } else {
-            ret = njs_object_length(vm, value, &length);
-            if (njs_slow_path(ret == NJS_ERROR)) {
-                return NULL;
-            }
+        ret = njs_object_length(vm, value, &length);
+        if (njs_slow_path(ret == NJS_ERROR)) {
+            return NULL;
         }
 
         size = length * element_size;
@@ -166,18 +158,6 @@ njs_typed_array_alloc(njs_vm_t *vm, njs_
             memcpy(&buffer->u.u8[0], &src_tarray->buffer->u.u8[0], size);
         }
 
-    } else if (src_array != NULL) {
-        for (i = 0; i < length; i++) {
-            ret = njs_value_to_number(vm, &src_array->start[i], &num);
-            if (njs_slow_path(ret == NJS_ERROR)) {
-                return NULL;
-            }
-
-            if (ret == NJS_OK) {
-                njs_typed_array_prop_set(vm, array, i, num);
-            }
-        }
-
     } else if (!njs_is_array_buffer(value) && njs_is_object(value)) {
         for (i = 0; i < length; i++) {
             ret = njs_value_property_i64(vm, value, i, &prop);



More information about the nginx-devel mailing list