Fix leaking lastIndex values in RegExp built-ins (#4166)
JerryScript-DCO-1.0-Signed-off-by: Dániel Bátyai daniel.batyai@h-lab.eu
This commit is contained in:
@@ -567,7 +567,6 @@ ecma_make_length_value (ecma_length_t number) /**< number to be encoded */
|
|||||||
return ecma_make_integer_value ((ecma_integer_value_t) number);
|
return ecma_make_integer_value ((ecma_integer_value_t) number);
|
||||||
}
|
}
|
||||||
|
|
||||||
JERRY_ASSERT (number <= ECMA_NUMBER_MAX_SAFE_INTEGER);
|
|
||||||
return ecma_create_float_number ((ecma_number_t) number);
|
return ecma_create_float_number ((ecma_number_t) number);
|
||||||
} /* ecma_make_length_value */
|
} /* ecma_make_length_value */
|
||||||
|
|
||||||
|
|||||||
@@ -2263,11 +2263,14 @@ ecma_regexp_split_helper (ecma_value_t this_arg, /**< this value */
|
|||||||
while (current_index < string_length)
|
while (current_index < string_length)
|
||||||
{
|
{
|
||||||
/* 24.a-b. */
|
/* 24.a-b. */
|
||||||
|
ecma_value_t index_value = ecma_make_length_value (current_index);
|
||||||
result = ecma_op_object_put (splitter_obj_p,
|
result = ecma_op_object_put (splitter_obj_p,
|
||||||
lastindex_str_p,
|
lastindex_str_p,
|
||||||
ecma_make_length_value (current_index),
|
index_value,
|
||||||
true);
|
true);
|
||||||
|
|
||||||
|
ecma_free_value (index_value);
|
||||||
|
|
||||||
if (ECMA_IS_VALUE_ERROR (result))
|
if (ECMA_IS_VALUE_ERROR (result))
|
||||||
{
|
{
|
||||||
goto cleanup_array;
|
goto cleanup_array;
|
||||||
@@ -2771,11 +2774,14 @@ ecma_regexp_replace_helper_fast (ecma_replace_context_t *ctx_p, /**<replace cont
|
|||||||
#if ENABLED (JERRY_ESNEXT)
|
#if ENABLED (JERRY_ESNEXT)
|
||||||
if (JERRY_UNLIKELY ((re_ctx.flags & RE_FLAG_STICKY) != 0))
|
if (JERRY_UNLIKELY ((re_ctx.flags & RE_FLAG_STICKY) != 0))
|
||||||
{
|
{
|
||||||
|
ecma_value_t index_value = ecma_make_length_value (index);
|
||||||
result = ecma_op_object_put ((ecma_object_t *) re_obj_p,
|
result = ecma_op_object_put ((ecma_object_t *) re_obj_p,
|
||||||
ecma_get_magic_string (LIT_MAGIC_STRING_LASTINDEX_UL),
|
ecma_get_magic_string (LIT_MAGIC_STRING_LASTINDEX_UL),
|
||||||
ecma_make_length_value (index),
|
index_value,
|
||||||
true);
|
true);
|
||||||
|
|
||||||
|
ecma_free_value (index_value);
|
||||||
|
|
||||||
if (ECMA_IS_VALUE_ERROR (result))
|
if (ECMA_IS_VALUE_ERROR (result))
|
||||||
{
|
{
|
||||||
goto cleanup_builder;
|
goto cleanup_builder;
|
||||||
@@ -3063,24 +3069,28 @@ ecma_regexp_replace_helper (ecma_value_t this_arg, /**< this argument */
|
|||||||
goto cleanup_results;
|
goto cleanup_results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ecma_value_t last_index = result;
|
||||||
|
|
||||||
ecma_length_t index;
|
ecma_length_t index;
|
||||||
if (ECMA_IS_VALUE_ERROR (ecma_op_to_length (result, &index)))
|
result = ecma_op_to_length (last_index, &index);
|
||||||
|
ecma_free_value (last_index);
|
||||||
|
|
||||||
|
if (ECMA_IS_VALUE_ERROR (result))
|
||||||
{
|
{
|
||||||
ecma_free_value (result);
|
|
||||||
result = ECMA_VALUE_ERROR;
|
|
||||||
goto cleanup_results;
|
goto cleanup_results;
|
||||||
}
|
}
|
||||||
|
|
||||||
ecma_free_value (result);
|
|
||||||
|
|
||||||
index = ecma_op_advance_string_index (string_p, index, (replace_ctx.flags & RE_FLAG_UNICODE) != 0);
|
index = ecma_op_advance_string_index (string_p, index, (replace_ctx.flags & RE_FLAG_UNICODE) != 0);
|
||||||
|
last_index = ecma_make_length_value (index);
|
||||||
|
|
||||||
/* 10.d.iii.3.c */
|
/* 10.d.iii.3.c */
|
||||||
result = ecma_op_object_put (this_obj_p,
|
result = ecma_op_object_put (this_obj_p,
|
||||||
ecma_get_magic_string (LIT_MAGIC_STRING_LASTINDEX_UL),
|
ecma_get_magic_string (LIT_MAGIC_STRING_LASTINDEX_UL),
|
||||||
ecma_make_length_value (index),
|
last_index,
|
||||||
true);
|
true);
|
||||||
|
|
||||||
|
ecma_free_value (last_index);
|
||||||
|
|
||||||
if (ECMA_IS_VALUE_ERROR (result))
|
if (ECMA_IS_VALUE_ERROR (result))
|
||||||
{
|
{
|
||||||
goto cleanup_results;
|
goto cleanup_results;
|
||||||
@@ -3469,18 +3479,18 @@ ecma_regexp_match_helper (ecma_value_t this_arg, /**< this argument */
|
|||||||
|
|
||||||
if (is_match_empty)
|
if (is_match_empty)
|
||||||
{
|
{
|
||||||
ecma_value_t this_index = ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_LASTINDEX_UL);
|
ecma_value_t last_index = ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_LASTINDEX_UL);
|
||||||
|
|
||||||
if (ECMA_IS_VALUE_ERROR (this_index))
|
if (ECMA_IS_VALUE_ERROR (last_index))
|
||||||
{
|
{
|
||||||
goto result_cleanup;
|
goto result_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLED (JERRY_ESNEXT)
|
#if ENABLED (JERRY_ESNEXT)
|
||||||
ecma_length_t index;
|
ecma_length_t index;
|
||||||
ecma_value_t length_value = ecma_op_to_length (this_index, &index);
|
ecma_value_t length_value = ecma_op_to_length (last_index, &index);
|
||||||
|
|
||||||
ecma_free_value (this_index);
|
ecma_free_value (last_index);
|
||||||
|
|
||||||
if (ECMA_IS_VALUE_ERROR (length_value))
|
if (ECMA_IS_VALUE_ERROR (length_value))
|
||||||
{
|
{
|
||||||
@@ -3489,20 +3499,23 @@ ecma_regexp_match_helper (ecma_value_t this_arg, /**< this argument */
|
|||||||
|
|
||||||
index = ecma_op_advance_string_index (str_p, index, full_unicode);
|
index = ecma_op_advance_string_index (str_p, index, full_unicode);
|
||||||
|
|
||||||
|
last_index = ecma_make_length_value (index);
|
||||||
ecma_value_t next_set_status = ecma_op_object_put (obj_p,
|
ecma_value_t next_set_status = ecma_op_object_put (obj_p,
|
||||||
ecma_get_magic_string (LIT_MAGIC_STRING_LASTINDEX_UL),
|
ecma_get_magic_string (LIT_MAGIC_STRING_LASTINDEX_UL),
|
||||||
ecma_make_length_value (index),
|
ecma_make_length_value (index),
|
||||||
true);
|
true);
|
||||||
#else /* !ENABLED (JERRY_ESNEXT) */
|
#else /* !ENABLED (JERRY_ESNEXT) */
|
||||||
ecma_number_t next_index = ecma_get_number_from_value (this_index);
|
ecma_number_t index = ecma_get_number_from_value (last_index);
|
||||||
|
ecma_free_value (last_index);
|
||||||
|
|
||||||
|
last_index = ecma_make_number_value (index + 1);
|
||||||
ecma_value_t next_set_status = ecma_op_object_put (obj_p,
|
ecma_value_t next_set_status = ecma_op_object_put (obj_p,
|
||||||
ecma_get_magic_string (LIT_MAGIC_STRING_LASTINDEX_UL),
|
ecma_get_magic_string (LIT_MAGIC_STRING_LASTINDEX_UL),
|
||||||
ecma_make_number_value (next_index + 1),
|
last_index,
|
||||||
true);
|
true);
|
||||||
|
|
||||||
ecma_free_value (this_index);
|
|
||||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||||
|
ecma_free_value (last_index);
|
||||||
|
|
||||||
if (ECMA_IS_VALUE_ERROR (next_set_status))
|
if (ECMA_IS_VALUE_ERROR (next_set_status))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -721,4 +721,33 @@ assert(r[Symbol.replace]("aaaa", function(match, index) {
|
|||||||
}) === "baaa");
|
}) === "baaa");
|
||||||
|
|
||||||
assert (replaceCalled);
|
assert (replaceCalled);
|
||||||
assert (r.lastIndex === 2)
|
assert (r.lastIndex === 2);
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
var r = /./g;
|
||||||
|
var execWasCalled = false;
|
||||||
|
var coercibleIndex = {
|
||||||
|
valueOf: function() {
|
||||||
|
return Math.pow(2, 54);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
var result = {
|
||||||
|
length: 1,
|
||||||
|
0: '',
|
||||||
|
index: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
r.exec = function() {
|
||||||
|
if (execWasCalled) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
r.lastIndex = coercibleIndex;
|
||||||
|
execWasCalled = true;
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
assert(r[Symbol.replace]('', '') === '');
|
||||||
|
assert(r.lastIndex === Math.pow(2, 53));
|
||||||
|
})();
|
||||||
|
|||||||
Reference in New Issue
Block a user