mirror of
https://github.com/neovim/neovim.git
synced 2025-09-17 16:58:17 +00:00
vim-patch:8.2.4206: condition with many "(" causes a crash
Problem: Condition with many "(" causes a crash.
Solution: Limit recursion to 1000.
fe6fb267e6
Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
@@ -65,6 +65,7 @@ static char *e_nowhitespace
|
|||||||
= N_("E274: No white space allowed before parenthesis");
|
= N_("E274: No white space allowed before parenthesis");
|
||||||
static char *e_write2 = N_("E80: Error while writing: %s");
|
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_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";
|
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;
|
const char *start_leader, *end_leader;
|
||||||
int ret = OK;
|
int ret = OK;
|
||||||
char *alias;
|
char *alias;
|
||||||
|
static int recurse = 0;
|
||||||
|
|
||||||
// Initialise variable so that tv_clear() can't mistake this for a
|
// Initialise variable so that tv_clear() can't mistake this for a
|
||||||
// string and free a string that isn't there.
|
// 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;
|
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) {
|
switch (**arg) {
|
||||||
// Number constant.
|
// Number constant.
|
||||||
case '0':
|
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) {
|
if (ret == OK && evaluate && end_leader > start_leader) {
|
||||||
ret = eval7_leader(rettv, (char *)start_leader, &end_leader);
|
ret = eval7_leader(rettv, (char *)start_leader, &end_leader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
recurse--;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -367,6 +367,11 @@ func Test_curly_assignment()
|
|||||||
unlet g:gvar
|
unlet g:gvar
|
||||||
endfunc
|
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
|
" K_SPECIAL in the modified character used be escaped, which causes
|
||||||
" double-escaping with feedkeys() or as the return value of an <expr> mapping,
|
" double-escaping with feedkeys() or as the return value of an <expr> mapping,
|
||||||
" and doesn't match what getchar() returns,
|
" and doesn't match what getchar() returns,
|
||||||
|
Reference in New Issue
Block a user