From: Alexander Borisov Date: Fri, 19 Apr 2019 14:48:39 +0000 (+0300) Subject: Added uint32_t overflow check for njs_array_alloc() function. X-Git-Tag: 0.3.2~61 X-Git-Url: http://git.kaiwu.me/postgresql/log/contrib/postgres_fdw/static/gitweb.js?a=commitdiff_plain;h=cf289e01baabedbf168f128279ba4693d82b874e;p=njs.git Added uint32_t overflow check for njs_array_alloc() function. --- diff --git a/njs/njs_array.c b/njs/njs_array.c index 8ef2114b..75b2edb3 100644 --- a/njs/njs_array.c +++ b/njs/njs_array.c @@ -125,19 +125,23 @@ static njs_ret_t njs_array_prototype_sort_continuation(njs_vm_t *vm, 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; - array = nxt_mp_alloc(vm->mem_pool, sizeof(njs_array_t)); - if (nxt_slow_path(array == NULL)) { - goto memory_error; + if (nxt_slow_path(length > UINT32_MAX)) { + goto overflow; } - size = (uint64_t) length + spare; + size = length + spare; + + if (nxt_slow_path(size > NJS_ARRAY_MAX_LENGTH)) { + goto memory_error; + } - if (nxt_slow_path((size * sizeof(njs_value_t)) >= UINT32_MAX)) { + array = nxt_mp_alloc(vm->mem_pool, sizeof(njs_array_t)); + if (nxt_slow_path(array == NULL)) { goto memory_error; } @@ -163,6 +167,12 @@ memory_error: njs_memory_error(vm); + return NULL; + +overflow: + + njs_range_error(vm, "Invalid array length"); + return NULL; } diff --git a/njs/njs_array.h b/njs/njs_array.h index 5d13a8b3..6c7bbb05 100644 --- a/njs/njs_array.h +++ b/njs/njs_array.h @@ -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 --git a/njs/njs_object.c b/njs/njs_object.c index 3f3ccc8a..8e47f795 100644 --- a/njs/njs_object.c +++ b/njs/njs_object.c @@ -338,7 +338,7 @@ njs_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_value_t *object, 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, njs_property_query_t *pq, 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 --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index 5095daa4..7f578507 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -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(",,") },