From f50808ed135ab973296bca515ae4029b321afe47 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 16 Apr 2022 18:52:17 +0100 Subject: [PATCH] patch 8.2.4763: using invalid pointer with "V:" in Ex mode Problem: Using invalid pointer with "V:" in Ex mode. Solution: Correctly handle the command being changed to "+". --- src/ex_docmd.c | 29 ++++++++++++++++++++++++----- src/testdir/test_ex_mode.vim | 13 +++++++++++++ src/version.c | 2 ++ 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/ex_docmd.c b/src/ex_docmd.c index 47a12fd2cf82a..58df97a9aa615 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -2783,7 +2783,9 @@ parse_command_modifiers( cmdmod_T *cmod, int skip_only) { + char_u *orig_cmd = eap->cmd; char_u *cmd_start = NULL; + int did_plus_cmd = FALSE; char_u *p; int starts_with_colon = FALSE; int vim9script = in_vim9script(); @@ -2819,6 +2821,7 @@ parse_command_modifiers( && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) { eap->cmd = (char_u *)"+"; + did_plus_cmd = TRUE; if (!skip_only) ex_pressedreturn = TRUE; } @@ -3105,13 +3108,29 @@ parse_command_modifiers( // Since the modifiers have been parsed put the colon on top of the // space: "'<,'>mod cmd" -> "mod:'<,'>cmd // Put eap->cmd after the colon. - mch_memmove(cmd_start - 5, cmd_start, eap->cmd - cmd_start); - eap->cmd -= 5; - mch_memmove(eap->cmd - 1, ":'<,'>", 6); + if (did_plus_cmd) + { + size_t len = STRLEN(cmd_start); + + // Special case: empty command may have been changed to "+": + // "'<,'>mod" -> "mod'<,'>+ + mch_memmove(orig_cmd, cmd_start, len); + STRCPY(orig_cmd + len, "'<,'>+"); + } + else + { + mch_memmove(cmd_start - 5, cmd_start, eap->cmd - cmd_start); + eap->cmd -= 5; + mch_memmove(eap->cmd - 1, ":'<,'>", 6); + } } else - // no modifiers, move the pointer back - eap->cmd -= 5; + // No modifiers, move the pointer back. + // Special case: empty command may have been changed to "+". + if (did_plus_cmd) + eap->cmd = (char_u *)"'<,'>+"; + else + eap->cmd = orig_cmd; } return OK; diff --git a/src/testdir/test_ex_mode.vim b/src/testdir/test_ex_mode.vim index 2642a16d25762..d981ced6b8f6d 100644 --- a/src/testdir/test_ex_mode.vim +++ b/src/testdir/test_ex_mode.vim @@ -250,5 +250,18 @@ func Test_ex_mode_large_indent() bwipe! endfunc +" This was accessing illegal memory when using "+" for eap->cmd. +func Test_empty_command_visual_mode() + let lines =<< trim END + r + 0norm0V: + :qall! + END + call writefile(lines, 'Xexmodescript') + call assert_equal(1, RunVim([], [], '-u NONE -e -s -S Xexmodescript')) + + call delete('Xexmodescript') +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c index 1cc0d906b1341..d6f2ef4314372 100644 --- a/src/version.c +++ b/src/version.c @@ -746,6 +746,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 4763, /**/ 4762, /**/