diff options
author | Bram Moolenaar <Bram@vim.org> | 2022-04-16 18:52:17 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-04-16 18:52:17 +0100 |
commit | f50808ed135ab973296bca515ae4029b321afe47 (patch) | |
tree | f932fa6eb924a1b1148b254f622dc3b3f0f2cb97 /src | |
parent | ca7e86c23789eb0ed8f6400f25ea9e0e1036f9fc (diff) | |
download | vim-git-f50808ed135ab973296bca515ae4029b321afe47.tar.gz |
patch 8.2.4763: using invalid pointer with "V:" in Ex modev8.2.4763
Problem: Using invalid pointer with "V:" in Ex mode.
Solution: Correctly handle the command being changed to "+".
Diffstat (limited to 'src')
-rw-r--r-- | src/ex_docmd.c | 29 | ||||
-rw-r--r-- | src/testdir/test_ex_mode.vim | 13 | ||||
-rw-r--r-- | src/version.c | 2 |
3 files changed, 39 insertions, 5 deletions
diff --git a/src/ex_docmd.c b/src/ex_docmd.c index 47a12fd2c..58df97a9a 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 2642a16d2..d981ced6b 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<sfile> + 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 1cc0d906b..d6f2ef431 100644 --- a/src/version.c +++ b/src/version.c @@ -747,6 +747,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4763, +/**/ 4762, /**/ 4761, |