details: https://hg.nginx.org/njs/rev/434c654ef638 branches: changeset: 912:434c654ef638 user: Alexander Borisov <alexander.bori...@nginx.com> date: Fri Apr 19 17:48:39 2019 +0300 description: Added uint32_t overflow check for njs_array_alloc() function.
diffstat: njs/njs_array.c | 24 +++++++++++++++++------- njs/njs_array.h | 10 +++++----- njs/njs_object.c | 4 ++-- njs/test/njs_unit_test.c | 6 ++++++ 4 files changed, 30 insertions(+), 14 deletions(-) diffs (110 lines): diff -r a6c82ddff460 -r 434c654ef638 njs/njs_array.c --- a/njs/njs_array.c Fri Apr 19 20:03:49 2019 +0800 +++ b/njs/njs_array.c Fri Apr 19 17:48:39 2019 +0300 @@ -125,22 +125,26 @@ static njs_ret_t njs_array_prototype_sor nxt_noinline njs_array_t * -njs_array_alloc(njs_vm_t *vm, uint32_t length, uint32_t spare) +njs_array_alloc(njs_vm_t *vm, uint64_t length, uint32_t spare) { uint64_t size; njs_array_t *array; + if (nxt_slow_path(length > UINT32_MAX)) { + goto overflow; + } + + size = length + spare; + + if (nxt_slow_path(size > NJS_ARRAY_MAX_LENGTH)) { + goto memory_error; + } + array = nxt_mp_alloc(vm->mem_pool, sizeof(njs_array_t)); if (nxt_slow_path(array == NULL)) { goto memory_error; } - size = (uint64_t) length + spare; - - if (nxt_slow_path((size * sizeof(njs_value_t)) >= UINT32_MAX)) { - goto memory_error; - } - array->data = nxt_mp_align(vm->mem_pool, sizeof(njs_value_t), size * sizeof(njs_value_t)); if (nxt_slow_path(array->data == NULL)) { @@ -164,6 +168,12 @@ memory_error: njs_memory_error(vm); return NULL; + +overflow: + + njs_range_error(vm, "Invalid array length"); + + return NULL; } diff -r a6c82ddff460 -r 434c654ef638 njs/njs_array.h --- a/njs/njs_array.h Fri Apr 19 20:03:49 2019 +0800 +++ b/njs/njs_array.h Fri Apr 19 17:48:39 2019 +0300 @@ -8,14 +8,14 @@ #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_MAX_INDEX 0xffffffff +#define NJS_ARRAY_INVALID_INDEX NJS_ARRAY_MAX_INDEX -#define NJS_ARRAY_SPARE 8 +#define NJS_ARRAY_SPARE 8 +#define NJS_ARRAY_MAX_LENGTH (UINT32_MAX/ sizeof(njs_value_t)) -njs_array_t *njs_array_alloc(njs_vm_t *vm, uint32_t length, uint32_t spare); +njs_array_t *njs_array_alloc(njs_vm_t *vm, uint64_t length, uint32_t spare); njs_ret_t njs_array_add(njs_vm_t *vm, njs_array_t *array, njs_value_t *value); njs_ret_t njs_array_string_add(njs_vm_t *vm, njs_array_t *array, const u_char *start, size_t size, size_t length); diff -r a6c82ddff460 -r 434c654ef638 njs/njs_object.c --- a/njs/njs_object.c Fri Apr 19 20:03:49 2019 +0800 +++ b/njs/njs_object.c Fri Apr 19 17:48:39 2019 +0300 @@ -338,7 +338,7 @@ njs_property_query(njs_vm_t *vm, njs_pro if (nxt_fast_path(!njs_is_null_or_undefined_or_boolean(property))) { index = njs_value_to_index(property); - if (nxt_fast_path(index < NJS_ARRAY_MAX_LENGTH)) { + if (nxt_fast_path(index < NJS_ARRAY_MAX_INDEX)) { return njs_array_property_query(vm, pq, object->data.u.array, index); } @@ -459,7 +459,7 @@ njs_object_property_query(njs_vm_t *vm, switch (proto->type) { case NJS_ARRAY: index = njs_value_to_index(property); - if (nxt_fast_path(index < NJS_ARRAY_MAX_LENGTH)) { + if (nxt_fast_path(index < NJS_ARRAY_MAX_INDEX)) { array = (njs_array_t *) proto; return njs_array_property_query(vm, pq, array, index); } diff -r a6c82ddff460 -r 434c654ef638 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Fri Apr 19 20:03:49 2019 +0800 +++ b/njs/test/njs_unit_test.c Fri Apr 19 17:48:39 2019 +0300 @@ -7950,6 +7950,12 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = Array(1111111111)"), nxt_string("MemoryError") }, + { nxt_string("var x = Array(2**32)"), + nxt_string("RangeError: Invalid array length") }, + + { nxt_string("var x = Array(2**28)"), + nxt_string("MemoryError") }, + { nxt_string("var a = new Array(3); a"), nxt_string(",,") }, _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel