0
0
mirror of https://github.com/vim/vim.git synced 2025-09-26 04:04:07 -04:00

patch 8.0.1475: invalid memory access in read_redo()

Problem:    Invalid memory access in read_redo(). (gy741)
Solution:   Convert the replacement character back from a negative number to
            CR or NL. (hint by Dominique Pelle, closes #2616)
This commit is contained in:
Bram Moolenaar
2018-02-06 22:52:49 +01:00
parent dd08b6a32b
commit f12519dec8
5 changed files with 43 additions and 11 deletions

View File

@@ -1685,11 +1685,19 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank)
get_op_char(oap->op_type), get_extra_op_char(oap->op_type), get_op_char(oap->op_type), get_extra_op_char(oap->op_type),
oap->motion_force, cap->cmdchar, cap->nchar); oap->motion_force, cap->cmdchar, cap->nchar);
else if (cap->cmdchar != ':') else if (cap->cmdchar != ':')
{
int nchar = oap->op_type == OP_REPLACE ? cap->nchar : NUL;
/* reverse what nv_replace() did */
if (nchar == REPLACE_CR_NCHAR)
nchar = CAR;
else if (nchar == REPLACE_NL_NCHAR)
nchar = NL;
prep_redo(oap->regname, 0L, NUL, 'v', prep_redo(oap->regname, 0L, NUL, 'v',
get_op_char(oap->op_type), get_op_char(oap->op_type),
get_extra_op_char(oap->op_type), get_extra_op_char(oap->op_type),
oap->op_type == OP_REPLACE nchar);
? cap->nchar : NUL); }
if (!redo_VIsual_busy) if (!redo_VIsual_busy)
{ {
redo_VIsual_mode = resel_VIsual_mode; redo_VIsual_mode = resel_VIsual_mode;
@@ -7023,10 +7031,12 @@ nv_replace(cmdarg_T *cap)
reset_VIsual(); reset_VIsual();
if (had_ctrl_v) if (had_ctrl_v)
{ {
if (cap->nchar == '\r') /* Use a special (negative) number to make a difference between a
cap->nchar = -1; * literal CR or NL and a line break. */
else if (cap->nchar == '\n') if (cap->nchar == CAR)
cap->nchar = -2; cap->nchar = REPLACE_CR_NCHAR;
else if (cap->nchar == NL)
cap->nchar = REPLACE_NL_NCHAR;
} }
nv_operator(cap); nv_operator(cap);
return; return;

View File

@@ -2113,13 +2113,21 @@ op_replace(oparg_T *oap, int c)
size_t oldlen; size_t oldlen;
struct block_def bd; struct block_def bd;
char_u *after_p = NULL; char_u *after_p = NULL;
int had_ctrl_v_cr = (c == -1 || c == -2); int had_ctrl_v_cr = FALSE;
if ((curbuf->b_ml.ml_flags & ML_EMPTY ) || oap->empty) if ((curbuf->b_ml.ml_flags & ML_EMPTY ) || oap->empty)
return OK; /* nothing to do */ return OK; /* nothing to do */
if (had_ctrl_v_cr) if (c == REPLACE_CR_NCHAR)
c = (c == -1 ? '\r' : '\n'); {
had_ctrl_v_cr = TRUE;
c = CAR;
}
else if (c == REPLACE_NL_NCHAR)
{
had_ctrl_v_cr = TRUE;
c = NL;
}
#ifdef FEAT_MBYTE #ifdef FEAT_MBYTE
if (has_mbyte) if (has_mbyte)
@@ -2207,7 +2215,8 @@ op_replace(oparg_T *oap, int c)
/* insert pre-spaces */ /* insert pre-spaces */
vim_memset(newp + bd.textcol, ' ', (size_t)bd.startspaces); vim_memset(newp + bd.textcol, ' ', (size_t)bd.startspaces);
/* insert replacement chars CHECK FOR ALLOCATED SPACE */ /* insert replacement chars CHECK FOR ALLOCATED SPACE */
/* -1/-2 is used for entering CR literally. */ /* REPLACE_CR_NCHAR/REPLACE_NL_NCHAR is used for entering CR
* literally. */
if (had_ctrl_v_cr || (c != '\r' && c != '\n')) if (had_ctrl_v_cr || (c != '\r' && c != '\n'))
{ {
#ifdef FEAT_MBYTE #ifdef FEAT_MBYTE
@@ -6370,7 +6379,7 @@ write_viminfo_registers(FILE *fp)
* |{bartype},{flags},{name},{type}, * |{bartype},{flags},{name},{type},
* {linecount},{width},{timestamp},"line1","line2" * {linecount},{width},{timestamp},"line1","line2"
* flags: REG_PREVIOUS - register is y_previous * flags: REG_PREVIOUS - register is y_previous
* REG_EXEC - used for @@ * REG_EXEC - used for @@
*/ */
if (y_previous == &y_regs[i]) if (y_previous == &y_regs[i])
flags |= REG_PREVIOUS; flags |= REG_PREVIOUS;

View File

@@ -403,3 +403,10 @@ func Test_undo_0()
bwipe! bwipe!
endfunc endfunc
func Test_redo_empty_line()
new
exe "norm\x16r\x160"
exe "norm."
bwipe!
endfunc

View File

@@ -771,6 +771,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 */
/**/
1475,
/**/ /**/
1474, 1474,
/**/ /**/

View File

@@ -2515,4 +2515,8 @@ typedef enum {
# endif # endif
#endif #endif
/* Replacement for nchar used by nv_replace(). */
#define REPLACE_CR_NCHAR -1
#define REPLACE_NL_NCHAR -2
#endif /* VIM__H */ #endif /* VIM__H */