To: vim_dev@googlegroups.com Subject: Patch 8.0.1475 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.1475 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) Files: src/testdir/test_undo.vim, src/normal.c, src/vim.h, src/ops.c *** ../vim-8.0.1474/src/testdir/test_undo.vim 2018-01-30 22:46:01.405404260 +0100 --- src/testdir/test_undo.vim 2018-02-06 22:06:44.207003652 +0100 *************** *** 403,405 **** --- 403,412 ---- bwipe! endfunc + + func Test_redo_empty_line() + new + exe "norm\x16r\x160" + exe "norm." + bwipe! + endfunc *** ../vim-8.0.1474/src/normal.c 2017-12-21 20:27:40.768178638 +0100 --- src/normal.c 2018-02-06 22:44:21.569892327 +0100 *************** *** 1685,1695 **** get_op_char(oap->op_type), get_extra_op_char(oap->op_type), oap->motion_force, cap->cmdchar, cap->nchar); else if (cap->cmdchar != ':') 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); if (!redo_VIsual_busy) { redo_VIsual_mode = resel_VIsual_mode; --- 1685,1703 ---- get_op_char(oap->op_type), get_extra_op_char(oap->op_type), oap->motion_force, cap->cmdchar, cap->nchar); 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), ! nchar); ! } if (!redo_VIsual_busy) { redo_VIsual_mode = resel_VIsual_mode; *************** *** 7023,7032 **** reset_VIsual(); if (had_ctrl_v) { ! if (cap->nchar == '\r') ! cap->nchar = -1; ! else if (cap->nchar == '\n') ! cap->nchar = -2; } nv_operator(cap); return; --- 7031,7042 ---- reset_VIsual(); if (had_ctrl_v) { ! /* 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; *** ../vim-8.0.1474/src/vim.h 2018-02-03 17:36:22.630091837 +0100 --- src/vim.h 2018-02-06 22:39:44.991978664 +0100 *************** *** 2515,2518 **** --- 2515,2522 ---- # endif #endif + /* Replacement for nchar used by nv_replace(). */ + #define REPLACE_CR_NCHAR -1 + #define REPLACE_NL_NCHAR -2 + #endif /* VIM__H */ *** ../vim-8.0.1474/src/ops.c 2017-12-19 12:27:19.378404474 +0100 --- src/ops.c 2018-02-06 22:42:30.050732630 +0100 *************** *** 2113,2125 **** size_t oldlen; struct block_def bd; char_u *after_p = NULL; ! int had_ctrl_v_cr = (c == -1 || c == -2); 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'); #ifdef FEAT_MBYTE if (has_mbyte) --- 2113,2133 ---- size_t oldlen; struct block_def bd; char_u *after_p = NULL; ! int had_ctrl_v_cr = FALSE; if ((curbuf->b_ml.ml_flags & ML_EMPTY ) || oap->empty) return OK; /* nothing to do */ ! 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; ! } #ifdef FEAT_MBYTE if (has_mbyte) *************** *** 2207,2213 **** /* insert pre-spaces */ vim_memset(newp + bd.textcol, ' ', (size_t)bd.startspaces); /* insert replacement chars CHECK FOR ALLOCATED SPACE */ ! /* -1/-2 is used for entering CR literally. */ if (had_ctrl_v_cr || (c != '\r' && c != '\n')) { #ifdef FEAT_MBYTE --- 2215,2222 ---- /* insert pre-spaces */ vim_memset(newp + bd.textcol, ' ', (size_t)bd.startspaces); /* insert replacement chars CHECK FOR ALLOCATED SPACE */ ! /* REPLACE_CR_NCHAR/REPLACE_NL_NCHAR is used for entering CR ! * literally. */ if (had_ctrl_v_cr || (c != '\r' && c != '\n')) { #ifdef FEAT_MBYTE *************** *** 6370,6376 **** * |{bartype},{flags},{name},{type}, * {linecount},{width},{timestamp},"line1","line2" * flags: REG_PREVIOUS - register is y_previous ! * REG_EXEC - used for @@ */ if (y_previous == &y_regs[i]) flags |= REG_PREVIOUS; --- 6379,6385 ---- * |{bartype},{flags},{name},{type}, * {linecount},{width},{timestamp},"line1","line2" * flags: REG_PREVIOUS - register is y_previous ! * REG_EXEC - used for @@ */ if (y_previous == &y_regs[i]) flags |= REG_PREVIOUS; *** ../vim-8.0.1474/src/version.c 2018-02-06 22:02:38.980897880 +0100 --- src/version.c 2018-02-06 22:51:19.294751991 +0100 *************** *** 773,774 **** --- 773,776 ---- { /* Add new patch number below this line */ + /**/ + 1475, /**/ -- Apologies for taking up the bandwidth with the apology. Anything else I can apologise for ...... er no can't think of anything, sorry about that. Andy Hunt (Member of British Olympic Apology Squad) /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///