Rework the engine's internal recursion limit (#2969)
This patch unifies the recursion limit checking for RegExp, function call and JSON as well. Until now the limit was only a counter which was increased/decreased at certain points. This counter has been substituted with a numeric limit which allows to restrict the stack usage. This patch fixes #2963 and resolves the closed #2258 issue. Co-authored-by: Gabor Loki loki@inf.u-szeged.hu JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-regexp-object.h"
|
||||
#include "ecma-try-catch-macro.h"
|
||||
#include "jcontext.h"
|
||||
#include "jrt-libc-includes.h"
|
||||
#include "lit-char-helpers.h"
|
||||
#include "re-compiler.h"
|
||||
@@ -63,13 +64,6 @@
|
||||
*/
|
||||
#define RE_IS_CAPTURE_GROUP(x) (((x) < RE_OP_NON_CAPTURE_GROUP_START) ? 1 : 0)
|
||||
|
||||
/*
|
||||
* Check RegExp recursion depth limit
|
||||
*/
|
||||
#if defined (JERRY_REGEXP_RECURSION_LIMIT) && (JERRY_REGEXP_RECURSION_LIMIT != 0)
|
||||
JERRY_STATIC_ASSERT (JERRY_REGEXP_RECURSION_LIMIT > 0, regexp_recursion_limit_must_be_greater_than_zero);
|
||||
#endif /* defined (JERRY_REGEXP_RECURSION_LIMIT) && (JERRY_REGEXP_RECURSION_LIMIT) != 0) */
|
||||
|
||||
/**
|
||||
* Parse RegExp flags (global, ignoreCase, multiline)
|
||||
*
|
||||
@@ -351,7 +345,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
const lit_utf8_byte_t *str_p, /**< input string pointer */
|
||||
const lit_utf8_byte_t **out_str_p) /**< [out] matching substring iterator */
|
||||
{
|
||||
REGEXP_RECURSION_COUNTER_DECREASE_AND_TEST ();
|
||||
ECMA_CHECK_STACK_USAGE ();
|
||||
const lit_utf8_byte_t *str_curr_p = str_p;
|
||||
|
||||
while (true)
|
||||
@@ -364,14 +358,12 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
{
|
||||
JERRY_TRACE_MSG ("Execute RE_OP_MATCH: match\n");
|
||||
*out_str_p = str_curr_p;
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return ECMA_VALUE_TRUE; /* match */
|
||||
}
|
||||
case RE_OP_CHAR:
|
||||
{
|
||||
if (str_curr_p >= re_ctx_p->input_end_p)
|
||||
{
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return ECMA_VALUE_FALSE; /* fail */
|
||||
}
|
||||
|
||||
@@ -383,7 +375,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
if (ch1 != ch2)
|
||||
{
|
||||
JERRY_TRACE_MSG ("fail\n");
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return ECMA_VALUE_FALSE; /* fail */
|
||||
}
|
||||
|
||||
@@ -395,7 +386,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
{
|
||||
if (str_curr_p >= re_ctx_p->input_end_p)
|
||||
{
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return ECMA_VALUE_FALSE; /* fail */
|
||||
}
|
||||
|
||||
@@ -405,7 +395,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
if (lit_char_is_line_terminator (ch))
|
||||
{
|
||||
JERRY_TRACE_MSG ("fail\n");
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return ECMA_VALUE_FALSE; /* fail */
|
||||
}
|
||||
|
||||
@@ -425,7 +414,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
if (!(re_ctx_p->flags & RE_FLAG_MULTILINE))
|
||||
{
|
||||
JERRY_TRACE_MSG ("fail\n");
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return ECMA_VALUE_FALSE; /* fail */
|
||||
}
|
||||
|
||||
@@ -436,7 +424,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
}
|
||||
|
||||
JERRY_TRACE_MSG ("fail\n");
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return ECMA_VALUE_FALSE; /* fail */
|
||||
}
|
||||
case RE_OP_ASSERT_END:
|
||||
@@ -452,7 +439,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
if (!(re_ctx_p->flags & RE_FLAG_MULTILINE))
|
||||
{
|
||||
JERRY_TRACE_MSG ("fail\n");
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return ECMA_VALUE_FALSE; /* fail */
|
||||
}
|
||||
|
||||
@@ -463,7 +449,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
}
|
||||
|
||||
JERRY_TRACE_MSG ("fail\n");
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return ECMA_VALUE_FALSE; /* fail */
|
||||
}
|
||||
case RE_OP_ASSERT_WORD_BOUNDARY:
|
||||
@@ -495,7 +480,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
if (is_wordchar_left == is_wordchar_right)
|
||||
{
|
||||
JERRY_TRACE_MSG ("fail\n");
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return ECMA_VALUE_FALSE; /* fail */
|
||||
}
|
||||
}
|
||||
@@ -507,7 +491,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
if (is_wordchar_left != is_wordchar_right)
|
||||
{
|
||||
JERRY_TRACE_MSG ("fail\n");
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return ECMA_VALUE_FALSE; /* fail */
|
||||
}
|
||||
}
|
||||
@@ -575,7 +558,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
}
|
||||
|
||||
JMEM_FINALIZE_LOCAL_ARRAY (saved_bck_p);
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return match_value;
|
||||
}
|
||||
case RE_OP_CHAR_CLASS:
|
||||
@@ -588,7 +570,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
if (str_curr_p >= re_ctx_p->input_end_p)
|
||||
{
|
||||
JERRY_TRACE_MSG ("fail\n");
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return ECMA_VALUE_FALSE; /* fail */
|
||||
}
|
||||
|
||||
@@ -619,7 +600,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
if (!is_match)
|
||||
{
|
||||
JERRY_TRACE_MSG ("fail\n");
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return ECMA_VALUE_FALSE; /* fail */
|
||||
}
|
||||
}
|
||||
@@ -629,7 +609,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
if (is_match)
|
||||
{
|
||||
JERRY_TRACE_MSG ("fail\n");
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return ECMA_VALUE_FALSE; /* fail */
|
||||
}
|
||||
}
|
||||
@@ -660,7 +639,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
if (str_curr_p >= re_ctx_p->input_end_p)
|
||||
{
|
||||
JERRY_TRACE_MSG ("fail\n");
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return ECMA_VALUE_FALSE; /* fail */
|
||||
}
|
||||
|
||||
@@ -670,7 +648,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
if (ch1 != ch2)
|
||||
{
|
||||
JERRY_TRACE_MSG ("fail\n");
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return ECMA_VALUE_FALSE; /* fail */
|
||||
}
|
||||
}
|
||||
@@ -694,7 +671,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
if (ecma_is_value_true (match_value))
|
||||
{
|
||||
*out_str_p = sub_str_p;
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return match_value; /* match */
|
||||
}
|
||||
else if (ECMA_IS_VALUE_ERROR (match_value))
|
||||
@@ -709,7 +685,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
bc_p = old_bc_p;
|
||||
|
||||
re_ctx_p->saved_p[RE_GLOBAL_START_IDX] = old_start_p;
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return ECMA_VALUE_FALSE; /* fail */
|
||||
}
|
||||
case RE_OP_SAVE_AND_MATCH:
|
||||
@@ -717,7 +692,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
JERRY_TRACE_MSG ("End of pattern is reached: match\n");
|
||||
re_ctx_p->saved_p[RE_GLOBAL_END_IDX] = str_curr_p;
|
||||
*out_str_p = str_curr_p;
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return ECMA_VALUE_TRUE; /* match */
|
||||
}
|
||||
case RE_OP_ALTERNATIVE:
|
||||
@@ -782,7 +756,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
if (ecma_is_value_true (match_value))
|
||||
{
|
||||
*out_str_p = sub_str_p;
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return match_value; /* match */
|
||||
}
|
||||
else if (ECMA_IS_VALUE_ERROR (match_value))
|
||||
@@ -841,7 +814,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
if (ecma_is_value_true (match_value))
|
||||
{
|
||||
*out_str_p = sub_str_p;
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return match_value; /* match */
|
||||
}
|
||||
else if (ECMA_IS_VALUE_ERROR (match_value))
|
||||
@@ -866,7 +838,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
if (ecma_is_value_true (match_value))
|
||||
{
|
||||
*out_str_p = sub_str_p;
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return match_value; /* match */
|
||||
}
|
||||
else if (ECMA_IS_VALUE_ERROR (match_value))
|
||||
@@ -876,7 +847,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
}
|
||||
|
||||
re_ctx_p->saved_p[start_idx] = old_start_p;
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return ECMA_VALUE_FALSE; /* fail */
|
||||
}
|
||||
case RE_OP_CAPTURE_NON_GREEDY_GROUP_END:
|
||||
@@ -922,7 +892,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
if (ecma_is_value_true (match_value))
|
||||
{
|
||||
*out_str_p = sub_str_p;
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return match_value; /* match */
|
||||
}
|
||||
else if (ECMA_IS_VALUE_ERROR (match_value))
|
||||
@@ -971,7 +940,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
if (re_ctx_p->num_of_iterations_p[iter_idx] >= min
|
||||
&& str_curr_p== re_ctx_p->saved_p[start_idx])
|
||||
{
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return ECMA_VALUE_FALSE; /* fail */
|
||||
}
|
||||
|
||||
@@ -993,7 +961,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
if (ecma_is_value_true (match_value))
|
||||
{
|
||||
*out_str_p = sub_str_p;
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return match_value; /* match */
|
||||
}
|
||||
else if (ECMA_IS_VALUE_ERROR (match_value))
|
||||
@@ -1018,7 +985,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
if (ecma_is_value_true (match_value))
|
||||
{
|
||||
*out_str_p = sub_str_p;
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return match_value; /* match */
|
||||
}
|
||||
else if (ECMA_IS_VALUE_ERROR (match_value))
|
||||
@@ -1040,7 +1006,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
if (ecma_is_value_true (match_value))
|
||||
{
|
||||
*out_str_p = sub_str_p;
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return match_value; /* match */
|
||||
}
|
||||
else if (ECMA_IS_VALUE_ERROR (match_value))
|
||||
@@ -1052,7 +1017,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
/* restore if fails */
|
||||
re_ctx_p->saved_p[end_idx] = old_end_p;
|
||||
re_ctx_p->num_of_iterations_p[iter_idx]--;
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return ECMA_VALUE_FALSE; /* fail */
|
||||
}
|
||||
case RE_OP_NON_GREEDY_ITERATOR:
|
||||
@@ -1077,7 +1041,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
if (ecma_is_value_true (match_value))
|
||||
{
|
||||
*out_str_p = sub_str_p;
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return match_value; /* match */
|
||||
}
|
||||
else if (ECMA_IS_VALUE_ERROR (match_value))
|
||||
@@ -1101,7 +1064,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
str_curr_p = sub_str_p;
|
||||
num_of_iter++;
|
||||
}
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return ECMA_VALUE_FALSE; /* fail */
|
||||
}
|
||||
default:
|
||||
@@ -1145,7 +1107,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
if (ecma_is_value_true (match_value))
|
||||
{
|
||||
*out_str_p = sub_str_p;
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return match_value; /* match */
|
||||
}
|
||||
else if (ECMA_IS_VALUE_ERROR (match_value))
|
||||
@@ -1161,7 +1122,6 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
lit_utf8_read_prev (&str_curr_p);
|
||||
num_of_iter--;
|
||||
}
|
||||
REGEXP_RECURSION_COUNTER_INCREASE ();
|
||||
return ECMA_VALUE_FALSE; /* fail */
|
||||
}
|
||||
}
|
||||
@@ -1250,7 +1210,6 @@ ecma_regexp_exec_helper (ecma_value_t regexp_value, /**< RegExp object */
|
||||
re_ctx.input_start_p = input_curr_p;
|
||||
const lit_utf8_byte_t *input_end_p = re_ctx.input_start_p + input_buffer_size;
|
||||
re_ctx.input_end_p = input_end_p;
|
||||
REGEXP_RECURSION_COUNTER_INIT ();
|
||||
|
||||
/* 1. Read bytecode header and init regexp matcher context. */
|
||||
re_ctx.flags = bc_p->header.status_flags;
|
||||
|
||||
Reference in New Issue
Block a user