diff options
-rw-r--r-- | src/errors.h | 7 | ||||
-rw-r--r-- | src/eval.c | 12 | ||||
-rw-r--r-- | src/testdir/test_eval_stuff.vim | 5 | ||||
-rw-r--r-- | src/version.c | 2 |
4 files changed, 25 insertions, 1 deletions
diff --git a/src/errors.h b/src/errors.h index e632d5b240..d89c27c22b 100644 --- a/src/errors.h +++ b/src/errors.h @@ -2718,6 +2718,8 @@ EXTERN char e_invalid_command_after_export[] INIT(= N_("E1043: Invalid command after :export")); EXTERN char e_export_with_invalid_argument[] INIT(= N_("E1044: Export with invalid argument")); +// E1045 not used +// E1046 not used EXTERN char e_syntax_error_in_import_str[] INIT(= N_("E1047: Syntax error in import: %s")); EXTERN char e_item_not_found_in_script_str[] @@ -2786,6 +2788,7 @@ EXTERN char e_missing_argument_type_for_str[] // E1080 unused EXTERN char e_cannot_unlet_str[] INIT(= N_("E1081: Cannot unlet %s")); +// E1082 unused EXTERN char e_missing_backtick[] INIT(= N_("E1083: Missing backtick")); EXTERN char e_cannot_delete_vim9_script_function_str[] @@ -2906,6 +2909,7 @@ EXTERN char e_for_argument_must_be_sequence_of_lists[] INIT(= N_("E1140: :for argument must be a sequence of lists")); EXTERN char e_indexable_type_required[] INIT(= N_("E1141: Indexable type required")); +// E1142 unused EXTERN char e_empty_expression_str[] INIT(= N_("E1143: Empty expression: \"%s\"")); EXTERN char e_command_str_not_followed_by_white_space_str[] @@ -2966,7 +2970,8 @@ EXTERN char e_argument_name_shadows_existing_variable_str[] INIT(= N_("E1167: Argument name shadows existing variable: %s")); EXTERN char e_argument_already_declared_in_script_str[] INIT(= N_("E1168: Argument already declared in the script: %s")); -// E1169 unused +EXTERN char e_expression_too_recursive_str[] + INIT(= N_("E1169: Expression too recursive: %s")); EXTERN char e_cannot_use_hash_curly_to_start_comment[] INIT(= N_("E1170: Cannot use #{ to start a comment")); EXTERN char e_missing_end_block[] diff --git a/src/eval.c b/src/eval.c index 2ca3377492..d42e1f8266 100644 --- a/src/eval.c +++ b/src/eval.c @@ -3526,6 +3526,7 @@ eval7( char_u *start_leader, *end_leader; int ret = OK; char_u *alias; + static int recurse = 0; /* * Initialise variable so that clear_tv() can't mistake this for a @@ -3552,6 +3553,15 @@ eval7( return FAIL; } + // Limit recursion to 1000 levels. At least at 10000 we run out of stack + // and crash. + if (recurse == 1000) + { + semsg(_(e_expression_too_recursive_str), *arg); + return FAIL; + } + ++recurse; + switch (**arg) { /* @@ -3781,6 +3791,8 @@ eval7( */ if (ret == OK && evaluate && end_leader > start_leader) ret = eval7_leader(rettv, FALSE, start_leader, &end_leader); + + --recurse; return ret; } diff --git a/src/testdir/test_eval_stuff.vim b/src/testdir/test_eval_stuff.vim index ff6d695f62..6043ed9a13 100644 --- a/src/testdir/test_eval_stuff.vim +++ b/src/testdir/test_eval_stuff.vim @@ -590,4 +590,9 @@ func Test_curly_assignment() unlet g:gvar endfunc +func Test_deep_recursion() + " this was running out of stack + call assert_fails("exe 'if ' .. repeat('(', 1002)", 'E1169: Expression too recursive: ((') +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c index 4cb980ea4a..16a99ef92e 100644 --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4206, +/**/ 4205, /**/ 4204, |