vim-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 vim/vim#2616)

f12519dec8
This commit is contained in:
Justin M. Keyes 2018-02-11 13:46:35 +01:00
parent 4b7f7be301
commit abed6a0b1a
4 changed files with 38 additions and 11 deletions

View File

@ -1641,12 +1641,20 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
prep_redo(oap->regname, cap->count0,
get_op_char(oap->op_type), get_extra_op_char(oap->op_type),
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',
get_op_char(oap->op_type),
get_extra_op_char(oap->op_type),
oap->op_type == OP_REPLACE
? cap->nchar : NUL);
nchar);
}
if (!redo_VIsual_busy) {
redo_VIsual_mode = resel_VIsual_mode;
redo_VIsual_vcol = resel_VIsual_vcol;
@ -5854,10 +5862,13 @@ static void nv_replace(cmdarg_T *cap)
if (got_int)
reset_VIsual();
if (had_ctrl_v) {
if (cap->nchar == '\r')
cap->nchar = -1;
else if (cap->nchar == '\n')
cap->nchar = -2;
// Use a special (negative) number to make a difference between a
// literal CR or NL and a line break.
if (cap->nchar == CAR) {
cap->nchar = REPLACE_CR_NCHAR;
} else if (cap->nchar == NL) {
cap->nchar = REPLACE_NL_NCHAR;
}
}
nv_operator(cap);
return;

View File

@ -1629,13 +1629,18 @@ int op_replace(oparg_T *oap, int c)
colnr_T oldlen;
struct block_def bd;
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)
return OK; /* nothing to do */
if (had_ctrl_v_cr)
c = (c == -1 ? '\r' : '\n');
if (c == REPLACE_CR_NCHAR) {
had_ctrl_v_cr = true;
c = CAR;
} else if (c == REPLACE_NL_NCHAR) {
had_ctrl_v_cr = true;
c = NL;
}
if (has_mbyte)
mb_adjust_opend(oap);
@ -1713,7 +1718,7 @@ int op_replace(oparg_T *oap, int c)
// insert pre-spaces
memset(newp + bd.textcol, ' ', (size_t)bd.startspaces);
// 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.
size_t after_p_len = 0;
if (had_ctrl_v_cr || (c != '\r' && c != '\n')) {
// strlen(newp) at this point

View File

@ -282,3 +282,10 @@ func Test_cmd_in_reg_undo()
only!
let @a=''
endfunc
func Test_redo_empty_line()
new
exe "norm\x16r\x160"
exe "norm."
bwipe!
endfunc

View File

@ -313,4 +313,8 @@ enum { FOLD_TEXT_LEN = 51 }; //!< buffer size for get_foldtext()
# define OPEN_CHR_FILES
#endif
// Replacement for nchar used by nv_replace().
#define REPLACE_CR_NCHAR -1
#define REPLACE_NL_NCHAR -2
#endif // NVIM_VIM_H