patch 9.1.1470: use-after-free with popup callback on error
Commit:
https://github.com/vim/vim/commit/8e83105798f07b78e638f5e651462d84bcd84f59
Author: Christian Brabandt <[email protected]>
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 <[email protected]>
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 [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/vim_dev/E1uRvuL-006Khd-2T%40256bit.org.