mirror of
https://github.com/vim/vim.git
synced 2025-09-25 03:54:15 -04:00
patch 8.2.4975: recursive command line loop may cause a crash
Problem: Recursive command line loop may cause a crash. Solution: Limit recursion of getcmdline().
This commit is contained in:
@@ -1581,6 +1581,7 @@ getcmdline_int(
|
|||||||
int indent, // indent for inside conditionals
|
int indent, // indent for inside conditionals
|
||||||
int clear_ccline) // clear ccline first
|
int clear_ccline) // clear ccline first
|
||||||
{
|
{
|
||||||
|
static int depth = 0; // call depth
|
||||||
int c;
|
int c;
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
@@ -1611,6 +1612,9 @@ getcmdline_int(
|
|||||||
int cmdline_type;
|
int cmdline_type;
|
||||||
int wild_type;
|
int wild_type;
|
||||||
|
|
||||||
|
// one recursion level deeper
|
||||||
|
++depth;
|
||||||
|
|
||||||
if (ccline.cmdbuff != NULL)
|
if (ccline.cmdbuff != NULL)
|
||||||
{
|
{
|
||||||
// Being called recursively. Since ccline is global, we need to save
|
// Being called recursively. Since ccline is global, we need to save
|
||||||
@@ -1641,6 +1645,13 @@ getcmdline_int(
|
|||||||
if (init_ccline(firstc, indent) != OK)
|
if (init_ccline(firstc, indent) != OK)
|
||||||
goto theend; // out of memory
|
goto theend; // out of memory
|
||||||
|
|
||||||
|
if (depth == 50)
|
||||||
|
{
|
||||||
|
// Somehow got into a loop recursively calling getcmdline(), bail out.
|
||||||
|
emsg(_(e_command_too_recursive));
|
||||||
|
goto theend;
|
||||||
|
}
|
||||||
|
|
||||||
ExpandInit(&xpc);
|
ExpandInit(&xpc);
|
||||||
ccline.xpc = &xpc;
|
ccline.xpc = &xpc;
|
||||||
|
|
||||||
@@ -2576,6 +2587,7 @@ theend:
|
|||||||
{
|
{
|
||||||
char_u *p = ccline.cmdbuff;
|
char_u *p = ccline.cmdbuff;
|
||||||
|
|
||||||
|
--depth;
|
||||||
if (did_save_ccline)
|
if (did_save_ccline)
|
||||||
restore_cmdline(&save_ccline);
|
restore_cmdline(&save_ccline);
|
||||||
else
|
else
|
||||||
|
@@ -3392,4 +3392,16 @@ func Test_screenpos_and_completion()
|
|||||||
call feedkeys(":let a\<C-R>=Check_completion()\<CR>\<Esc>", "xt")
|
call feedkeys(":let a\<C-R>=Check_completion()\<CR>\<Esc>", "xt")
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_recursive_register()
|
||||||
|
let @= = ''
|
||||||
|
silent! ?e/
|
||||||
|
let caught = 'no'
|
||||||
|
try
|
||||||
|
normal //
|
||||||
|
catch /E169:/
|
||||||
|
let caught = 'yes'
|
||||||
|
endtry
|
||||||
|
call assert_equal('yes', caught)
|
||||||
|
endfunc
|
||||||
|
|
||||||
" vim: shiftwidth=2 sts=2 expandtab
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
@@ -746,6 +746,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
4975,
|
||||||
/**/
|
/**/
|
||||||
4974,
|
4974,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user