From: Igor Sysoev Date: Wed, 29 Mar 2017 12:54:33 +0000 (+0300) Subject: Large indexes processing has been fixed in array iterator X-Git-Tag: 0.1.10~16 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=52022641eb61129250a9f3f0d19cafab0c3ef275;p=njs.git Large indexes processing has been fixed in array iterator functions. --- diff --git a/njs/njs_array.c b/njs/njs_array.c index 9149cbf7..f5ac692f 100644 --- a/njs/njs_array.c +++ b/njs/njs_array.c @@ -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; diff --git a/njs/njs_array.h b/njs/njs_array.h index a4b05031..320c2d95 100644 --- a/njs/njs_array.h +++ b/njs/njs_array.h @@ -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 --git a/njs/njs_vm.c b/njs/njs_vm.c index d16cbf60..9e9f357a 100644 --- a/njs/njs_vm.c +++ b/njs/njs_vm.c @@ -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); + } } } diff --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index 495e0288..24974b22 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -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") },