From e673ae41a998d1391bd562edb2ed6d49db7cc716 Mon Sep 17 00:00:00 2001 From: Dmitry Volyntsev Date: Mon, 21 Feb 2022 16:52:47 +0000 Subject: [PATCH] Fixed Array.prototype.concat() when "this" is a slow array. Previously, when the current appended element is fast array the "this" array was expected to always be a fast array also. This may not be the case when the previous appended element was not fast thus converting the "this" array to a slow form. Previous fix introduced in 2c1382bab643 (0.7.2) was not complete, the correct fix is to never assume "this" is fast, whereas njs_array_add() may only be called with fast arrays. This closes #471 issue in Github. --- src/njs_array.c | 9 ++++++--- src/test/njs_unit_test.c | 5 +++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/njs_array.c b/src/njs_array.c index 7e81d6c6..81a7c155 100644 --- a/src/njs_array.c +++ b/src/njs_array.c @@ -364,6 +364,8 @@ njs_array_expand(njs_vm_t *vm, njs_array_t *array, uint32_t prepend, uint64_t size; njs_value_t *start, *old; + njs_assert(array->object.fast_array); + free_before = array->start - array->data; free_after = array->size - array->length - free_before; @@ -1754,9 +1756,10 @@ njs_array_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_set_invalid(&retval); } - ret = njs_array_add(vm, array, &retval); - if (njs_slow_path(ret != NJS_OK)) { - return NJS_ERROR; + ret = njs_value_property_i64_set(vm, &this, length, + &retval); + if (njs_slow_path(ret == NJS_ERROR)) { + return ret; } } diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index 89bc1615..dc18a13b 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -4253,6 +4253,11 @@ static njs_unit_test_t njs_test[] = "njs.dump([a[0], a[33],a.length])"), njs_str("[1,1,65]") }, + { njs_str("var a = [1]; a[1111111] = 2;" + "var a2 = [3].concat(a, [4]);" + "njs.dump(a2)"), + njs_str("[3,1,<1111110 empty items>,2,4]") }, + { njs_str("var re = /abc/; re[Symbol.isConcatSpreadable] = true;" "re[0] = 1, re[1] = 2, re[2] = 3, re.length = 3;" "[].concat(re)"), -- 2.47.3