Patch 8.2.2207
Problem:    Illegal memory access if popup menu items are changed while the
            menu is visible. (Tomáš Janoušek)
Solution:   Make a copy of the text. (closes #7537)
Files:      src/popupmenu.c, src/testdir/test_popup.vim,
            src/testdir/dumps/Test_popup_command_04.dump,
            src/testdir/dumps/Test_popup_command_05.dump


*** ../vim-8.2.2206/src/popupmenu.c     2020-12-09 18:13:40.713680179 +0100
--- src/popupmenu.c     2020-12-24 18:14:29.928532862 +0100
***************
*** 1458,1467 ****
        return;
  
      FOR_ALL_CHILD_MENUS(menu, mp)
        if (menu_is_separator(mp->dname))
!           array[idx++].pum_text = (char_u *)"";
        else if (mp->modes & mp->enabled & mode)
!           array[idx++].pum_text = mp->dname;
  
      pum_array = array;
      pum_compute_size();
--- 1458,1478 ----
        return;
  
      FOR_ALL_CHILD_MENUS(menu, mp)
+     {
+       char_u *s = NULL;
+ 
+       // Make a copy of the text, the menu may be redefined in a callback.
        if (menu_is_separator(mp->dname))
!           s = (char_u *)"";
        else if (mp->modes & mp->enabled & mode)
!           s = mp->dname;
!       if (s != NULL)
!       {
!           s = vim_strsave(s);
!           if (s != NULL)
!               array[idx++].pum_text = s;
!       }
!     }
  
      pum_array = array;
      pum_compute_size();
***************
*** 1542,1547 ****
--- 1553,1560 ----
        }
      }
  
+     for (idx = 0; idx < pum_size; ++idx)
+       vim_free(array[idx].pum_text);
      vim_free(array);
      pum_undisplay();
  # ifdef FEAT_BEVAL_TERM
*** ../vim-8.2.2206/src/testdir/test_popup.vim  2020-10-28 20:19:56.376057067 
+0100
--- src/testdir/test_popup.vim  2020-12-24 18:35:50.918262814 +0100
***************
*** 859,876 ****
    call assert_fails('popup Foo', 'E337:')
    unmenu Test.Foo
  
    let lines =<< trim END
        one two three four five
        and one two Xthree four five
        one more two three four five
    END
    call writefile(lines, 'Xtest')
!   let buf = RunVimInTerminal('Xtest', {})
    call term_sendkeys(buf, ":source $VIMRUNTIME/menu.vim\<CR>")
    call term_sendkeys(buf, "/X\<CR>:popup PopUp\<CR>")
    call VerifyScreenDump(buf, 'Test_popup_command_01', {})
  
!   " Select a word
    call term_sendkeys(buf, "jj")
    call VerifyScreenDump(buf, 'Test_popup_command_02', {})
  
--- 859,888 ----
    call assert_fails('popup Foo', 'E337:')
    unmenu Test.Foo
  
+   let script =<< trim END
+     func StartTimer()
+       call timer_start(100, {-> ChangeMenu()})
+     endfunc
+     func ChangeMenu()
+       nunmenu PopUp.&Paste
+       nnoremenu 1.40 PopUp.&Paste :echomsg "pasted"<CR>
+       echomsg 'changed'
+     endfunc
+   END
+   call writefile(script, 'XtimerScript')
+ 
    let lines =<< trim END
        one two three four five
        and one two Xthree four five
        one more two three four five
    END
    call writefile(lines, 'Xtest')
!   let buf = RunVimInTerminal('-S XtimerScript Xtest', {})
    call term_sendkeys(buf, ":source $VIMRUNTIME/menu.vim\<CR>")
    call term_sendkeys(buf, "/X\<CR>:popup PopUp\<CR>")
    call VerifyScreenDump(buf, 'Test_popup_command_01', {})
  
!   " go to the Paste entry in the menu
    call term_sendkeys(buf, "jj")
    call VerifyScreenDump(buf, 'Test_popup_command_02', {})
  
***************
*** 879,886 ****
--- 891,910 ----
    call VerifyScreenDump(buf, 'Test_popup_command_03', {})
  
    call term_sendkeys(buf, "\<Esc>")
+ 
+   " Set a timer to change a menu entry while it's displayed.  The text should
+   " not change but the command does.  Making the screendump also verifies that
+   " "changed" shows up, which means the timer triggered
+   call term_sendkeys(buf, "/X\<CR>:call StartTimer() | popup PopUp\<CR>")
+   call VerifyScreenDump(buf, 'Test_popup_command_04', {})
+ 
+   " Select the Paste entry, executes the changed menu item.
+   call term_sendkeys(buf, "jj\<CR>")
+   call VerifyScreenDump(buf, 'Test_popup_command_05', {})
+ 
    call StopVimInTerminal(buf)
    call delete('Xtest')
