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.

Raspunde prin e-mail lui