0
0
mirror of https://github.com/vim/vim.git synced 2025-07-24 10:45:12 -04:00

patch 9.1.1470: use-after-free with popup callback on error

Problem:  use-after-free with popup callback on error
          (Brian Carbone, lifepillar)
Solution: check if the popup window is valid before accessing it

fixes: #17558
closes: #17565

Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Christian Brabandt 2025-06-18 18:33:31 +02:00
parent 9d065a4862
commit 8e83105798
No known key found for this signature in database
GPG Key ID: F3F92DA383FDDE09
3 changed files with 53 additions and 1 deletions

View File

@ -2421,11 +2421,17 @@ back_to_prevwin(win_T *wp)
/*
* Close popup "wp" and invoke any close callback for it.
* Careful: callback function might have freed the popup window already
*/
static void
popup_close_and_callback(win_T *wp, typval_T *arg)
{
int id = wp->w_id;
int id;
if (!win_valid(wp))
return;
id = wp->w_id;
#ifdef FEAT_TERMINAL
if (wp == curwin && curbuf->b_term != NULL)

View File

@ -1121,6 +1121,7 @@ func Test_win_execute_not_allowed()
call assert_fails('call win_execute(winid, "wincmd t")', 'E994:')
call assert_fails('call win_execute(winid, "wincmd b")', 'E994:')
call popup_clear()
bw filename
endfunc
func Test_popup_with_wrap()
@ -4449,4 +4450,47 @@ func Test_popupwin_clears_cmdline_on_hide()
call StopVimInTerminal(buf)
endfunc
func Test_popupwin_callback_closes_popupwin()
" Test that the command line is properly cleared for overlong
" popup windows and using popup_hide()
CheckRunVimInTerminal
let lines =<< trim END
vim9script
def Filter(winid: number, keyCode: string): bool
popup_close(winid)
colorscheme missing
return true
enddef
def Popup(): number
return popup_create('', {
border: [2, 2, 2, 2],
close: 'button',
filter: Filter,
})
enddef
nnoremap gs <scriptcmd>Popup()<cr>
END
call writefile(lines, 'XtestPopup1_win', 'D')
let buf = RunVimInTerminal('-S XtestPopup1_win', #{rows: 10})
let i = 0
while i <= 10
call term_sendkeys(buf, "gs")
call term_wait(buf)
" this was causing a use-after-free
call term_sendkeys(buf, "q")
" clear the hit-enter prompt
call term_sendkeys(buf, "\<cr>")
call term_wait(buf)
let i += 1
endwhile
call term_sendkeys(buf, ":echo 'Done'\<cr>")
call WaitForAssert({-> assert_match('Done', term_getline(buf, 10))})
" clean up
call StopVimInTerminal(buf)
endfunc
" vim: shiftwidth=2 sts=2

View File

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