0
0
mirror of https://github.com/vim/vim.git synced 2025-09-24 03:44:06 -04:00

patch 8.1.2197: ExitPre autocommand may cause accessing freed memory

Problem:    ExitPre autocommand may cause accessing freed memory.
Solution:   Check the window pointer is still valid. (closes #5093)
This commit is contained in:
Bram Moolenaar
2019-10-20 22:27:10 +02:00
parent d53ebfc624
commit 34ba06b6e6
3 changed files with 31 additions and 6 deletions

View File

@@ -4817,9 +4817,9 @@ before_quit_autocmds(win_T *wp, int quit_all, int forceit)
{ {
apply_autocmds(EVENT_QUITPRE, NULL, NULL, FALSE, wp->w_buffer); apply_autocmds(EVENT_QUITPRE, NULL, NULL, FALSE, wp->w_buffer);
/* Bail out when autocommands closed the window. // Bail out when autocommands closed the window.
* Refuse to quit when the buffer in the last window is being closed (can // Refuse to quit when the buffer in the last window is being closed (can
* only happen in autocommands). */ // only happen in autocommands).
if (!win_valid(wp) if (!win_valid(wp)
|| curbuf_locked() || curbuf_locked()
|| (wp->w_buffer->b_nwindows == 1 && wp->w_buffer->b_locked > 0)) || (wp->w_buffer->b_nwindows == 1 && wp->w_buffer->b_locked > 0))
@@ -4828,9 +4828,10 @@ before_quit_autocmds(win_T *wp, int quit_all, int forceit)
if (quit_all || (check_more(FALSE, forceit) == OK && only_one_window())) if (quit_all || (check_more(FALSE, forceit) == OK && only_one_window()))
{ {
apply_autocmds(EVENT_EXITPRE, NULL, NULL, FALSE, curbuf); apply_autocmds(EVENT_EXITPRE, NULL, NULL, FALSE, curbuf);
/* Refuse to quit when locked or when the buffer in the last window is // Refuse to quit when locked or when the window was closed or the
* being closed (can only happen in autocommands). */ // buffer in the last window is being closed (can only happen in
if (curbuf_locked() // autocommands).
if (!win_valid(wp) || curbuf_locked()
|| (curbuf->b_nwindows == 1 && curbuf->b_locked > 0)) || (curbuf->b_nwindows == 1 && curbuf->b_locked > 0))
return TRUE; return TRUE;
} }

View File

@@ -40,6 +40,7 @@ func Test_exiting()
endif endif
call delete('Xtestout') call delete('Xtestout')
" ExitPre autocommand splits the window, so that it's no longer the last one.
let after =<< trim [CODE] let after =<< trim [CODE]
au QuitPre * call writefile(["QuitPre"], "Xtestout", "a") au QuitPre * call writefile(["QuitPre"], "Xtestout", "a")
au ExitPre * call writefile(["ExitPre"], "Xtestout", "a") au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")
@@ -58,4 +59,25 @@ func Test_exiting()
\ readfile('Xtestout')) \ readfile('Xtestout'))
endif endif
call delete('Xtestout') call delete('Xtestout')
" ExitPre autocommand splits and closes the window, so that there is still
" one window but it's a different one.
let after =<< trim [CODE]
au QuitPre * call writefile(["QuitPre"], "Xtestout", "a")
au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")
augroup nasty
au ExitPre * split | only
augroup END
quit
augroup nasty
au! ExitPre
augroup END
quit
[CODE]
if RunVim([], after, '')
call assert_equal(['QuitPre', 'ExitPre', 'QuitPre', 'ExitPre'],
\ readfile('Xtestout'))
endif
call delete('Xtestout')
endfunc endfunc

View File

@@ -741,6 +741,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 */
/**/
2197,
/**/ /**/
2196, 2196,
/**/ /**/