From fe6c7b9b61afd8d5507cf18a8f8bff9eef0a886d Mon Sep 17 00:00:00 2001 From: Robert Fancsik Date: Fri, 17 Nov 2017 21:37:20 +0100 Subject: [PATCH] Fixed TypedArray error handling This patch fixes #2106. The problem was that the function always tried to transform the array-like object to TypedArray object even if there was an error during TypedArray creation. JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu --- .../ecma/operations/ecma-typedarray-object.c | 114 +++++++++--------- .../jerry/fail/regression-test-issue-2106.js | 15 +++ 2 files changed, 73 insertions(+), 56 deletions(-) create mode 100644 tests/jerry/fail/regression-test-issue-2106.js diff --git a/jerry-core/ecma/operations/ecma-typedarray-object.c b/jerry-core/ecma/operations/ecma-typedarray-object.c index ae4011dd0..3862099d8 100644 --- a/jerry-core/ecma/operations/ecma-typedarray-object.c +++ b/jerry-core/ecma/operations/ecma-typedarray-object.c @@ -417,65 +417,67 @@ ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like obje if (ECMA_IS_VALUE_ERROR (new_typedarray)) { - ret_value = ecma_copy_value (new_typedarray); - } - - ecma_object_t *new_typedarray_p = ecma_get_object_from_value (new_typedarray); - - /* 17 */ - ecma_value_t current_index; - - for (uint32_t index = 0; index < len && ecma_is_value_empty (ret_value); index++) - { - /* 17.a */ - ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (index); - - /* 17.b */ - ECMA_TRY_CATCH (current_value, ecma_op_object_find (arraylike_object_p, index_str_p), ret_value); - - if (ecma_is_value_found (current_value)) - { - if (func_object_p != NULL) - { - /* 17.d 17.f */ - current_index = ecma_make_uint32_value (index); - ecma_value_t call_args[] = { current_value, current_index}; - - ECMA_TRY_CATCH (mapped_value, ecma_op_function_call (func_object_p, this_val, call_args, 2), ret_value); - - bool set_status = ecma_op_typedarray_set_index_prop (new_typedarray_p, index, mapped_value); - - if (!set_status) - { - ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument type."));; - } - - ECMA_FINALIZE (mapped_value); - } - else - { - /* 17.e 17.f */ - bool set_status = ecma_op_typedarray_set_index_prop (new_typedarray_p, index, current_value); - - if (!set_status) - { - ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument type."));; - } - } - } - - ECMA_FINALIZE (current_value); - - ecma_deref_ecma_string (index_str_p); - } - - if (ecma_is_value_empty (ret_value)) - { - ret_value = ecma_make_object_value (new_typedarray_p); + ret_value = new_typedarray; } else { - ecma_deref_object (new_typedarray_p); + ecma_object_t *new_typedarray_p = ecma_get_object_from_value (new_typedarray); + + /* 17 */ + ecma_value_t current_index; + + for (uint32_t index = 0; index < len && ecma_is_value_empty (ret_value); index++) + { + /* 17.a */ + ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (index); + + /* 17.b */ + ECMA_TRY_CATCH (current_value, ecma_op_object_find (arraylike_object_p, index_str_p), ret_value); + + if (ecma_is_value_found (current_value)) + { + if (func_object_p != NULL) + { + /* 17.d 17.f */ + current_index = ecma_make_uint32_value (index); + ecma_value_t call_args[] = { current_value, current_index}; + + ECMA_TRY_CATCH (mapped_value, ecma_op_function_call (func_object_p, this_val, call_args, 2), ret_value); + + bool set_status = ecma_op_typedarray_set_index_prop (new_typedarray_p, index, mapped_value); + + if (!set_status) + { + ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument type."));; + } + + ECMA_FINALIZE (mapped_value); + } + else + { + /* 17.e 17.f */ + bool set_status = ecma_op_typedarray_set_index_prop (new_typedarray_p, index, current_value); + + if (!set_status) + { + ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument type."));; + } + } + } + + ECMA_FINALIZE (current_value); + + ecma_deref_ecma_string (index_str_p); + } + + if (ecma_is_value_empty (ret_value)) + { + ret_value = ecma_make_object_value (new_typedarray_p); + } + else + { + ecma_deref_object (new_typedarray_p); + } } ECMA_OP_TO_NUMBER_FINALIZE (len_number); diff --git a/tests/jerry/fail/regression-test-issue-2106.js b/tests/jerry/fail/regression-test-issue-2106.js new file mode 100644 index 000000000..10b7661f6 --- /dev/null +++ b/tests/jerry/fail/regression-test-issue-2106.js @@ -0,0 +1,15 @@ +// 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. + +new Float32Array({ length: 0x40000001 });