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:
Robert Fancsik
2019-07-23 15:31:37 +02:00
committed by GitHub
parent f53dba1a3a
commit 4a9e185840
20 changed files with 156 additions and 216 deletions
+3 -1
View File
@@ -73,7 +73,9 @@ matrix:
- name: "ASAN Tests" - name: "ASAN Tests"
env: env:
- OPTS="--quiet --jerry-tests --jerry-test-suite --skip-list=parser-oom.js,parser-oom2.js --buildoptions=--compile-flag=-fsanitize=address,--compile-flag=-m32,--compile-flag=-fno-omit-frame-pointer,--compile-flag=-fno-common,--compile-flag=-O2,--debug,--system-allocator=on,--linker-flag=-fuse-ld=gold" # Skipping maximum stack usage related tests due to 'detect_stack_use_after_return=1' ASAN option.
# For more detailed description: https://github.com/google/sanitizers/wiki/AddressSanitizerUseAfterReturn#compatibility
- OPTS="--quiet --jerry-tests --jerry-test-suite --skip-list=parser-oom.js,parser-oom2.js,stack-limit.js,regression-test-issue-2190.js,regression-test-issue-2258-2963.js,regression-test-issue-2448.js,regression-test-issue-2905.js --buildoptions=--stack-limit=0,--compile-flag=-fsanitize=address,--compile-flag=-m32,--compile-flag=-fno-omit-frame-pointer,--compile-flag=-fno-common,--compile-flag=-O2,--debug,--system-allocator=on,--linker-flag=-fuse-ld=gold"
- ASAN_OPTIONS=detect_stack_use_after_return=1:check_initialization_order=true:strict_init_order=true - ASAN_OPTIONS=detect_stack_use_after_return=1:check_initialization_order=true:strict_init_order=true
- TIMEOUT=600 - TIMEOUT=600
compiler: gcc-5 compiler: gcc-5
+5 -14
View File
@@ -39,8 +39,7 @@ set(JERRY_SYSTEM_ALLOCATOR OFF CACHE BOOL "Enable system allocato
set(JERRY_VALGRIND OFF CACHE BOOL "Enable Valgrind support?") set(JERRY_VALGRIND OFF CACHE BOOL "Enable Valgrind support?")
set(JERRY_VM_EXEC_STOP OFF CACHE BOOL "Enable VM execution stopping?") set(JERRY_VM_EXEC_STOP OFF CACHE BOOL "Enable VM execution stopping?")
set(JERRY_GLOBAL_HEAP_SIZE "(512)" CACHE STRING "Size of memory heap, in kilobytes") set(JERRY_GLOBAL_HEAP_SIZE "(512)" CACHE STRING "Size of memory heap, in kilobytes")
set(JERRY_REGEXP_RECURSION_LIMIT "0" CACHE STRING "Limit of regexp recursion depth") set(JERRY_STACK_LIMIT "(0)" CACHE STRING "Maximum stack usage size, in kilobytes")
set(JERRY_CALL_STACK_LIMIT "0" CACHE STRING "Limit of function call recursion depth")
# Option overrides # Option overrides
if(USING_MSVC) if(USING_MSVC)
@@ -102,8 +101,7 @@ message(STATUS "JERRY_SYSTEM_ALLOCATOR " ${JERRY_SYSTEM_ALLOCATOR})
message(STATUS "JERRY_VALGRIND " ${JERRY_VALGRIND}) message(STATUS "JERRY_VALGRIND " ${JERRY_VALGRIND})
message(STATUS "JERRY_VM_EXEC_STOP " ${JERRY_VM_EXEC_STOP}) message(STATUS "JERRY_VM_EXEC_STOP " ${JERRY_VM_EXEC_STOP})
message(STATUS "JERRY_GLOBAL_HEAP_SIZE " ${JERRY_GLOBAL_HEAP_SIZE}) message(STATUS "JERRY_GLOBAL_HEAP_SIZE " ${JERRY_GLOBAL_HEAP_SIZE})
message(STATUS "JERRY_REGEXP_RECURSION_LIMIT " ${JERRY_REGEXP_RECURSION_LIMIT}) message(STATUS "JERRY_STACK_LIMIT " ${JERRY_STACK_LIMIT})
message(STATUS "JERRY_CALL_STACK_LIMIT " ${JERRY_CALL_STACK_LIMIT})
# Include directories # Include directories
set(INCLUDE_CORE_PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") set(INCLUDE_CORE_PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
@@ -275,16 +273,6 @@ endif()
# RegExp strict mode # RegExp strict mode
jerry_add_define01(JERRY_REGEXP_STRICT_MODE) jerry_add_define01(JERRY_REGEXP_STRICT_MODE)
# RegExp recursion depth limit
if(JERRY_REGEXP_RECURSION_LIMIT)
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_REGEXP_RECURSION_LIMIT=${JERRY_REGEXP_RECURSION_LIMIT})
endif()
# Function call recursion depth limit
if(JERRY_CALL_STACK_LIMIT)
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_CALL_STACK_LIMIT=${JERRY_CALL_STACK_LIMIT})
endif()
# RegExp byte-code dumps # RegExp byte-code dumps
jerry_add_define01(JERRY_REGEXP_DUMP_BYTE_CODE) jerry_add_define01(JERRY_REGEXP_DUMP_BYTE_CODE)
@@ -309,6 +297,9 @@ jerry_add_define01(JERRY_VM_EXEC_STOP)
# Size of heap # Size of heap
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_GLOBAL_HEAP_SIZE=${JERRY_GLOBAL_HEAP_SIZE}) set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_GLOBAL_HEAP_SIZE=${JERRY_GLOBAL_HEAP_SIZE})
# Maximum size of stack memory usage
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_STACK_LIMIT=${JERRY_STACK_LIMIT})
add_library(${JERRY_CORE_NAME} ${SOURCE_CORE_FILES}) add_library(${JERRY_CORE_NAME} ${SOURCE_CORE_FILES})
target_compile_definitions(${JERRY_CORE_NAME} PUBLIC ${DEFINES_JERRY}) target_compile_definitions(${JERRY_CORE_NAME} PUBLIC ${DEFINES_JERRY})
+16 -33
View File
@@ -205,6 +205,19 @@
# define JERRY_GLOBAL_HEAP_SIZE (512) # define JERRY_GLOBAL_HEAP_SIZE (512)
#endif /* !defined (JERRY_GLOBAL_HEAP_SIZE) */ #endif /* !defined (JERRY_GLOBAL_HEAP_SIZE) */
/**
* Maximum stack usage size in kilobytes
*
* Note: This feature cannot be used when 'detect_stack_use_after_return=1' ASAN option is enabled.
* For more detailed description:
* - https://github.com/google/sanitizers/wiki/AddressSanitizerUseAfterReturn#compatibility
*
* Default value: 0, unlimited
*/
#ifndef JERRY_STACK_LIMIT
# define JERRY_STACK_LIMIT (0)
#endif /* !defined (JERRY_STACK_LIMIT) */
/** /**
* Enable/Disable property lookup cache. * Enable/Disable property lookup cache.
* *
@@ -352,22 +365,6 @@
# define JERRY_REGEXP_STRICT_MODE 0 # define JERRY_REGEXP_STRICT_MODE 0
#endif /* !defined (JERRY_REGEXP_STRICT_MODE) */ #endif /* !defined (JERRY_REGEXP_STRICT_MODE) */
/**
* Set the RegExp parser and execution recursion limit.
*
* Allowed values:
* 0: Disable recursion limit check.
* 1 or greater: Set the recursion limit to the given number.
*
* Note:
* A negative value will cause a static assert compiler error.
*
* Default value: 0
*/
#ifndef JERRY_REGEXP_RECURSION_LIMIT
# define JERRY_REGEXP_RECURSION_LIMIT 0
#endif /* !defined (JERRY_REGEXP_RECURSION_LIMIT) */
/** /**
* Enable/Disable the snapshot execution functions. * Enable/Disable the snapshot execution functions.
* *
@@ -435,23 +432,6 @@
# define JERRY_VM_EXEC_STOP 0 # define JERRY_VM_EXEC_STOP 0
#endif /* !defined (JERRY_VM_EXEC_STOP) */ #endif /* !defined (JERRY_VM_EXEC_STOP) */
/**
* Set the function call recursion limit.
*
* Allowed values:
* 0: Disable recursion limit check.
* 1 or greater: Set the recursion limit to the given number.
*
* Note:
* A negative value will cause a static assert compiler error.
*
* Default value: 0
*/
#ifndef JERRY_CALL_STACK_LIMIT
# define JERRY_CALL_STACK_LIMIT 0
#endif /* !defined (JERRY_CALL_STACK_LIMIT) */
/** /**
* Advanced section configurations. * Advanced section configurations.
*/ */
@@ -631,6 +611,9 @@
#if !defined (JERRY_GLOBAL_HEAP_SIZE) || (JERRY_GLOBAL_HEAP_SIZE <= 0) #if !defined (JERRY_GLOBAL_HEAP_SIZE) || (JERRY_GLOBAL_HEAP_SIZE <= 0)
# error "Invalid value for 'JERRY_GLOBAL_HEAP_SIZE' macro." # error "Invalid value for 'JERRY_GLOBAL_HEAP_SIZE' macro."
#endif #endif
#if !defined (JERRY_STACK_LIMIT) || (JERRY_STACK_LIMIT < 0)
# error "Invalid value for 'JERRY_STACK_LIMIT' macro."
#endif
#if !defined (JERRY_LCACHE) \ #if !defined (JERRY_LCACHE) \
|| ((JERRY_LCACHE != 0) && (JERRY_LCACHE != 1)) || ((JERRY_LCACHE != 0) && (JERRY_LCACHE != 1))
# error "Invalid value for 'JERRY_LCACHE' macro." # error "Invalid value for 'JERRY_LCACHE' macro."
+19
View File
@@ -1542,6 +1542,25 @@ typedef struct
*/ */
#define ECMA_SYMBOL_HASH_SHIFT 2 #define ECMA_SYMBOL_HASH_SHIFT 2
#if (JERRY_STACK_LIMIT != 0)
/**
* Check the current stack usage. If the limit is reached a RangeError is raised.
*/
#define ECMA_CHECK_STACK_USAGE() \
do \
{ \
if (ecma_get_current_stack_usage () > CONFIG_MEM_STACK_LIMIT) \
{ \
return ecma_raise_range_error (ECMA_ERR_MSG ("Maximum call stack size exceeded.")); \
} \
} while (0)
#else /* JERRY_STACK_LIMIT == 0) */
/**
* If the stack limit is unlimited, this check is an empty macro.
*/
#define ECMA_CHECK_STACK_USAGE()
#endif /* (JERRY_STACK_LIMIT != 0) */
/** /**
* @} * @}
* @} * @}
+15
View File
@@ -1599,6 +1599,21 @@ ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG); ((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG);
} /* ecma_bytecode_deref */ } /* ecma_bytecode_deref */
#if (JERRY_STACK_LIMIT != 0)
/**
* Check the current stack usage by calculating the difference from the initial stack base.
*
* @return current stack usage in bytes
*/
uintptr_t JERRY_ATTR_NOINLINE
ecma_get_current_stack_usage (void)
{
volatile int __sp;
return (uintptr_t) (JERRY_CONTEXT (stack_base) - (uintptr_t)&__sp);
} /* ecma_get_current_stack_usage */
#endif /* (JERRY_STACK_LIMIT != 0) */
/** /**
* @} * @}
* @} * @}
+3
View File
@@ -393,6 +393,9 @@ ecma_value_t ecma_clear_error_reference (ecma_value_t value, bool set_abort_flag
void ecma_bytecode_ref (ecma_compiled_code_t *bytecode_p); void ecma_bytecode_ref (ecma_compiled_code_t *bytecode_p);
void ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p); void ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p);
#if (JERRY_STACK_LIMIT != 0)
uintptr_t ecma_get_current_stack_usage (void);
#endif /* (JERRY_STACK_LIMIT != 0) */
/* ecma-helpers-external-pointers.c */ /* ecma-helpers-external-pointers.c */
bool ecma_create_native_pointer_property (ecma_object_t *obj_p, void *native_p, void *info_p); bool ecma_create_native_pointer_property (ecma_object_t *obj_p, void *native_p, void *info_p);
+4 -3
View File
@@ -42,9 +42,10 @@ ecma_init (void)
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_HIGH_PRESSURE_GC; JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_HIGH_PRESSURE_GC;
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ #endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
#if defined (JERRY_CALL_STACK_LIMIT) && (JERRY_CALL_STACK_LIMIT != 0) #if (JERRY_STACK_LIMIT != 0)
JERRY_CONTEXT (function_call_counter) = JERRY_CALL_STACK_LIMIT; volatile int sp;
#endif /* defined (JERRY_CALL_STACK_LIMIT) && (JERRY_CALL_STACK_LIMIT != 0) */ JERRY_CONTEXT (stack_base) = (uintptr_t)&sp;
#endif /* (JERRY_STACK_LIMIT != 0) */
#if ENABLED (JERRY_ES2015_BUILTIN_PROMISE) #if ENABLED (JERRY_ES2015_BUILTIN_PROMISE)
ecma_job_queue_init (); ecma_job_queue_init ();
@@ -705,16 +705,7 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
|| ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION || ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION
|| !ecma_op_function_has_construct_flag (arguments_list_p)); || !ecma_op_function_has_construct_flag (arguments_list_p));
#if defined (JERRY_CALL_STACK_LIMIT) && (JERRY_CALL_STACK_LIMIT != 0) ECMA_CHECK_STACK_USAGE ();
if (JERRY_UNLIKELY (JERRY_CONTEXT (function_call_counter) == 0))
{
return ecma_raise_range_error (ECMA_ERR_MSG ("Maximum call stack size is exceeded."));
}
else
{
JERRY_CONTEXT (function_call_counter)--;
}
#endif /* defined (JERRY_CALL_STACK_LIMIT) && (JERRY_CALL_STACK_LIMIT != 0) */
switch (ecma_get_object_type (func_obj_p)) switch (ecma_get_object_type (func_obj_p))
{ {
@@ -729,10 +720,6 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
arguments_list_p, arguments_list_p,
arguments_list_len); arguments_list_len);
#if defined (JERRY_CALL_STACK_LIMIT) && (JERRY_CALL_STACK_LIMIT != 0)
JERRY_CONTEXT (function_call_counter)++;
#endif /* defined (JERRY_CALL_STACK_LIMIT) && (JERRY_CALL_STACK_LIMIT != 0) */
return ret_value; return ret_value;
} }
@@ -823,10 +810,6 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
ecma_free_value (this_binding); ecma_free_value (this_binding);
} }
#if defined (JERRY_CALL_STACK_LIMIT) && (JERRY_CALL_STACK_LIMIT != 0)
JERRY_CONTEXT (function_call_counter)++;
#endif /* defined (JERRY_CALL_STACK_LIMIT) && (JERRY_CALL_STACK_LIMIT != 0) */
return ret_value; return ret_value;
} }
case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION: case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION:
@@ -837,9 +820,6 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
this_arg_value, this_arg_value,
arguments_list_p, arguments_list_p,
arguments_list_len); arguments_list_len);
#if defined (JERRY_CALL_STACK_LIMIT) && (JERRY_CALL_STACK_LIMIT != 0)
JERRY_CONTEXT (function_call_counter)++;
#endif /* defined (JERRY_CALL_STACK_LIMIT) && (JERRY_CALL_STACK_LIMIT != 0) */
if (JERRY_UNLIKELY (ecma_is_value_error_reference (ret_value))) if (JERRY_UNLIKELY (ecma_is_value_error_reference (ret_value)))
{ {
@@ -888,10 +868,6 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
ecma_deref_object (local_env_p); ecma_deref_object (local_env_p);
} }
#if defined (JERRY_CALL_STACK_LIMIT) && (JERRY_CALL_STACK_LIMIT != 0)
JERRY_CONTEXT (function_call_counter)++;
#endif /* defined (JERRY_CALL_STACK_LIMIT) && (JERRY_CALL_STACK_LIMIT != 0) */
return ret_value; return ret_value;
} }
#endif /* ENABLED (JERRY_ES2015_ARROW_FUNCTION) */ #endif /* ENABLED (JERRY_ES2015_ARROW_FUNCTION) */
@@ -902,10 +878,6 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
} }
} }
#if defined (JERRY_CALL_STACK_LIMIT) && (JERRY_CALL_STACK_LIMIT != 0)
JERRY_CONTEXT (function_call_counter)++;
#endif /* defined (JERRY_CALL_STACK_LIMIT) && (JERRY_CALL_STACK_LIMIT != 0) */
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_DIRECT_EVAL; JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_DIRECT_EVAL;
ecma_extended_object_t *ext_function_p; ecma_extended_object_t *ext_function_p;
@@ -22,6 +22,7 @@
#include "ecma-objects.h" #include "ecma-objects.h"
#include "ecma-regexp-object.h" #include "ecma-regexp-object.h"
#include "ecma-try-catch-macro.h" #include "ecma-try-catch-macro.h"
#include "jcontext.h"
#include "jrt-libc-includes.h" #include "jrt-libc-includes.h"
#include "lit-char-helpers.h" #include "lit-char-helpers.h"
#include "re-compiler.h" #include "re-compiler.h"
@@ -63,13 +64,6 @@
*/ */
#define RE_IS_CAPTURE_GROUP(x) (((x) < RE_OP_NON_CAPTURE_GROUP_START) ? 1 : 0) #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) * 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 *str_p, /**< input string pointer */
const lit_utf8_byte_t **out_str_p) /**< [out] matching substring iterator */ 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; const lit_utf8_byte_t *str_curr_p = str_p;
while (true) 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"); JERRY_TRACE_MSG ("Execute RE_OP_MATCH: match\n");
*out_str_p = str_curr_p; *out_str_p = str_curr_p;
REGEXP_RECURSION_COUNTER_INCREASE ();
return ECMA_VALUE_TRUE; /* match */ return ECMA_VALUE_TRUE; /* match */
} }
case RE_OP_CHAR: case RE_OP_CHAR:
{ {
if (str_curr_p >= re_ctx_p->input_end_p) if (str_curr_p >= re_ctx_p->input_end_p)
{ {
REGEXP_RECURSION_COUNTER_INCREASE ();
return ECMA_VALUE_FALSE; /* fail */ 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) if (ch1 != ch2)
{ {
JERRY_TRACE_MSG ("fail\n"); JERRY_TRACE_MSG ("fail\n");
REGEXP_RECURSION_COUNTER_INCREASE ();
return ECMA_VALUE_FALSE; /* fail */ 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) if (str_curr_p >= re_ctx_p->input_end_p)
{ {
REGEXP_RECURSION_COUNTER_INCREASE ();
return ECMA_VALUE_FALSE; /* fail */ 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)) if (lit_char_is_line_terminator (ch))
{ {
JERRY_TRACE_MSG ("fail\n"); JERRY_TRACE_MSG ("fail\n");
REGEXP_RECURSION_COUNTER_INCREASE ();
return ECMA_VALUE_FALSE; /* fail */ 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)) if (!(re_ctx_p->flags & RE_FLAG_MULTILINE))
{ {
JERRY_TRACE_MSG ("fail\n"); JERRY_TRACE_MSG ("fail\n");
REGEXP_RECURSION_COUNTER_INCREASE ();
return ECMA_VALUE_FALSE; /* fail */ 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"); JERRY_TRACE_MSG ("fail\n");
REGEXP_RECURSION_COUNTER_INCREASE ();
return ECMA_VALUE_FALSE; /* fail */ return ECMA_VALUE_FALSE; /* fail */
} }
case RE_OP_ASSERT_END: 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)) if (!(re_ctx_p->flags & RE_FLAG_MULTILINE))
{ {
JERRY_TRACE_MSG ("fail\n"); JERRY_TRACE_MSG ("fail\n");
REGEXP_RECURSION_COUNTER_INCREASE ();
return ECMA_VALUE_FALSE; /* fail */ 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"); JERRY_TRACE_MSG ("fail\n");
REGEXP_RECURSION_COUNTER_INCREASE ();
return ECMA_VALUE_FALSE; /* fail */ return ECMA_VALUE_FALSE; /* fail */
} }
case RE_OP_ASSERT_WORD_BOUNDARY: 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) if (is_wordchar_left == is_wordchar_right)
{ {
JERRY_TRACE_MSG ("fail\n"); JERRY_TRACE_MSG ("fail\n");
REGEXP_RECURSION_COUNTER_INCREASE ();
return ECMA_VALUE_FALSE; /* fail */ 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) if (is_wordchar_left != is_wordchar_right)
{ {
JERRY_TRACE_MSG ("fail\n"); JERRY_TRACE_MSG ("fail\n");
REGEXP_RECURSION_COUNTER_INCREASE ();
return ECMA_VALUE_FALSE; /* fail */ 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); JMEM_FINALIZE_LOCAL_ARRAY (saved_bck_p);
REGEXP_RECURSION_COUNTER_INCREASE ();
return match_value; return match_value;
} }
case RE_OP_CHAR_CLASS: 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) if (str_curr_p >= re_ctx_p->input_end_p)
{ {
JERRY_TRACE_MSG ("fail\n"); JERRY_TRACE_MSG ("fail\n");
REGEXP_RECURSION_COUNTER_INCREASE ();
return ECMA_VALUE_FALSE; /* fail */ 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) if (!is_match)
{ {
JERRY_TRACE_MSG ("fail\n"); JERRY_TRACE_MSG ("fail\n");
REGEXP_RECURSION_COUNTER_INCREASE ();
return ECMA_VALUE_FALSE; /* fail */ 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) if (is_match)
{ {
JERRY_TRACE_MSG ("fail\n"); JERRY_TRACE_MSG ("fail\n");
REGEXP_RECURSION_COUNTER_INCREASE ();
return ECMA_VALUE_FALSE; /* fail */ 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) if (str_curr_p >= re_ctx_p->input_end_p)
{ {
JERRY_TRACE_MSG ("fail\n"); JERRY_TRACE_MSG ("fail\n");
REGEXP_RECURSION_COUNTER_INCREASE ();
return ECMA_VALUE_FALSE; /* fail */ 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) if (ch1 != ch2)
{ {
JERRY_TRACE_MSG ("fail\n"); JERRY_TRACE_MSG ("fail\n");
REGEXP_RECURSION_COUNTER_INCREASE ();
return ECMA_VALUE_FALSE; /* fail */ 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)) if (ecma_is_value_true (match_value))
{ {
*out_str_p = sub_str_p; *out_str_p = sub_str_p;
REGEXP_RECURSION_COUNTER_INCREASE ();
return match_value; /* match */ return match_value; /* match */
} }
else if (ECMA_IS_VALUE_ERROR (match_value)) 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; bc_p = old_bc_p;
re_ctx_p->saved_p[RE_GLOBAL_START_IDX] = old_start_p; re_ctx_p->saved_p[RE_GLOBAL_START_IDX] = old_start_p;
REGEXP_RECURSION_COUNTER_INCREASE ();
return ECMA_VALUE_FALSE; /* fail */ return ECMA_VALUE_FALSE; /* fail */
} }
case RE_OP_SAVE_AND_MATCH: 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"); JERRY_TRACE_MSG ("End of pattern is reached: match\n");
re_ctx_p->saved_p[RE_GLOBAL_END_IDX] = str_curr_p; re_ctx_p->saved_p[RE_GLOBAL_END_IDX] = str_curr_p;
*out_str_p = str_curr_p; *out_str_p = str_curr_p;
REGEXP_RECURSION_COUNTER_INCREASE ();
return ECMA_VALUE_TRUE; /* match */ return ECMA_VALUE_TRUE; /* match */
} }
case RE_OP_ALTERNATIVE: 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)) if (ecma_is_value_true (match_value))
{ {
*out_str_p = sub_str_p; *out_str_p = sub_str_p;
REGEXP_RECURSION_COUNTER_INCREASE ();
return match_value; /* match */ return match_value; /* match */
} }
else if (ECMA_IS_VALUE_ERROR (match_value)) 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)) if (ecma_is_value_true (match_value))
{ {
*out_str_p = sub_str_p; *out_str_p = sub_str_p;
REGEXP_RECURSION_COUNTER_INCREASE ();
return match_value; /* match */ return match_value; /* match */
} }
else if (ECMA_IS_VALUE_ERROR (match_value)) 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)) if (ecma_is_value_true (match_value))
{ {
*out_str_p = sub_str_p; *out_str_p = sub_str_p;
REGEXP_RECURSION_COUNTER_INCREASE ();
return match_value; /* match */ return match_value; /* match */
} }
else if (ECMA_IS_VALUE_ERROR (match_value)) 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; re_ctx_p->saved_p[start_idx] = old_start_p;
REGEXP_RECURSION_COUNTER_INCREASE ();
return ECMA_VALUE_FALSE; /* fail */ return ECMA_VALUE_FALSE; /* fail */
} }
case RE_OP_CAPTURE_NON_GREEDY_GROUP_END: 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)) if (ecma_is_value_true (match_value))
{ {
*out_str_p = sub_str_p; *out_str_p = sub_str_p;
REGEXP_RECURSION_COUNTER_INCREASE ();
return match_value; /* match */ return match_value; /* match */
} }
else if (ECMA_IS_VALUE_ERROR (match_value)) 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 if (re_ctx_p->num_of_iterations_p[iter_idx] >= min
&& str_curr_p== re_ctx_p->saved_p[start_idx]) && str_curr_p== re_ctx_p->saved_p[start_idx])
{ {
REGEXP_RECURSION_COUNTER_INCREASE ();
return ECMA_VALUE_FALSE; /* fail */ 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)) if (ecma_is_value_true (match_value))
{ {
*out_str_p = sub_str_p; *out_str_p = sub_str_p;
REGEXP_RECURSION_COUNTER_INCREASE ();
return match_value; /* match */ return match_value; /* match */
} }
else if (ECMA_IS_VALUE_ERROR (match_value)) 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)) if (ecma_is_value_true (match_value))
{ {
*out_str_p = sub_str_p; *out_str_p = sub_str_p;
REGEXP_RECURSION_COUNTER_INCREASE ();
return match_value; /* match */ return match_value; /* match */
} }
else if (ECMA_IS_VALUE_ERROR (match_value)) 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)) if (ecma_is_value_true (match_value))
{ {
*out_str_p = sub_str_p; *out_str_p = sub_str_p;
REGEXP_RECURSION_COUNTER_INCREASE ();
return match_value; /* match */ return match_value; /* match */
} }
else if (ECMA_IS_VALUE_ERROR (match_value)) 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 */ /* restore if fails */
re_ctx_p->saved_p[end_idx] = old_end_p; re_ctx_p->saved_p[end_idx] = old_end_p;
re_ctx_p->num_of_iterations_p[iter_idx]--; re_ctx_p->num_of_iterations_p[iter_idx]--;
REGEXP_RECURSION_COUNTER_INCREASE ();
return ECMA_VALUE_FALSE; /* fail */ return ECMA_VALUE_FALSE; /* fail */
} }
case RE_OP_NON_GREEDY_ITERATOR: 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)) if (ecma_is_value_true (match_value))
{ {
*out_str_p = sub_str_p; *out_str_p = sub_str_p;
REGEXP_RECURSION_COUNTER_INCREASE ();
return match_value; /* match */ return match_value; /* match */
} }
else if (ECMA_IS_VALUE_ERROR (match_value)) 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; str_curr_p = sub_str_p;
num_of_iter++; num_of_iter++;
} }
REGEXP_RECURSION_COUNTER_INCREASE ();
return ECMA_VALUE_FALSE; /* fail */ return ECMA_VALUE_FALSE; /* fail */
} }
default: 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)) if (ecma_is_value_true (match_value))
{ {
*out_str_p = sub_str_p; *out_str_p = sub_str_p;
REGEXP_RECURSION_COUNTER_INCREASE ();
return match_value; /* match */ return match_value; /* match */
} }
else if (ECMA_IS_VALUE_ERROR (match_value)) 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); lit_utf8_read_prev (&str_curr_p);
num_of_iter--; num_of_iter--;
} }
REGEXP_RECURSION_COUNTER_INCREASE ();
return ECMA_VALUE_FALSE; /* fail */ 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; re_ctx.input_start_p = input_curr_p;
const lit_utf8_byte_t *input_end_p = re_ctx.input_start_p + input_buffer_size; const lit_utf8_byte_t *input_end_p = re_ctx.input_start_p + input_buffer_size;
re_ctx.input_end_p = input_end_p; re_ctx.input_end_p = input_end_p;
REGEXP_RECURSION_COUNTER_INIT ();
/* 1. Read bytecode header and init regexp matcher context. */ /* 1. Read bytecode header and init regexp matcher context. */
re_ctx.flags = bc_p->header.status_flags; re_ctx.flags = bc_p->header.status_flags;
@@ -28,46 +28,6 @@
* @{ * @{
*/ */
#if defined (JERRY_REGEXP_RECURSION_LIMIT) && (JERRY_REGEXP_RECURSION_LIMIT != 0)
/**
* Decrease the recursion counter and test it.
* If the counter reaches the limit of the recursion depth
* it will return with a range error.
*/
#define REGEXP_RECURSION_COUNTER_DECREASE_AND_TEST() \
do \
{ \
if (--re_ctx_p->recursion_counter == 0) \
{ \
return ecma_raise_range_error (ECMA_ERR_MSG ("RegExp recursion limit is exceeded.")); \
} \
} \
while (0)
/**
* Increase the recursion counter.
*/
#define REGEXP_RECURSION_COUNTER_INCREASE() (++re_ctx_p->recursion_counter)
/**
* Set the recursion counter to the max depth of the recursion.
*/
#define REGEXP_RECURSION_COUNTER_INIT() (re_ctx.recursion_counter = JERRY_REGEXP_RECURSION_LIMIT)
#else /* !(defined (JERRY_REGEXP_RECURSION_LIMIT) && (JERRY_REGEXP_RECURSION_LIMIT != 0)) */
/**
* Decrease the recursion counter and test it.
* If the counter reaches the limit of the recursion depth
* it will return with a range error.
*/
#define REGEXP_RECURSION_COUNTER_DECREASE_AND_TEST()
/**
* Increase the recursion counter.
*/
#define REGEXP_RECURSION_COUNTER_INCREASE()
/**
* Set the recursion counter to the max depth of the recursion.
*/
#define REGEXP_RECURSION_COUNTER_INIT()
#endif /* defined (JERRY_REGEXP_RECURSION_LIMIT) && (JERRY_REGEXP_RECURSION_LIMIT != 0) */
/** /**
* RegExp flags * RegExp flags
* Note: * Note:
@@ -88,9 +48,6 @@ typedef struct
const lit_utf8_byte_t **saved_p; /**< saved result string pointers, ECMA 262 v5, 15.10.2.1, State */ const lit_utf8_byte_t **saved_p; /**< saved result string pointers, ECMA 262 v5, 15.10.2.1, State */
const lit_utf8_byte_t *input_start_p; /**< start of input pattern string */ const lit_utf8_byte_t *input_start_p; /**< start of input pattern string */
const lit_utf8_byte_t *input_end_p; /**< end of input pattern string */ const lit_utf8_byte_t *input_end_p; /**< end of input pattern string */
#if defined (JERRY_REGEXP_RECURSION_LIMIT) && (JERRY_REGEXP_RECURSION_LIMIT != 0)
uint32_t recursion_counter; /**< RegExp recursion counter */
#endif /* defined (JERRY_REGEXP_RECURSION_LIMIT) && (JERRY_REGEXP_RECURSION_LIMIT != 0) */
uint32_t num_of_captures; /**< number of capture groups */ uint32_t num_of_captures; /**< number of capture groups */
uint32_t num_of_non_captures; /**< number of non-capture groups */ uint32_t num_of_non_captures; /**< number of non-capture groups */
uint32_t *num_of_iterations_p; /**< number of iterations */ uint32_t *num_of_iterations_p; /**< number of iterations */
+8 -3
View File
@@ -42,6 +42,11 @@
*/ */
#define CONFIG_MEM_HEAP_SIZE (JERRY_GLOBAL_HEAP_SIZE * 1024) #define CONFIG_MEM_HEAP_SIZE (JERRY_GLOBAL_HEAP_SIZE * 1024)
/**
* Maximum stack usage size in bytes
*/
#define CONFIG_MEM_STACK_LIMIT (JERRY_STACK_LIMIT * 1024)
/** /**
* Max heap usage limit * Max heap usage limit
*/ */
@@ -169,9 +174,9 @@ struct jerry_context_t
* ECMAScript execution should be stopped */ * ECMAScript execution should be stopped */
#endif /* ENABLED (JERRY_VM_EXEC_STOP) */ #endif /* ENABLED (JERRY_VM_EXEC_STOP) */
#if defined (JERRY_CALL_STACK_LIMIT) && (JERRY_CALL_STACK_LIMIT != 0) #if (JERRY_STACK_LIMIT != 0)
uint32_t function_call_counter; /**< Function call recursion counter */ uintptr_t stack_base; /**< stack base marker */
#endif /* defined (JERRY_CALL_STACK_LIMIT) && (JERRY_CALL_STACK_LIMIT != 0) */ #endif /* (JERRY_STACK_LIMIT != 0) */
#if ENABLED (JERRY_DEBUGGER) #if ENABLED (JERRY_DEBUGGER)
uint8_t debugger_send_buffer[JERRY_DEBUGGER_TRANSPORT_MAX_BUFFER_SIZE]; /**< buffer for sending messages */ uint8_t debugger_send_buffer[JERRY_DEBUGGER_TRANSPORT_MAX_BUFFER_SIZE]; /**< buffer for sending messages */
+1 -4
View File
@@ -246,7 +246,7 @@ static ecma_value_t
re_parse_alternative (re_compiler_ctx_t *re_ctx_p, /**< RegExp compiler context */ re_parse_alternative (re_compiler_ctx_t *re_ctx_p, /**< RegExp compiler context */
bool expect_eof) /**< expect end of file */ bool expect_eof) /**< expect end of file */
{ {
REGEXP_RECURSION_COUNTER_DECREASE_AND_TEST (); ECMA_CHECK_STACK_USAGE ();
uint32_t idx; uint32_t idx;
re_bytecode_ctx_t *bc_ctx_p = re_ctx_p->bytecode_ctx_p; re_bytecode_ctx_t *bc_ctx_p = re_ctx_p->bytecode_ctx_p;
ecma_value_t ret_value = ECMA_VALUE_EMPTY; ecma_value_t ret_value = ECMA_VALUE_EMPTY;
@@ -441,7 +441,6 @@ re_parse_alternative (re_compiler_ctx_t *re_ctx_p, /**< RegExp compiler context
else else
{ {
re_insert_u32 (bc_ctx_p, alterantive_offset, re_get_bytecode_length (bc_ctx_p) - alterantive_offset); re_insert_u32 (bc_ctx_p, alterantive_offset, re_get_bytecode_length (bc_ctx_p) - alterantive_offset);
REGEXP_RECURSION_COUNTER_INCREASE ();
should_loop = false; should_loop = false;
} }
break; break;
@@ -455,7 +454,6 @@ re_parse_alternative (re_compiler_ctx_t *re_ctx_p, /**< RegExp compiler context
else else
{ {
re_insert_u32 (bc_ctx_p, alterantive_offset, re_get_bytecode_length (bc_ctx_p) - alterantive_offset); re_insert_u32 (bc_ctx_p, alterantive_offset, re_get_bytecode_length (bc_ctx_p) - alterantive_offset);
REGEXP_RECURSION_COUNTER_INCREASE ();
should_loop = false; should_loop = false;
} }
@@ -562,7 +560,6 @@ re_compile_bytecode (const re_compiled_code_t **out_bytecode_p, /**< [out] point
re_ctx.flags = flags; re_ctx.flags = flags;
re_ctx.highest_backref = 0; re_ctx.highest_backref = 0;
re_ctx.num_of_non_captures = 0; re_ctx.num_of_non_captures = 0;
REGEXP_RECURSION_COUNTER_INIT ();
re_bytecode_ctx_t bc_ctx; re_bytecode_ctx_t bc_ctx;
bc_ctx.block_start_p = NULL; bc_ctx.block_start_p = NULL;
-3
View File
@@ -41,9 +41,6 @@ typedef struct
uint32_t num_of_captures; /**< number of capture groups */ uint32_t num_of_captures; /**< number of capture groups */
uint32_t num_of_non_captures; /**< number of non-capture groups */ uint32_t num_of_non_captures; /**< number of non-capture groups */
uint32_t highest_backref; /**< highest backreference */ uint32_t highest_backref; /**< highest backreference */
#if defined (JERRY_REGEXP_RECURSION_LIMIT) && (JERRY_REGEXP_RECURSION_LIMIT != 0)
uint32_t recursion_counter; /**< RegExp recursion counter */
#endif /* defined (JERRY_REGEXP_RECURSION_LIMIT) && (JERRY_REGEXP_RECURSION_LIMIT != 0) */
re_bytecode_ctx_t *bytecode_ctx_p; /**< pointer of RegExp bytecode context */ re_bytecode_ctx_t *bytecode_ctx_p; /**< pointer of RegExp bytecode context */
re_token_t current_token; /**< current token */ re_token_t current_token; /**< current token */
re_parser_ctx_t *parser_ctx_p; /**< pointer of RegExp parser context */ re_parser_ctx_t *parser_ctx_p; /**< pointer of RegExp parser context */
-7
View File
@@ -43,13 +43,6 @@
* @{ * @{
*/ */
/*
* Check VM recursion depth limit
*/
#if defined (JERRY_CALL_STACK_LIMIT) && (JERRY_CALL_STACK_LIMIT != 0)
JERRY_STATIC_ASSERT (JERRY_CALL_STACK_LIMIT > 0, function_call_recursion_limit_must_be_greater_than_zero);
#endif /* defined (JERRY_CALL_STACK_LIMIT) && (JERRY_CALL_STACK_LIMIT != 0) */
/** /**
* Get the value of object[property]. * Get the value of object[property].
* *
+20
View File
@@ -0,0 +1,20 @@
// 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.
try {
/(?:(?=x)){1000}xyz/.exec('xyz');
assert(false);
} catch (e) {
assert(e instanceof RangeError);
}
@@ -0,0 +1,20 @@
// 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.
try {
JSON.stringify(10, Array);
assert(false);
} catch (e) {
assert(e instanceof RangeError);
}
+22
View File
@@ -0,0 +1,22 @@
// 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.
var x = new RegExp('(/*()+?b+?b+?|.|)+')
try {
x.exec('?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????');
assert(false);
} catch (e) {
assert(e instanceof RangeError);
}
@@ -12,19 +12,13 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
/* Note: if the tests suite vm-recursion-limit changes, this variable must be changed as well */
var limit = 100;
var counter = 0;
function f () { function f () {
counter++; f();
return f ();
} }
try { try {
f (); f();
assert (false); assert(false);
} catch (e) { } catch (e) {
assert (e instanceof RangeError); assert(e instanceof RangeError);
assert (counter === limit);
} }
+3 -11
View File
@@ -120,6 +120,8 @@ def get_arguments():
help='enable logging (%(choices)s)') help='enable logging (%(choices)s)')
coregrp.add_argument('--mem-heap', metavar='SIZE', type=int, coregrp.add_argument('--mem-heap', metavar='SIZE', type=int,
help='size of memory heap (in kilobytes)') help='size of memory heap (in kilobytes)')
coregrp.add_argument('--stack-limit', metavar='SIZE', type=int,
help='maximum stack usage (in kilobytes)')
coregrp.add_argument('--mem-stats', metavar='X', choices=['ON', 'OFF'], type=str.upper, coregrp.add_argument('--mem-stats', metavar='X', choices=['ON', 'OFF'], type=str.upper,
help=devhelp('enable memory statistics (%(choices)s)')) help=devhelp('enable memory statistics (%(choices)s)'))
coregrp.add_argument('--mem-stress-test', metavar='X', choices=['ON', 'OFF'], type=str.upper, coregrp.add_argument('--mem-stress-test', metavar='X', choices=['ON', 'OFF'], type=str.upper,
@@ -128,10 +130,6 @@ def get_arguments():
help='specify profile file') help='specify profile file')
coregrp.add_argument('--regexp-strict-mode', metavar='X', choices=['ON', 'OFF'], type=str.upper, coregrp.add_argument('--regexp-strict-mode', metavar='X', choices=['ON', 'OFF'], type=str.upper,
help=devhelp('enable regexp strict mode (%(choices)s)')) help=devhelp('enable regexp strict mode (%(choices)s)'))
coregrp.add_argument('--regexp-recursion-limit', metavar='N', type=int,
help='regexp recursion depth limit')
coregrp.add_argument('--call-stack-limit', metavar='N', type=int,
help='Function call recursion depth limit')
coregrp.add_argument('--show-opcodes', metavar='X', choices=['ON', 'OFF'], type=str.upper, coregrp.add_argument('--show-opcodes', metavar='X', choices=['ON', 'OFF'], type=str.upper,
help=devhelp('enable parser byte-code dumps (%(choices)s)')) help=devhelp('enable parser byte-code dumps (%(choices)s)'))
coregrp.add_argument('--show-regexp-opcodes', metavar='X', choices=['ON', 'OFF'], type=str.upper, coregrp.add_argument('--show-regexp-opcodes', metavar='X', choices=['ON', 'OFF'], type=str.upper,
@@ -156,11 +154,6 @@ def get_arguments():
parser.print_help() parser.print_help()
sys.exit(0) sys.exit(0)
if arguments.call_stack_limit:
if arguments.call_stack_limit < 0:
print ('Configuration error: Function call recursion limit must be greater or equal than 0')
sys.exit(1)
return arguments return arguments
def generate_build_options(arguments): def generate_build_options(arguments):
@@ -202,12 +195,11 @@ def generate_build_options(arguments):
build_options_append('JERRY_LINE_INFO', arguments.line_info) build_options_append('JERRY_LINE_INFO', arguments.line_info)
build_options_append('JERRY_LOGGING', arguments.logging) build_options_append('JERRY_LOGGING', arguments.logging)
build_options_append('JERRY_GLOBAL_HEAP_SIZE', arguments.mem_heap) build_options_append('JERRY_GLOBAL_HEAP_SIZE', arguments.mem_heap)
build_options_append('JERRY_STACK_LIMIT', arguments.stack_limit)
build_options_append('JERRY_MEM_STATS', arguments.mem_stats) build_options_append('JERRY_MEM_STATS', arguments.mem_stats)
build_options_append('JERRY_MEM_GC_BEFORE_EACH_ALLOC', arguments.mem_stress_test) build_options_append('JERRY_MEM_GC_BEFORE_EACH_ALLOC', arguments.mem_stress_test)
build_options_append('JERRY_PROFILE', arguments.profile) build_options_append('JERRY_PROFILE', arguments.profile)
build_options_append('JERRY_REGEXP_STRICT_MODE', arguments.regexp_strict_mode) build_options_append('JERRY_REGEXP_STRICT_MODE', arguments.regexp_strict_mode)
build_options_append('JERRY_REGEXP_RECURSION_LIMIT', arguments.regexp_recursion_limit)
build_options_append('JERRY_CALL_STACK_LIMIT', arguments.call_stack_limit)
build_options_append('JERRY_PARSER_DUMP_BYTE_CODE', arguments.show_opcodes) build_options_append('JERRY_PARSER_DUMP_BYTE_CODE', arguments.show_opcodes)
build_options_append('JERRY_REGEXP_DUMP_BYTE_CODE', arguments.show_regexp_opcodes) build_options_append('JERRY_REGEXP_DUMP_BYTE_CODE', arguments.show_regexp_opcodes)
build_options_append('JERRY_SNAPSHOT_EXEC', arguments.snapshot_exec) build_options_append('JERRY_SNAPSHOT_EXEC', arguments.snapshot_exec)
+10 -12
View File
@@ -36,7 +36,7 @@ def skip_if(condition, desc):
OPTIONS_PROFILE_MIN = ['--profile=minimal'] OPTIONS_PROFILE_MIN = ['--profile=minimal']
OPTIONS_PROFILE_ES51 = [] # NOTE: same as ['--profile=es5.1'] OPTIONS_PROFILE_ES51 = [] # NOTE: same as ['--profile=es5.1']
OPTIONS_PROFILE_ES2015 = ['--profile=es2015-subset'] OPTIONS_PROFILE_ES2015 = ['--profile=es2015-subset']
OPTIONS_CALL_STACK_LIMIT = ['--call-stack-limit=100'] OPTIONS_STACK_LIMIT = ['--stack-limit=128']
OPTIONS_DEBUG = ['--debug'] OPTIONS_DEBUG = ['--debug']
OPTIONS_SNAPSHOT = ['--snapshot-save=on', '--snapshot-exec=on', '--jerry-cmdline-snapshot=on'] OPTIONS_SNAPSHOT = ['--snapshot-save=on', '--snapshot-exec=on', '--jerry-cmdline-snapshot=on']
OPTIONS_UNITTESTS = ['--unittests=on', '--jerry-cmdline=off', '--error-messages=on', OPTIONS_UNITTESTS = ['--unittests=on', '--jerry-cmdline=off', '--error-messages=on',
@@ -68,22 +68,22 @@ JERRY_UNITTESTS_OPTIONS = [
# Test options for jerry-tests # Test options for jerry-tests
JERRY_TESTS_OPTIONS = [ JERRY_TESTS_OPTIONS = [
Options('jerry_tests-es5.1', Options('jerry_tests-es5.1',
OPTIONS_PROFILE_ES51 + OPTIONS_CALL_STACK_LIMIT), OPTIONS_PROFILE_ES51 + OPTIONS_STACK_LIMIT),
Options('jerry_tests-es5.1-snapshot', Options('jerry_tests-es5.1-snapshot',
OPTIONS_PROFILE_ES51 + OPTIONS_SNAPSHOT + OPTIONS_CALL_STACK_LIMIT, OPTIONS_PROFILE_ES51 + OPTIONS_SNAPSHOT + OPTIONS_STACK_LIMIT,
['--snapshot']), ['--snapshot']),
Options('jerry_tests-es5.1-debug', Options('jerry_tests-es5.1-debug',
OPTIONS_PROFILE_ES51 + OPTIONS_DEBUG + OPTIONS_CALL_STACK_LIMIT), OPTIONS_PROFILE_ES51 + OPTIONS_DEBUG + OPTIONS_STACK_LIMIT),
Options('jerry_tests-es5.1-debug-snapshot', Options('jerry_tests-es5.1-debug-snapshot',
OPTIONS_PROFILE_ES51 + OPTIONS_SNAPSHOT + OPTIONS_DEBUG + OPTIONS_CALL_STACK_LIMIT, OPTIONS_PROFILE_ES51 + OPTIONS_SNAPSHOT + OPTIONS_DEBUG + OPTIONS_STACK_LIMIT,
['--snapshot']), ['--snapshot']),
Options('jerry_tests-es5.1-debug-cpointer_32bit', Options('jerry_tests-es5.1-debug-cpointer_32bit',
OPTIONS_PROFILE_ES51 + OPTIONS_DEBUG + OPTIONS_CALL_STACK_LIMIT OPTIONS_PROFILE_ES51 + OPTIONS_DEBUG + OPTIONS_STACK_LIMIT
+ ['--cpointer-32bit=on', '--mem-heap=1024']), + ['--cpointer-32bit=on', '--mem-heap=1024']),
Options('jerry_tests-es5.1-debug-external_context', Options('jerry_tests-es5.1-debug-external_context',
OPTIONS_PROFILE_ES51 + OPTIONS_DEBUG + OPTIONS_CALL_STACK_LIMIT + ['--external-context=on']), OPTIONS_PROFILE_ES51 + OPTIONS_DEBUG + OPTIONS_STACK_LIMIT + ['--external-context=on']),
Options('jerry_tests-es2015_subset-debug', Options('jerry_tests-es2015_subset-debug',
OPTIONS_PROFILE_ES2015 + OPTIONS_DEBUG + OPTIONS_CALL_STACK_LIMIT), OPTIONS_PROFILE_ES2015 + OPTIONS_DEBUG + OPTIONS_STACK_LIMIT),
] ]
# Test options for jerry-test-suite # Test options for jerry-test-suite
@@ -157,10 +157,8 @@ JERRY_BUILDOPTIONS = [
['--jerry-cmdline-test=on']), ['--jerry-cmdline-test=on']),
Options('buildoption_test-cmdline_snapshot', Options('buildoption_test-cmdline_snapshot',
['--jerry-cmdline-snapshot=on']), ['--jerry-cmdline-snapshot=on']),
Options('buildoption_test-regexp_recursion_limit', Options('buildoption_test-recursion_limit',
['--regexp-recursion-limit=1000']), OPTIONS_STACK_LIMIT),
Options('buildoption_test-vm_recursion_limit',
OPTIONS_CALL_STACK_LIMIT),
Options('buildoption_test-single-source', Options('buildoption_test-single-source',
['--cmake-param=-DENABLE_ALL_IN_ONE_SOURCE=ON']), ['--cmake-param=-DENABLE_ALL_IN_ONE_SOURCE=ON']),
] ]