forked from aniani/vim
patch 8.2.5023: substitute overwrites allocated buffer
Problem: Substitute overwrites allocated buffer. Solution: Disallow undo when in a substitute command.
This commit is contained in:
42
src/normal.c
42
src/normal.c
@@ -183,6 +183,22 @@ find_command(int cmdchar)
|
||||
return idx;
|
||||
}
|
||||
|
||||
/*
|
||||
* If currently editing a cmdline or text is locked: beep and give an error
|
||||
* message, return TRUE.
|
||||
*/
|
||||
static int
|
||||
check_text_locked(oparg_T *oap)
|
||||
{
|
||||
if (text_locked())
|
||||
{
|
||||
clearopbeep(oap);
|
||||
text_locked_msg();
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle the count before a normal command and set cap->count0.
|
||||
*/
|
||||
@@ -802,14 +818,9 @@ normal_cmd(
|
||||
goto normal_end;
|
||||
}
|
||||
|
||||
if (text_locked() && (nv_cmds[idx].cmd_flags & NV_NCW))
|
||||
{
|
||||
// This command is not allowed while editing a cmdline: beep.
|
||||
clearopbeep(oap);
|
||||
text_locked_msg();
|
||||
goto normal_end;
|
||||
}
|
||||
if ((nv_cmds[idx].cmd_flags & NV_NCW) && curbuf_locked())
|
||||
if ((nv_cmds[idx].cmd_flags & NV_NCW)
|
||||
&& (check_text_locked(oap) || curbuf_locked()))
|
||||
// this command is not allowed now
|
||||
goto normal_end;
|
||||
|
||||
// In Visual/Select mode, a few keys are handled in a special way.
|
||||
@@ -4049,12 +4060,8 @@ nv_gotofile(cmdarg_T *cap)
|
||||
char_u *ptr;
|
||||
linenr_T lnum = -1;
|
||||
|
||||
if (text_locked())
|
||||
{
|
||||
clearopbeep(cap->oap);
|
||||
text_locked_msg();
|
||||
if (check_text_locked(cap->oap))
|
||||
return;
|
||||
}
|
||||
if (curbuf_locked())
|
||||
{
|
||||
clearop(cap->oap);
|
||||
@@ -6182,14 +6189,7 @@ nv_g_cmd(cmdarg_T *cap)
|
||||
|
||||
// "gQ": improved Ex mode
|
||||
case 'Q':
|
||||
if (text_locked())
|
||||
{
|
||||
clearopbeep(cap->oap);
|
||||
text_locked_msg();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!checkclearopq(oap))
|
||||
if (!check_text_locked(cap->oap) && !checkclearopq(oap))
|
||||
do_exmode(TRUE);
|
||||
break;
|
||||
|
||||
|
@@ -1013,6 +1013,28 @@ func Test_sub_change_window()
|
||||
delfunc Repl
|
||||
endfunc
|
||||
|
||||
" This was undoign a change in between computing the length and using it.
|
||||
func Do_Test_sub_undo_change()
|
||||
new
|
||||
norm o0000000000000000000000000000000000000000000000000000
|
||||
silent! s/\%')/\=Repl()
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
func Test_sub_undo_change()
|
||||
func Repl()
|
||||
silent! norm g-
|
||||
endfunc
|
||||
call Do_Test_sub_undo_change()
|
||||
|
||||
func! Repl()
|
||||
silent earlier
|
||||
endfunc
|
||||
call Do_Test_sub_undo_change()
|
||||
|
||||
delfunc Repl
|
||||
endfunc
|
||||
|
||||
" Test for the 2-letter and 3-letter :substitute commands
|
||||
func Test_substitute_short_cmd()
|
||||
new
|
||||
|
@@ -2327,6 +2327,12 @@ undo_time(
|
||||
int above = FALSE;
|
||||
int did_undo = TRUE;
|
||||
|
||||
if (text_locked())
|
||||
{
|
||||
text_locked_msg();
|
||||
return;
|
||||
}
|
||||
|
||||
// First make sure the current undoable change is synced.
|
||||
if (curbuf->b_u_synced == FALSE)
|
||||
u_sync(TRUE);
|
||||
|
@@ -734,6 +734,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
5023,
|
||||
/**/
|
||||
5022,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user