patch 9.1.1773: Crash in BufLeave after BufUnload closes other windows
Problem: Crash in BufLeave/WinLeave/TabLeave when closing window after
BufUnload closes all other windows in the tab page.
Solution: Avoid duplicate BufLeave/WinLeave events. Trigger TabLeave
before removing the buffer (zeertzjq).
related: #14166
related: neovim/neovim#33603
closes: #18330
Signed-off-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
86e8e909f2
commit
0c70820015
14
src/window.c
14
src/window.c
@ -2605,10 +2605,12 @@ close_last_window_tabpage(
|
||||
* page and then close the window and the tab page. This avoids that
|
||||
* curwin and curtab are invalid while we are freeing memory, they may
|
||||
* be used in GUI events.
|
||||
* Don't trigger autocommands yet, they may use wrong values, so do
|
||||
* Don't trigger *Enter autocommands yet, they may use wrong values, so do
|
||||
* that below.
|
||||
* Do trigger *Leave autocommands, unless win->w_buffer is NULL, in which
|
||||
* case they have already been triggered.
|
||||
*/
|
||||
goto_tabpage_tp(alt_tabpage(), FALSE, TRUE);
|
||||
goto_tabpage_tp(alt_tabpage(), FALSE, win->w_buffer != NULL);
|
||||
|
||||
// Safety check: Autocommands may have closed the window when jumping
|
||||
// to the other tab page.
|
||||
@ -2906,6 +2908,7 @@ win_close(win_T *win, int free_buf)
|
||||
win_comp_pos();
|
||||
win_fix_scroll(FALSE);
|
||||
}
|
||||
|
||||
if (close_curwin)
|
||||
{
|
||||
// Pass WEE_ALLOW_PARSE_MESSAGES to decrement dont_parse_messages
|
||||
@ -2923,6 +2926,13 @@ win_close(win_T *win, int free_buf)
|
||||
apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
|
||||
}
|
||||
|
||||
if (ONE_WINDOW && curwin->w_locked && curbuf->b_locked_split
|
||||
&& first_tabpage->tp_next != NULL)
|
||||
// The new curwin is the last window in the current tab page, and it is
|
||||
// already being closed. Trigger TabLeave now, as after its buffer is
|
||||
// removed it's no longer safe to do that.
|
||||
apply_autocmds(EVENT_TABLEAVE, NULL, NULL, FALSE, curbuf);
|
||||
|
||||
--split_disallowed;
|
||||
#ifdef MESSAGE_QUEUE
|
||||
if (!did_decrement)
|
||||
|
||||
Reference in New Issue
Block a user