Patch 9.0.0877
Problem:    Using freed memory with :comclear while listing commands.
Solution:   Bail out when the command list has changed. (closes #11440)
Files:      src/usercmd.c, src/errors.h, src/testdir/test_usercommands.vim


*** ../vim-9.0.0876/src/usercmd.c       2022-11-02 13:30:37.542314565 +0000
--- src/usercmd.c       2022-11-13 23:17:28.059292943 +0000
***************
*** 31,36 ****
--- 31,39 ----
  // List of all user commands.
  static garray_T ucmds = {0, 0, sizeof(ucmd_T), 4, NULL};
  
+ // When non-zero it is not allowed to add or remove user commands
+ static int ucmd_locked = 0;
+ 
  #define USER_CMD(i) (&((ucmd_T *)(ucmds.ga_data))[i])
  #define USER_CMD_GA(gap, i) (&((ucmd_T *)((gap)->ga_data))[i])
  
***************
*** 499,504 ****
--- 502,510 ----
      long      a;
      garray_T  *gap;
  
+     // don't allow for adding or removing user commands here
+     ++ucmd_locked;
+ 
      // In cmdwin, the alternative buffer should be used.
      gap = &prevwin_curwin()->w_buffer->b_ucmds;
      for (;;)
***************
*** 656,661 ****
--- 662,669 ----
  
      if (!found)
        msg(_("No user-defined commands found"));
+ 
+     --ucmd_locked;
  }
  
      char *
***************
*** 1223,1228 ****
--- 1231,1251 ----
  }
  
  /*
+  * If ucmd_locked is set give an error and return TRUE.
+  * Otherwise return FALSE.
+  */
+     static int
+ is_ucmd_locked(void)
+ {
+     if (ucmd_locked > 0)
+     {
+       emsg(_(e_cannot_change_user_commands_while_listing));
+       return TRUE;
+     }
+     return FALSE;
+ }
+ 
+ /*
   * Clear all user commands for "gap".
   */
      void
***************
*** 1231,1236 ****
--- 1254,1262 ----
      int               i;
      ucmd_T    *cmd;
  
+     if (is_ucmd_locked())
+       return;
+ 
      for (i = 0; i < gap->ga_len; ++i)
      {
        cmd = USER_CMD_GA(gap, i);
***************
*** 1285,1290 ****
--- 1311,1319 ----
        return;
      }
  
+     if (is_ucmd_locked())
+       return;
+ 
      vim_free(cmd->uc_name);
      vim_free(cmd->uc_rep);
  # if defined(FEAT_EVAL)
*** ../vim-9.0.0876/src/errors.h        2022-11-13 21:09:58.594211220 +0000
--- src/errors.h        2022-11-13 23:13:44.435120122 +0000
***************
*** 3339,3341 ****
--- 3339,3343 ----
  EXTERN char e_cannot_change_menus_while_listing[]
        INIT(= N_("E1310: Cannot change menus while listing"));
  #endif
+ EXTERN char e_cannot_change_user_commands_while_listing[]
+       INIT(= N_("E1311: Cannot change user commands while listing"));
*** ../vim-9.0.0876/src/testdir/test_usercommands.vim   2022-10-18 
13:11:18.466896436 +0100
--- src/testdir/test_usercommands.vim   2022-11-13 23:28:24.207745078 +0000
***************
*** 2,7 ****
--- 2,10 ----
  
  import './vim9.vim' as v9
  
+ source check.vim
+ source screendump.vim
+ 
  " Test for <mods> in user defined commands
  function Test_cmdmods()
    let g:mods = ''
***************
*** 373,378 ****
--- 376,389 ----
    call feedkeys(":com MyCmd chist\<Tab>\<C-B>\"\<CR>", 'tx')
    call assert_equal("\"com MyCmd chistory", @:)
  
+   " delete the Check commands to avoid them showing up
+   call feedkeys(":com Check\<C-A>\<C-B>\"\<CR>", 'tx')
+   let cmds = substitute(@:, '"com ', '', '')->split()
+   for cmd in cmds
+     exe 'delcommand ' .. cmd
+   endfor
+   delcommand MissingFeature
+ 
    command! DoCmd1 :
    command! DoCmd2 :
    call feedkeys(":com \<C-A>\<C-B>\"\<CR>", 'tx')
***************
*** 716,721 ****
--- 727,733 ----
           echo 'hello'
    END
    call v9.CheckScriptFailure(lines, 'E1026:')
+   delcommand DoesNotEnd
  
    let lines =<< trim END
        command HelloThere {
***************
*** 754,759 ****
--- 766,772 ----
        BadCommand
    END
    call v9.CheckScriptFailure(lines, 'E1128:')
+   delcommand BadCommand
  endfunc
  
  func Test_delcommand_buffer()
***************
*** 817,823 ****
    call DefCmd('Command')
  
    let name = 'Command'
!   while len(name) < 30
      exe 'delcommand ' .. name
      let name ..= 'x'
    endwhile
--- 830,836 ----
    call DefCmd('Command')
  
    let name = 'Command'
!   while len(name) <= 30
      exe 'delcommand ' .. name
      let name ..= 'x'
    endwhile
***************
*** 882,886 ****
--- 895,924 ----
    delcommand Rename
  endfunc
  
+ func Test_comclear_while_listing()
+   call CheckRunVimInTerminal()
+ 
+   let lines =<< trim END
+       set nocompatible
+       comclear
+       for i in range(1, 999)
+         exe 'command ' .. 'Foo' .. i .. ' bar'
+       endfor
+       au CmdlineLeave : call timer_start(0, {-> execute('comclear')})
+   END
+   call writefile(lines, 'Xcommandclear', 'D')
+   let buf = RunVimInTerminal('-S Xcommandclear', {'rows': 10})
+ 
+   " this was using freed memory
+   call term_sendkeys(buf, ":command\<CR>")
+   call TermWait(buf, 50)
+   call term_sendkeys(buf, "j")
+   call TermWait(buf, 50)
+   call term_sendkeys(buf, "G")
+   call term_sendkeys(buf, "\<CR>")
+ 
+   call StopVimInTerminal(buf)
+ endfunc
+ 
  
  " vim: shiftwidth=2 sts=2 expandtab
*** ../vim-9.0.0876/src/version.c       2022-11-13 22:38:06.045883322 +0000
--- src/version.c       2022-11-13 22:56:32.170538849 +0000
***************
*** 697,698 ****
--- 697,700 ----
  {   /* Add new patch number below this line */
+ /**/
+     877,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
57. You begin to wonder how on earth your service provider is allowed to call
    200 hours per month "unlimited."

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20221113233113.0BC4F1C0473%40moolenaar.net.

Raspunde prin e-mail lui