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;
}
njs_memory_error(vm);
+ return NULL;
+
+overflow:
+
+ njs_range_error(vm, "Invalid array length");
+
return NULL;
}
#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);
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);
}
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);
}
{ 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(",,") },