+   call delete('XtimerScript')
  endfunc
  
  func Test_popup_complete_backwards()
*** ../vim-8.2.2206/src/testdir/dumps/Test_popup_command_04.dump        
2020-12-24 18:37:59.089953436 +0100
--- src/testdir/dumps/Test_popup_command_04.dump        2020-12-24 
18:31:21.206844942 +0100
***************
*** 0 ****
--- 1,20 ----
+ |o+0&#ffffff0|n|e| |t|w|o| |t|h|r|e@1| |f|o|u|r| |f|i|v|e| @51
+ |a|n|d| |o|n|e| |t|w|o| |X|t|h|r|e@1| |f|o|u|r| |f|i|v|e| @46
+ |o|n|e| |m|o|r|e| |t|w| +0#0000001#ffd7ff255|U|n|d|o| @12| 
+0#0000000#ffffff0@45
+ |~+0#4040ff13&| @9| +0#0000001#ffd7ff255@17| +0#4040ff13#ffffff0@45
+ |~| @9| +0#0000001#ffd7ff255|P|a|s|t|e| @11| +0#4040ff13#ffffff0@45
+ |~| @9| +0#0000001#ffd7ff255@17| +0#4040ff13#ffffff0@45
+ |~| @9| +0#0000001#ffd7ff255|S|e|l|e|c|t| |W|o|r|d| @5| +0#4040ff13#ffffff0@45
+ |~| @9| +0#0000001#ffd7ff255|S|e|l|e|c|t| |S|e|n|t|e|n|c|e| @1| 
+0#4040ff13#ffffff0@45
+ |~| @9| +0#0000001#ffd7ff255|S|e|l|e|c|t| |P|a|r|a|g|r|a|p|h| | 
+0#4040ff13#ffffff0@45
+ |~| @9| +0#0000001#ffd7ff255|S|e|l|e|c|t| |L|i|n|e| @5| +0#4040ff13#ffffff0@45
+ |~| @9| +0#0000001#ffd7ff255|S|e|l|e|c|t| |B|l|o|c|k| @4| 
+0#4040ff13#ffffff0@45
+ |~| @9| +0#0000001#ffd7ff255|S|e|l|e|c|t| |A|l@1| @6| +0#4040ff13#ffffff0@45
+ |~| @73
+ |~| @73
+ |~| @73
+ |~| @73
+ |~| @73
+ |~| @73
+ |~| @73
+ |c+0#0000000&|h|a|n|g|e|d> @67
*** ../vim-8.2.2206/src/testdir/dumps/Test_popup_command_05.dump        
2020-12-24 18:37:59.093953428 +0100
--- src/testdir/dumps/Test_popup_command_05.dump        2020-12-24 
18:36:05.102229429 +0100
***************
*** 0 ****
--- 1,20 ----
+ |o+0&#ffffff0|n|e| |t|w|o| |t|h|r|e@1| |f|o|u|r| |f|i|v|e| @51
+ |a|n|d| |o|n|e| |t|w|o| >X|t|h|r|e@1| |f|o|u|r| |f|i|v|e| @46
+ |o|n|e| |m|o|r|e| |t|w|o| |t|h|r|e@1| |f|o|u|r| |f|i|v|e| @46
+ |~+0#4040ff13&| @73
+ |~| @73
+ |~| @73
+ |~| @73
+ |~| @73
+ |~| @73
+ |~| @73
+ |~| @73
+ |~| @73
+ |~| @73
+ |~| @73
+ |~| @73
+ |~| @73
+ |~| @73
+ |~| @73
+ |~| @73
+ |p+0#0000000&|a|s|t|e|d| @50|2|,|1|3| @9|A|l@1| 
*** ../vim-8.2.2206/src/version.c       2020-12-24 17:15:49.913113024 +0100
--- src/version.c       2020-12-24 18:38:06.245935686 +0100
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     2207,
  /**/

-- 
Bypasses are devices that allow some people to dash from point A to
point B very fast while other people dash from point B to point A very
fast.  People living at point C, being a point directly in between, are
often given to wonder what's so great about point A that so many people
from point B are so keen to get there and what's so great about point B
that so many people from point A are so keen to get there.  They often
wish that people would just once and for all work out where the hell
they wanted to be.
                -- Douglas Adams, "The Hitchhiker's Guide to the Galaxy"

 /// Bram Moolenaar -- [email protected] -- 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    ///

-- 
-- 
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/202012241740.0BOHe16J3263828%40masaka.moolenaar.net.

Raspunde prin e-mail lui