[njs] Large indexes processing has been fixed in array iterator
Igor Sysoev
igor at sysoev.ru
Wed Mar 29 12:56:47 UTC 2017
details: http://hg.nginx.org/njs/rev/8cdbd57379e8
branches:
changeset: 322:8cdbd57379e8
user: Igor Sysoev <igor at sysoev.ru>
date: Wed Mar 29 15:54:33 2017 +0300
description:
Large indexes processing has been fixed in array iterator
functions.
diffstat:
njs/njs_array.c | 26 +++++++++++++-------------
njs/njs_array.h | 4 ++++
njs/njs_vm.c | 16 +++++++++++-----
njs/test/njs_unit_test.c | 9 +++++++++
4 files changed, 37 insertions(+), 18 deletions(-)
diffs (168 lines):
diff -r a095dc0cd361 -r 8cdbd57379e8 njs/njs_array.c
--- a/njs/njs_array.c Tue Mar 28 07:50:05 2017 +0300
+++ b/njs/njs_array.c Wed Mar 29 15:54:33 2017 +0300
@@ -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_i
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 *arr
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_
} 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_continu
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;
-
- while (n >= 0) {
+ n = nxt_min(n, array->length) - 1;
+
+ 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;
diff -r a095dc0cd361 -r 8cdbd57379e8 njs/njs_array.h
--- a/njs/njs_array.h Tue Mar 28 07:50:05 2017 +0300
+++ b/njs/njs_array.h Wed Mar 29 15:54:33 2017 +0300
@@ -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
diff -r a095dc0cd361 -r 8cdbd57379e8 njs/njs_vm.c
--- a/njs/njs_vm.c Tue Mar 28 07:50:05 2017 +0300
+++ b/njs/njs_vm.c Wed Mar 29 15:54:33 2017 +0300
@@ -944,9 +944,10 @@ njs_property_query(njs_vm_t *vm, njs_pro
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_pro
return NJS_TRAP_PROPERTY;
}
- index = (int) num;
-
- if (nxt_fast_path(index >= 0 && (double) index == num)) {
- return njs_array_property_query(vm, pq, object, index);
+ if (nxt_fast_path(num >= 0)) {
+ index = (uint32_t) num;
+
+ valid = nxt_expect(1, (index < NJS_ARRAY_MAX_LENGTH
+ && (double) index == num));
+
+ if (valid) {
+ return njs_array_property_query(vm, pq, object, index);
+ }
}
}
diff -r a095dc0cd361 -r 8cdbd57379e8 njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c Tue Mar 28 07:50:05 2017 +0300
+++ b/njs/test/njs_unit_test.c Wed Mar 29 15:54:33 2017 +0300
@@ -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") },
More information about the nginx-devel
mailing list