]> granicus.if.org Git - vim/commitdiff
patch 8.2.4763: using invalid pointer with "V:" in Ex mode v8.2.4763
authorBram Moolenaar <Bram@vim.org>
Sat, 16 Apr 2022 17:52:17 +0000 (18:52 +0100)
committerBram Moolenaar <Bram@vim.org>
Sat, 16 Apr 2022 17:52:17 +0000 (18:52 +0100)
Problem:    Using invalid pointer with "V:" in Ex mode.
Solution:   Correctly handle the command being changed to "+".

src/ex_docmd.c
src/testdir/test_ex_mode.vim
src/version.c

index 47a12fd2cf82a5d61bb966380e079bf37e9a8113..58df97a9aa61503a7b4c4aa180a5bbbb7cb4f282 100644 (file)
@@ -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;
index 2642a16d257624a97d022150909334fa393931f3..d981ced6b8f6d92c9e024ef84aaf9c8bc56e1208 100644 (file)
@@ -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:\e
+      :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
index 1cc0d906b13414d0bad8019923cc740113bad5f7..d6f2ef4314372734f7c0f46d3696e07c0e4b198e 100644 (file)
@@ -746,6 +746,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4763,
 /**/
     4762,
 /**/