0
0
mirror of https://github.com/vim/vim.git synced 2025-10-01 04:54:07 -04:00

patch 8.2.2207: illegal memory access if popup menu items are changed

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)
This commit is contained in:
Bram Moolenaar
2020-12-24 18:39:02 +01:00
parent 0261a1aeeb
commit 38455a9213
5 changed files with 83 additions and 4 deletions

View File

@@ -1458,10 +1458,21 @@ pum_show_popupmenu(vimmenu_T *menu)
return; return;
FOR_ALL_CHILD_MENUS(menu, mp) 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)) if (menu_is_separator(mp->dname))
array[idx++].pum_text = (char_u *)""; s = (char_u *)"";
else if (mp->modes & mp->enabled & mode) else if (mp->modes & mp->enabled & mode)
array[idx++].pum_text = mp->dname; s = mp->dname;
if (s != NULL)
{
s = vim_strsave(s);
if (s != NULL)
array[idx++].pum_text = s;
}
}
pum_array = array; pum_array = array;
pum_compute_size(); pum_compute_size();
@@ -1542,6 +1553,8 @@ pum_show_popupmenu(vimmenu_T *menu)
} }
} }
for (idx = 0; idx < pum_size; ++idx)
vim_free(array[idx].pum_text);
vim_free(array); vim_free(array);
pum_undisplay(); pum_undisplay();
# ifdef FEAT_BEVAL_TERM # ifdef FEAT_BEVAL_TERM

View File

@@ -0,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

View File

@@ -0,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|

View File

@@ -859,18 +859,30 @@ func Test_popup_command()
call assert_fails('popup Foo', 'E337:') call assert_fails('popup Foo', 'E337:')
unmenu Test.Foo 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 let lines =<< trim END
one two three four five one two three four five
and one two Xthree four five and one two Xthree four five
one more two three four five one more two three four five
END END
call writefile(lines, 'Xtest') call writefile(lines, 'Xtest')
let buf = RunVimInTerminal('Xtest', {}) let buf = RunVimInTerminal('-S XtimerScript Xtest', {})
call term_sendkeys(buf, ":source $VIMRUNTIME/menu.vim\<CR>") call term_sendkeys(buf, ":source $VIMRUNTIME/menu.vim\<CR>")
call term_sendkeys(buf, "/X\<CR>:popup PopUp\<CR>") call term_sendkeys(buf, "/X\<CR>:popup PopUp\<CR>")
call VerifyScreenDump(buf, 'Test_popup_command_01', {}) call VerifyScreenDump(buf, 'Test_popup_command_01', {})
" Select a word " go to the Paste entry in the menu
call term_sendkeys(buf, "jj") call term_sendkeys(buf, "jj")
call VerifyScreenDump(buf, 'Test_popup_command_02', {}) call VerifyScreenDump(buf, 'Test_popup_command_02', {})
@@ -879,8 +891,20 @@ func Test_popup_command()
call VerifyScreenDump(buf, 'Test_popup_command_03', {}) call VerifyScreenDump(buf, 'Test_popup_command_03', {})
call term_sendkeys(buf, "\<Esc>") 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 StopVimInTerminal(buf)
call delete('Xtest') call delete('Xtest')
call delete('XtimerScript')
endfunc endfunc
func Test_popup_complete_backwards() func Test_popup_complete_backwards()

View File

@@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
2207,
/**/ /**/
2206, 2206,
/**/ /**/