0
0
mirror of https://github.com/vim/vim.git synced 2025-07-26 11:04:33 -04:00

updated for version 7.4.320

Problem:    Possible crash when an BufLeave autocommand deletes the buffer.
Solution:   Check for the window pointer being valid.  Postpone freeing the
            window until autocommands are done. (Yasuhiro Matsumoto)
This commit is contained in:
Bram Moolenaar 2014-06-12 14:01:31 +02:00
parent 980e58f7b3
commit 3be8585661
5 changed files with 27 additions and 6 deletions

View File

@ -371,7 +371,11 @@ close_buffer(win, buf, action, abort_if_last)
unload_buf = TRUE; unload_buf = TRUE;
#endif #endif
if (win != NULL) if (win != NULL
#ifdef FEAT_WINDOWS
&& win_valid(win) /* in case autocommands closed the window */
#endif
)
{ {
/* Set b_last_cursor when closing the last window for the buffer. /* Set b_last_cursor when closing the last window for the buffer.
* Remember the last cursor position and window options of the buffer. * Remember the last cursor position and window options of the buffer.

View File

@ -9549,7 +9549,8 @@ apply_autocmds_group(event, fname, fname_io, force, group, buf, eap)
/* /*
* When stopping to execute autocommands, restore the search patterns and * When stopping to execute autocommands, restore the search patterns and
* the redo buffer. Free buffers in the au_pending_free_buf list. * the redo buffer. Free any buffers in the au_pending_free_buf list and
* free any windows in the au_pending_free_win list.
*/ */
if (!autocmd_busy) if (!autocmd_busy)
{ {
@ -9562,6 +9563,12 @@ apply_autocmds_group(event, fname, fname_io, force, group, buf, eap)
vim_free(au_pending_free_buf); vim_free(au_pending_free_buf);
au_pending_free_buf = b; au_pending_free_buf = b;
} }
while (au_pending_free_win != NULL)
{
win_T *w = au_pending_free_win->w_next;
vim_free(au_pending_free_win);
au_pending_free_win = w;
}
} }
/* /*

View File

@ -387,10 +387,12 @@ EXTERN int keep_filetype INIT(= FALSE); /* value for did_filetype when
* which one is preferred, au_new_curbuf is set to it */ * which one is preferred, au_new_curbuf is set to it */
EXTERN buf_T *au_new_curbuf INIT(= NULL); EXTERN buf_T *au_new_curbuf INIT(= NULL);
/* When deleting the buffer and autocmd_busy is TRUE, do not free the buffer /* When deleting a buffer/window and autocmd_busy is TRUE, do not free the
* but link it in the list starting with au_pending_free_buf, using b_next. * buffer/window. but link it in the list starting with
* Free the buffer when autocmd_busy is set to FALSE. */ * au_pending_free_buf/ap_pending_free_win, using b_next/w_next.
* Free the buffer/window when autocmd_busy is being set to FALSE. */
EXTERN buf_T *au_pending_free_buf INIT(= NULL); EXTERN buf_T *au_pending_free_buf INIT(= NULL);
EXTERN win_T *au_pending_free_win INIT(= NULL);
#endif #endif
#ifdef FEAT_MOUSE #ifdef FEAT_MOUSE

View File

@ -734,6 +734,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 */
/**/
320,
/**/ /**/
319, 319,
/**/ /**/

View File

@ -4597,7 +4597,13 @@ win_free(wp, tp)
if (wp != aucmd_win) if (wp != aucmd_win)
#endif #endif
win_remove(wp, tp); win_remove(wp, tp);
vim_free(wp); if (autocmd_busy)
{
wp->w_next = au_pending_free_win;
au_pending_free_win = wp;
}
else
vim_free(wp);
#ifdef FEAT_AUTOCMD #ifdef FEAT_AUTOCMD
unblock_autocmds(); unblock_autocmds();