neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

commit 807c6bb909806b5abc3e46a9677bedfdddf2a7f0
parent b793395019333127e085997b7ced4ea02053697e
Author: zeertzjq <zeertzjq@outlook.com>
Date:   Thu, 27 Oct 2022 11:40:38 +0800

vim-patch:8.2.4206: condition with many "(" causes a crash

Problem:    Condition with many "(" causes a crash.
Solution:   Limit recursion to 1000.

https://github.com/vim/vim/commit/fe6fb267e6ee5c5da2f41889e4e0e0ac5bf4b89d

Co-authored-by: Bram Moolenaar <Bram@vim.org>

Diffstat:
Msrc/nvim/eval.c | 12++++++++++++
Msrc/nvim/testdir/test_eval_stuff.vim | 5+++++
2 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/src/nvim/eval.c b/src/nvim/eval.c @@ -65,6 +65,7 @@ static char *e_nowhitespace = N_("E274: No white space allowed before parenthesis"); static char *e_write2 = N_("E80: Error while writing: %s"); static char *e_string_list_or_blob_required = N_("E1098: String, List or Blob required"); +static char e_expression_too_recursive_str[] = N_("E1169: Expression too recursive: %s"); static char * const namespace_char = "abglstvw"; @@ -2911,6 +2912,7 @@ static int eval7(char **arg, typval_T *rettv, int evaluate, int want_string) const char *start_leader, *end_leader; int ret = OK; char *alias; + static int recurse = 0; // Initialise variable so that tv_clear() can't mistake this for a // string and free a string that isn't there. @@ -2923,6 +2925,14 @@ static int eval7(char **arg, typval_T *rettv, int evaluate, int want_string) } end_leader = *arg; + // 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) { // Number constant. case '0': @@ -3127,6 +3137,8 @@ static int eval7(char **arg, typval_T *rettv, int evaluate, int want_string) if (ret == OK && evaluate && end_leader > start_leader) { ret = eval7_leader(rettv, (char *)start_leader, &end_leader); } + + recurse--; return ret; } diff --git a/src/nvim/testdir/test_eval_stuff.vim b/src/nvim/testdir/test_eval_stuff.vim @@ -367,6 +367,11 @@ 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 + " K_SPECIAL in the modified character used be escaped, which causes " double-escaping with feedkeys() or as the return value of an <expr> mapping, " and doesn't match what getchar() returns,