]> git.kaiwu.me - njs.git/commitdiff
Large indexes processing has been fixed in array iterator
authorIgor Sysoev <igor@sysoev.ru>
Wed, 29 Mar 2017 12:54:33 +0000 (15:54 +0300)
committerIgor Sysoev <igor@sysoev.ru>
Wed, 29 Mar 2017 12:54:33 +0000 (15:54 +0300)
functions.

njs/njs_array.c
njs/njs_array.h
njs/njs_vm.c
njs/test/njs_unit_test.c

index 9149cbf7ac9a414d9c3ecce3c08874d1a40fecaa..f5ac692f9cf3f2b4ae85759ed420c511728c65ca 100644 (file)
@@ -75,7 +75,7 @@ typedef struct {
     njs_value_t             retval;
 
     njs_function_t          *function;
-    int32_t                 index;
+    uint32_t                index;
     uint32_t                current;
 } njs_array_sort_t;
 
@@ -105,7 +105,7 @@ static nxt_noinline uint32_t njs_array_iterator_next(njs_array_t *array,
     uint32_t n, uint32_t length);
 static nxt_noinline njs_ret_t njs_array_iterator_apply(njs_vm_t *vm,
     njs_array_iter_t *iter, njs_value_t *args, nxt_uint_t nargs);
-static uint32_t njs_array_reduce_right_next(njs_array_t *array, int32_t n);
+static uint32_t njs_array_reduce_right_next(njs_array_t *array, uint32_t n);
 static njs_ret_t njs_array_prototype_sort_continuation(njs_vm_t *vm,
     njs_value_t *args, nxt_uint_t nargs, njs_index_t unused);
 
@@ -1520,7 +1520,7 @@ static njs_ret_t
 njs_array_prototype_reduce_continuation(njs_vm_t *vm, njs_value_t *args,
     nxt_uint_t nargs, njs_index_t unused)
 {
-    nxt_int_t         n;
+    uint32_t          n;
     njs_array_t       *array;
     njs_value_t       arguments[5];
     njs_array_iter_t  *iter;
@@ -1588,7 +1588,7 @@ njs_array_iterator_next(njs_array_t *array, uint32_t n, uint32_t length)
         n++;
     }
 
-    return -1;
+    return NJS_ARRAY_INVALID_INDEX;
 }
 
 
@@ -1596,7 +1596,7 @@ static nxt_noinline njs_ret_t
 njs_array_iterator_apply(njs_vm_t *vm, njs_array_iter_t *iter,
     njs_value_t *args, nxt_uint_t nargs)
 {
-    nxt_int_t    n;
+    uint32_t     n;
     njs_array_t  *array;
     njs_value_t  arguments[4];
 
@@ -1632,7 +1632,7 @@ static njs_ret_t
 njs_array_prototype_reduce_right(njs_vm_t *vm, njs_value_t *args,
     nxt_uint_t nargs, njs_index_t unused)
 {
-    int32_t           n;
+    uint32_t          n;
     njs_array_t       *array;
     njs_array_iter_t  *iter;
 
@@ -1652,7 +1652,7 @@ njs_array_prototype_reduce_right(njs_vm_t *vm, njs_value_t *args,
     } else {
         n = iter->next_index;
 
-        if (n < 0) {
+        if (n == NJS_ARRAY_INVALID_INDEX) {
             goto type_error;
         }
 
@@ -1675,7 +1675,7 @@ static njs_ret_t
 njs_array_prototype_reduce_right_continuation(njs_vm_t *vm, njs_value_t *args,
     nxt_uint_t nargs, njs_index_t unused)
 {
-    nxt_int_t         n;
+    uint32_t          n;
     njs_array_t       *array;
     njs_value_t       arguments[5];
     njs_array_iter_t  *iter;
@@ -1708,11 +1708,11 @@ njs_array_prototype_reduce_right_continuation(njs_vm_t *vm, njs_value_t *args,
 
 
 static nxt_noinline uint32_t
-njs_array_reduce_right_next(njs_array_t *array, int32_t n)
+njs_array_reduce_right_next(njs_array_t *array, uint32_t n)
 {
-    n = nxt_min(n, (int32_t) array->length) - 1;
+    n = nxt_min(n, array->length) - 1;
 
-    while (n >= 0) {
+    while (n != NJS_ARRAY_INVALID_INDEX) {
         if (njs_is_valid(&array->start[n])) {
             return n;
         }
@@ -1789,7 +1789,7 @@ static njs_ret_t
 njs_array_prototype_sort_continuation(njs_vm_t *vm, njs_value_t *args,
     nxt_uint_t nargs, njs_index_t unused)
 {
-    nxt_int_t         n;
+    uint32_t          n;
     njs_array_t       *array;
     njs_value_t       value, *start, arguments[3];
     njs_array_sort_t  *sort;
index a4b05031df4574c5d7352351c4121234929bc999..320c2d958643b7797d92af6d34d6b945faa512bf 100644 (file)
@@ -8,6 +8,10 @@
 #define _NJS_ARRAY_H_INCLUDED_
 
 
+#define NJS_ARRAY_MAX_LENGTH     0xffffffff
+/* The maximum valid array index is the maximum array length minus 1. */
+#define NJS_ARRAY_INVALID_INDEX  NJS_ARRAY_MAX_LENGTH
+
 #define NJS_ARRAY_SPARE  8
 
 
index d16cbf608ff8000d372483ce564b3735c9233f59..9e9f357aa345aad768d6b8d8fde7e1835ffd6182 100644 (file)
@@ -944,9 +944,10 @@ njs_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_value_t *object,
     njs_value_t *property)
 {
     double          num;
-    int32_t         index;
+    uint32_t        index;
     uint32_t        (*hash)(const void *, size_t);
     njs_ret_t       ret;
+    nxt_bool_t      valid;
     njs_extern_t    *ext;
     njs_object_t    *obj;
     njs_function_t  *function;
@@ -983,10 +984,15 @@ njs_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_value_t *object,
                 return NJS_TRAP_PROPERTY;
             }
 
-            index = (int) num;
+            if (nxt_fast_path(num >= 0)) {
+                index = (uint32_t) num;
 
-            if (nxt_fast_path(index >= 0 && (double) index == num)) {
-                return njs_array_property_query(vm, pq, object, index);
+                valid = nxt_expect(1, (index < NJS_ARRAY_MAX_LENGTH
+                                       && (double) index == num));
+
+                if (valid) {
+                    return njs_array_property_query(vm, pq, object, index);
+                }
             }
         }
 
index 495e02882bbd8baf33a3a2cecc4b6187b18cc962..24974b2264bc1191e393808b055525764d8c4f4e 100644 (file)
@@ -2280,6 +2280,15 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("var a = [ 1, 2, 3 ]; a[0] + a[1] + a[2]"),
       nxt_string("6") },
 
+    { nxt_string("var a = [ 1, 2, 3 ]; a[-1] = 4; a + a[-1]"),
+      nxt_string("1,2,34") },
+
+    { nxt_string("var a = [ 1, 2, 3 ]; a[4294967295] = 4; a + a[4294967295]"),
+      nxt_string("1,2,34") },
+
+    { nxt_string("var a = [ 1, 2, 3 ]; a[4294967296] = 4; a + a[4294967296]"),
+      nxt_string("1,2,34") },
+
     { nxt_string("var n = 1, a = [ n += 1 ]; a"),
       nxt_string("2") },