From 32aa8acca143ee3d559965b6383299d469d1fd31 Mon Sep 17 00:00:00 2001 From: Adam Szilagyi Date: Thu, 4 Jun 2020 12:43:38 +0200 Subject: [PATCH] Fix TypedArray initialization with another TypedArray Fixes #3836 JerryScript-DCO-1.0-Signed-off-by: Adam Szilagyi aszilagy@inf.u-szeged.hu --- .../ecma/operations/ecma-arraybuffer-object.c | 1 + .../ecma/operations/ecma-typedarray-object.c | 20 ++++--- .../es2015/regression-test-issue-3836.js | 56 +++++++++++++++++++ 3 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 tests/jerry/es2015/regression-test-issue-3836.js diff --git a/jerry-core/ecma/operations/ecma-arraybuffer-object.c b/jerry-core/ecma/operations/ecma-arraybuffer-object.c index 71a610cc97..7b0e0077ca 100644 --- a/jerry-core/ecma/operations/ecma-arraybuffer-object.c +++ b/jerry-core/ecma/operations/ecma-arraybuffer-object.c @@ -15,6 +15,7 @@ #include "ecma-arraybuffer-object.h" #include "ecma-try-catch-macro.h" +#include "ecma-typedarray-object.h" #include "ecma-objects.h" #include "ecma-builtins.h" #include "ecma-exceptions.h" diff --git a/jerry-core/ecma/operations/ecma-typedarray-object.c b/jerry-core/ecma/operations/ecma-typedarray-object.c index 9127bcbf37..ee9ccd8f8f 100644 --- a/jerry-core/ecma/operations/ecma-typedarray-object.c +++ b/jerry-core/ecma/operations/ecma-typedarray-object.c @@ -534,15 +534,21 @@ ecma_typedarray_create_object_with_length (ecma_length_t array_length, /**< leng ecma_object_t *ctor_proto_p = ecma_get_object_from_value (ctor_proto); - ecma_value_t byte_length_val = ecma_make_uint32_value (byte_length); - ecma_value_t new_arraybuffer = ecma_op_function_construct (ctor_proto_p, - ctor_proto_p, - &byte_length_val, - 1); + ecma_object_t *prototype_p = ecma_op_get_prototype_from_constructor (ctor_proto_p, + ECMA_BUILTIN_ID_ARRAYBUFFER_PROTOTYPE); + ecma_deref_object (ctor_proto_p); - ecma_free_value (byte_length_val); - new_arraybuffer_p = ecma_get_object_from_value (new_arraybuffer); + if (JERRY_UNLIKELY (prototype_p == NULL)) + { + return ECMA_VALUE_ERROR; + } + + new_arraybuffer_p = ecma_arraybuffer_new_object (byte_length); + + ECMA_SET_NON_NULL_POINTER (new_arraybuffer_p->u2.prototype_cp, prototype_p); + + ecma_deref_object (prototype_p); } ecma_object_t *object_p = ecma_create_object (proto_p, diff --git a/tests/jerry/es2015/regression-test-issue-3836.js b/tests/jerry/es2015/regression-test-issue-3836.js new file mode 100644 index 0000000000..c8df8d570a --- /dev/null +++ b/tests/jerry/es2015/regression-test-issue-3836.js @@ -0,0 +1,56 @@ +// 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. + +function validate_typedarray (typedarray, result) { + assert(typedarray.length === result.length); + for (var i = 0; i < typedarray.length; i++) { + assert(typedarray[i] === result[i]); + } +} + +var v1 = new Float64Array(6); +v1.buffer.constructor = Uint8Array; +var v2 = new Float64Array(v1); + +assert(v2.buffer.constructor === Uint8Array); +validate_typedarray(v2, [0, 0, 0, 0, 0, 0]); + +var v3 = new Uint32Array(6); +v3.buffer.constructor = Float64Array; +var v4 = new Uint8Array(v3); + +assert(v4.buffer.constructor === Float64Array); +validate_typedarray(v4, [0, 0, 0, 0, 0, 0]); + +var v5 = new Uint32Array(6); +v5.buffer.constructor = Set; +var v6 = new Uint8Array(v5); + +assert(v6.buffer.constructor === Set); +validate_typedarray(v6, [0, 0, 0, 0, 0, 0]); + +var species_called = false; + +var v7 = new Float64Array(6); +var v8 = v7.buffer; +v8.constructor = { + get [Symbol.species] (){ + species_called = true; + return Uint8Array; + } +} +var v9 = new Float64Array(v7); + +assert(species_called); +assert(Reflect.getPrototypeOf(v9.buffer) === Uint8Array.prototype);