From 0b4030fdd9a320ce3f0190be4cd5b216dd89a9a8 Mon Sep 17 00:00:00 2001 From: "Artem S. Povalyukhin" Date: Fri, 26 Jul 2019 07:24:36 +0300 Subject: [PATCH] Fixed Array.length setter. This closes #26 and closes #27 issues on Github. --- njs/njs_array.c | 21 ++++++++++++++------- njs/test/njs_unit_test.c | 20 ++++++++++++++++++++ 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/njs/njs_array.c b/njs/njs_array.c index 7b43153f..dbeb0014 100644 --- a/njs/njs_array.c +++ b/njs/njs_array.c @@ -318,10 +318,11 @@ njs_array_length(njs_vm_t *vm, njs_value_t *value, njs_value_t *setval, njs_value_t *val; njs_array_t *array; njs_object_t *proto; + njs_value_t val_length; proto = njs_object(value); - if (setval == NULL) { + if (nxt_fast_path(setval == NULL)) { do { if (nxt_fast_path(proto->type == NJS_ARRAY)) { break; @@ -345,13 +346,19 @@ njs_array_length(njs_vm_t *vm, njs_value_t *value, njs_value_t *setval, return NJS_DECLINED; } - if (!njs_is_number(setval)) { - njs_range_error(vm, "Invalid array length"); - return NJS_ERROR; + if (nxt_slow_path(!njs_is_number(setval))) { + ret = njs_value_to_numeric(vm, &val_length, setval); + if (ret != NXT_OK) { + return ret; + } + + num = njs_number(&val_length); + + } else { + num = njs_number(setval); } - num = njs_number(setval); - length = (uint32_t) num; + length = njs_number_to_uint32(num); if ((double) length != num) { njs_range_error(vm, "Invalid array length"); @@ -379,7 +386,7 @@ njs_array_length(njs_vm_t *vm, njs_value_t *value, njs_value_t *setval, array->length = length; - njs_set_number(retval, length); + *retval = *setval; return NJS_OK; } diff --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index b0d5b669..dcf35a2b 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -3531,6 +3531,26 @@ static njs_unit_test_t njs_test[] = { nxt_string("[].length = -1"), nxt_string("RangeError: Invalid array length") }, + { nxt_string("var a = [1];" + "typeof (a.length = '') == 'string' && a.length == 0"), + nxt_string("true") }, + + { nxt_string("var a = [1]; " + "typeof (a.length = Object(2)) == 'object' && a.length == 2"), + nxt_string("true") }, + + { nxt_string("var a = [1]; " + "typeof (a.length = Object('2')) == 'object'"), + nxt_string("true") }, + + { nxt_string("var a = [1]; " + "a.length = { valueOf: () => 2 }; a.length == 2"), + nxt_string("true") }, + + { nxt_string("var a = [1]; " + "a.length = { toString: () => '2' }; a.length == 2"), + nxt_string("true") }, + { nxt_string("var a = []; a.length = 0; JSON.stringify(a)"), nxt_string("[]") }, -- 2.47.3