aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2018-02-11 13:46:35 +0100
committerJustin M. Keyes <justinkz@gmail.com>2018-02-11 19:03:27 +0100
commitabed6a0b1a71e54b143e98678f4daa6818b02f8d (patch)
treefed29c0808a3b0fe88d1e5c41f00b4d270b42554
parent4b7f7be3018563905d55197b43707ebe4ca12e78 (diff)
downloadrneovim-abed6a0b1a71e54b143e98678f4daa6818b02f8d.tar.gz
rneovim-abed6a0b1a71e54b143e98678f4daa6818b02f8d.tar.bz2
rneovim-abed6a0b1a71e54b143e98678f4daa6818b02f8d.zip
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) https://github.com/vim/vim/commit/f12519dec88251305793f1651f558d16506b4be2
-rw-r--r--src/nvim/normal.c25
-rw-r--r--src/nvim/ops.c13
-rw-r--r--src/nvim/testdir/test_undo.vim7
-rw-r--r--src/nvim/vim.h4
4 files changed, 38 insertions, 11 deletions
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index bca4a0f93e..0feac03e32 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -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;
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 665a102253..4d974f5760 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -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
diff --git a/src/nvim/testdir/test_undo.vim b/src/nvim/testdir/test_undo.vim
index f7d1d64ea3..3373258708 100644
--- a/src/nvim/testdir/test_undo.vim
+++ b/src/nvim/testdir/test_undo.vim
@@ -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
diff --git a/src/nvim/vim.h b/src/nvim/vim.h
index b932c2d0f8..0c13d331c8 100644
--- a/src/nvim/vim.h
+++ b/src/nvim/vim.h
@@ -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