Skip to content

Commit cc32d50

Browse files
committed
Fix leak in Array.prototype.indexOf() when 'fromIndex' can't coerce to primitive value.
JerryScript-DCO-1.0-Signed-off-by: Dániel Bátyai dbatyai.u-szeged@partner.samsung.com
1 parent c8a16f2 commit cc32d50

File tree

2 files changed

+30
-18
lines changed

2 files changed

+30
-18
lines changed

jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.cpp

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -938,31 +938,28 @@ ecma_builtin_array_prototype_object_index_of (ecma_value_t this_arg, /**< this a
938938
/* 3. */
939939
uint32_t len = ecma_number_to_uint32 (len_number);
940940

941-
ecma_number_t* num_p = ecma_alloc_number ();
942-
*num_p = ecma_int32_to_number (-1);
943-
944941
/* 4. */
945942
if (len == 0)
946943
{
944+
ecma_number_t *num_p = ecma_alloc_number ();
945+
*num_p = ecma_int32_to_number (-1);
947946
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (num_p));
948947
}
949948
else
950949
{
951950
/* 5. */
952951
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_from_idx, arg2, ret_value);
953952

953+
ecma_number_t found_index = ecma_int32_to_number (-1);
954+
954955
uint32_t from_idx = ecma_builtin_helper_array_index_normalize (arg_from_idx, len);
955956

956957
/* 6. */
957-
if (from_idx >= len)
958-
{
959-
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (num_p));
960-
}
961-
else
958+
if (from_idx < len)
962959
{
963960
JERRY_ASSERT (from_idx < len);
964961

965-
for (; from_idx < len && *num_p < 0 && ecma_is_completion_value_empty (ret_value); from_idx++)
962+
for (; from_idx < len && found_index < 0 && ecma_is_completion_value_empty (ret_value); from_idx++)
966963
{
967964
ecma_string_t *idx_str_p = ecma_new_ecma_string_from_uint32 (from_idx);
968965

@@ -975,23 +972,21 @@ ecma_builtin_array_prototype_object_index_of (ecma_value_t this_arg, /**< this a
975972
/* 9.b.ii */
976973
if (ecma_op_strict_equality_compare (arg1, get_value))
977974
{
978-
*num_p = ecma_uint32_to_number (from_idx);
975+
found_index = ecma_uint32_to_number (from_idx);
979976
}
980977

981978
ECMA_FINALIZE (get_value);
982979
}
983980

984981
ecma_deref_ecma_string (idx_str_p);
985982
}
983+
}
986984

987-
if (ecma_is_completion_value_empty (ret_value))
988-
{
989-
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (num_p));
990-
}
991-
else
992-
{
993-
ecma_dealloc_number (num_p);
994-
}
985+
if (ecma_is_completion_value_empty (ret_value))
986+
{
987+
ecma_number_t *num_p = ecma_alloc_number ();
988+
*num_p = found_index;
989+
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (num_p));
995990
}
996991

997992
ECMA_OP_TO_NUMBER_FINALIZE (arg_from_idx);

tests/jerry/array-prototype-indexof.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,23 @@ assert(obj.indexOf("foo") === -1);
4545
var arr = [11, 22, 33, 44];
4646
assert(arr.indexOf(44, 4) === -1);
4747

48+
var fromIndex = {
49+
toString: function () {
50+
return {};
51+
},
52+
53+
valueOf: function () {
54+
return {};
55+
}
56+
};
57+
58+
try {
59+
[0, 1].indexOf(1, fromIndex);
60+
assert(false);
61+
} catch (e) {
62+
assert(e instanceof TypeError);
63+
}
64+
4865
// Checking behavior when unable to get length
4966
var obj = { indexOf : Array.prototype.indexOf}
5067
Object.defineProperty(obj, 'length', { 'get' : function () { throw new ReferenceError ("foo"); } });

0 commit comments

Comments
 (0)