patch 9.1.1470: use-after-free with popup callback on error Commit: https://github.com/vim/vim/commit/8e83105798f07b78e638f5e651462d84bcd84f59 Author: Christian Brabandt <c...@256bit.org> Date: Wed Jun 18 18:33:31 2025 +0200
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 <c...@256bit.org> diff --git a/src/popupwin.c b/src/popupwin.c index 199ffaf8d..536e1b64c 100644 --- a/src/popupwin.c +++ b/src/popupwin.c @@ -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) diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim index 3c8e5d710..f01b74926 100644 --- a/src/testdir/test_popupwin.vim +++ b/src/testdir/test_popupwin.vim @@ -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 diff --git a/src/version.c b/src/version.c index 8b4f3e763..05e85ad4d 100644 --- a/src/version.c +++ b/src/version.c @@ -709,6 +709,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1470, /**/ 1469, /**/ -- -- 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 vim_dev+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/vim_dev/E1uRvuL-006Khd-2T%40256bit.org.