From 1774cca47c587e070b2cbdad951d9590777a4e99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20G=C3=A1l?= Date: Mon, 25 May 2020 16:36:54 +0200 Subject: [PATCH] Fix array length check in lastIndexOf (#3789) When lastIndexOf is executed the array length can change and in case of fast arrays the length should be re-checked. JerryScript-DCO-1.0-Signed-off-by: Peter Gal pgal.usz@partner.samsung.com --- .../ecma-builtin-array-prototype.c | 4 ++- tests/jerry/regression-test-issue-3779.js | 32 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 tests/jerry/regression-test-issue-3779.js diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c index 7dbbdeef8..383aeb74a 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c @@ -1775,9 +1775,11 @@ ecma_builtin_array_prototype_object_last_index_of (const ecma_value_t args[], /* if (ecma_op_object_is_fast_array (obj_p)) { ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p; + // It is possible that the length changed due to the callback performed above. + uint32_t array_length = ext_obj_p->u.array.length; if (ext_obj_p->u.array.u.hole_count < ECMA_FAST_ARRAY_HOLE_ONE - && len != 0) + && array_length > 0) { ecma_value_t *buffer_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, obj_p->u1.property_list_cp); diff --git a/tests/jerry/regression-test-issue-3779.js b/tests/jerry/regression-test-issue-3779.js new file mode 100644 index 000000000..c97db4b33 --- /dev/null +++ b/tests/jerry/regression-test-issue-3779.js @@ -0,0 +1,32 @@ +// Copyright JS Foundation and other contributors, http://js.foundation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +var array = [1, 2, 3]; +var idx_50 = array.lastIndexOf(50, { + valueOf: function() { + // Trigger removing elements from fast array. + array.length = 0; + } +}) + +assert (idx_50 === -1); + +var idx_51 = array.lastIndexOf(51, { + valueOf: function() { + array.push(51) + return 10; + } +}) + +assert (idx_51 === -1);