From 337c7cf51627050c0913e878a2ca70c0f56db608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20B=C3=A1tyai?= Date: Fri, 17 Jul 2015 10:44:48 +0200 Subject: [PATCH] Fix leak in Array.prototype.indexOf() when 'fromIndex' can't coerce to primitive value. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit JerryScript-DCO-1.0-Signed-off-by: Dániel Bátyai dbatyai.u-szeged@partner.samsung.com --- .../ecma-builtin-array-prototype.cpp | 31 ++++++++----------- tests/jerry/array-prototype-indexof.js | 17 ++++++++++ 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.cpp b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.cpp index 0a6c5b354b..d320512f2a 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.cpp @@ -1881,12 +1881,11 @@ ecma_builtin_array_prototype_object_index_of (ecma_value_t this_arg, /**< this a /* 3. */ uint32_t len = ecma_number_to_uint32 (len_number); - ecma_number_t *num_p = ecma_alloc_number (); - *num_p = ecma_int32_to_number (-1); - /* 4. */ if (len == 0) { + ecma_number_t *num_p = ecma_alloc_number (); + *num_p = ecma_int32_to_number (-1); ret_value = ecma_make_normal_completion_value (ecma_make_number_value (num_p)); } else @@ -1894,18 +1893,16 @@ ecma_builtin_array_prototype_object_index_of (ecma_value_t this_arg, /**< this a /* 5. */ ECMA_OP_TO_NUMBER_TRY_CATCH (arg_from_idx, arg2, ret_value); + ecma_number_t found_index = ecma_int32_to_number (-1); + uint32_t from_idx = ecma_builtin_helper_array_index_normalize (arg_from_idx, len); /* 6. */ - if (from_idx >= len) - { - ret_value = ecma_make_normal_completion_value (ecma_make_number_value (num_p)); - } - else + if (from_idx < len) { JERRY_ASSERT (from_idx < len); - for (; from_idx < len && *num_p < 0 && ecma_is_completion_value_empty (ret_value); from_idx++) + for (; from_idx < len && found_index < 0 && ecma_is_completion_value_empty (ret_value); from_idx++) { ecma_string_t *idx_str_p = ecma_new_ecma_string_from_uint32 (from_idx); @@ -1918,7 +1915,7 @@ ecma_builtin_array_prototype_object_index_of (ecma_value_t this_arg, /**< this a /* 9.b.ii */ if (ecma_op_strict_equality_compare (arg1, get_value)) { - *num_p = ecma_uint32_to_number (from_idx); + found_index = ecma_uint32_to_number (from_idx); } ECMA_FINALIZE (get_value); @@ -1926,15 +1923,13 @@ ecma_builtin_array_prototype_object_index_of (ecma_value_t this_arg, /**< this a ecma_deref_ecma_string (idx_str_p); } + } - if (ecma_is_completion_value_empty (ret_value)) - { - ret_value = ecma_make_normal_completion_value (ecma_make_number_value (num_p)); - } - else - { - ecma_dealloc_number (num_p); - } + if (ecma_is_completion_value_empty (ret_value)) + { + ecma_number_t *num_p = ecma_alloc_number (); + *num_p = found_index; + ret_value = ecma_make_normal_completion_value (ecma_make_number_value (num_p)); } ECMA_OP_TO_NUMBER_FINALIZE (arg_from_idx); diff --git a/tests/jerry/array-prototype-indexof.js b/tests/jerry/array-prototype-indexof.js index 5972fdd5f5..9577de2665 100644 --- a/tests/jerry/array-prototype-indexof.js +++ b/tests/jerry/array-prototype-indexof.js @@ -45,6 +45,23 @@ assert(obj.indexOf("foo") === -1); var arr = [11, 22, 33, 44]; assert(arr.indexOf(44, 4) === -1); +var fromIndex = { + toString: function () { + return {}; + }, + + valueOf: function () { + return {}; + } +}; + +try { + [0, 1].indexOf(1, fromIndex); + assert(false); +} catch (e) { + assert(e instanceof TypeError); +} + // Checking behavior when unable to get length var obj = { indexOf : Array.prototype.indexOf} Object.defineProperty(obj, 'length', { 'get' : function () { throw new ReferenceError ("foo"); } });