forked from aniani/vim
patch 9.0.0550: crash when closing a tabpage and buffer is NULL
Problem: Crash when closing a tabpage and buffer is NULL.
Solution: Adjust how autocommands are triggered when closing a window.
(closes #11198, closes #11197)
This commit is contained in:
@@ -6304,7 +6304,6 @@ tabpage_close_other(tabpage_T *tp, int forceit)
|
||||
{
|
||||
int done = 0;
|
||||
win_T *wp;
|
||||
int h = tabline_height();
|
||||
|
||||
// Limit to 1000 windows, autocommands may add a window while we close
|
||||
// one. OK, so I'm paranoid...
|
||||
@@ -6320,10 +6319,6 @@ tabpage_close_other(tabpage_T *tp, int forceit)
|
||||
}
|
||||
|
||||
apply_autocmds(EVENT_TABCLOSED, NULL, NULL, FALSE, curbuf);
|
||||
|
||||
redraw_tabline = TRUE;
|
||||
if (h != tabline_height())
|
||||
shell_new_rows();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -515,6 +515,26 @@ func Test_WinClosed_throws_with_tabs()
|
||||
augroup! test-WinClosed
|
||||
endfunc
|
||||
|
||||
" This used to trigger WinClosed twice for the same window, and the window's
|
||||
" buffer was NULL in the second autocommand.
|
||||
func Test_WinClosed_switch_tab()
|
||||
edit Xa
|
||||
split Xb
|
||||
split Xc
|
||||
tab split
|
||||
new
|
||||
augroup test-WinClosed
|
||||
autocmd WinClosed * tabprev | bwipe!
|
||||
augroup END
|
||||
close
|
||||
" Check that the tabline has been fully removed
|
||||
call assert_equal([1, 1], win_screenpos(0))
|
||||
|
||||
autocmd! test-WinClosed
|
||||
augroup! test-WinClosed
|
||||
%bwipe!
|
||||
endfunc
|
||||
|
||||
func s:AddAnAutocmd()
|
||||
augroup vimBarTest
|
||||
au BufReadCmd * echo 'hello'
|
||||
|
||||
@@ -699,6 +699,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
550,
|
||||
/**/
|
||||
549,
|
||||
/**/
|
||||
|
||||
20
src/window.c
20
src/window.c
@@ -2340,7 +2340,6 @@ close_windows(
|
||||
{
|
||||
win_T *wp;
|
||||
tabpage_T *tp, *nexttp;
|
||||
int h = tabline_height();
|
||||
int count = tabpage_index(NULL);
|
||||
|
||||
++RedrawingDisabled;
|
||||
@@ -2384,10 +2383,6 @@ close_windows(
|
||||
|
||||
if (count != tabpage_index(NULL))
|
||||
apply_autocmds(EVENT_TABCLOSED, NULL, NULL, FALSE, curbuf);
|
||||
|
||||
redraw_tabline = TRUE;
|
||||
if (h != tabline_height())
|
||||
shell_new_rows();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2446,18 +2441,11 @@ close_last_window_tabpage(
|
||||
* that below.
|
||||
*/
|
||||
goto_tabpage_tp(alt_tabpage(), FALSE, TRUE);
|
||||
redraw_tabline = TRUE;
|
||||
|
||||
// Safety check: Autocommands may have closed the window when jumping
|
||||
// to the other tab page.
|
||||
if (valid_tabpage(prev_curtab) && prev_curtab->tp_firstwin == win)
|
||||
{
|
||||
int h = tabline_height();
|
||||
|
||||
win_close_othertab(win, free_buf, prev_curtab);
|
||||
if (h != tabline_height())
|
||||
shell_new_rows();
|
||||
}
|
||||
#ifdef FEAT_JOB_CHANNEL
|
||||
entering_window(curwin);
|
||||
#endif
|
||||
@@ -2656,7 +2644,10 @@ win_close(win_T *win, int free_buf)
|
||||
&& win->w_buffer == NULL)
|
||||
{
|
||||
// Need to close the window anyway, since the buffer is NULL.
|
||||
// Don't trigger autocmds with a NULL buffer.
|
||||
block_autocmds();
|
||||
win_close_othertab(win, FALSE, prev_curtab);
|
||||
unblock_autocmds();
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
@@ -2907,6 +2898,8 @@ win_close_othertab(win_T *win, int free_buf, tabpage_T *tp)
|
||||
// When closing the last window in a tab page remove the tab page.
|
||||
if (tp->tp_firstwin == tp->tp_lastwin)
|
||||
{
|
||||
int h = tabline_height();
|
||||
|
||||
if (tp == first_tabpage)
|
||||
first_tabpage = tp->tp_next;
|
||||
else
|
||||
@@ -2922,6 +2915,9 @@ win_close_othertab(win_T *win, int free_buf, tabpage_T *tp)
|
||||
ptp->tp_next = tp->tp_next;
|
||||
}
|
||||
free_tp = TRUE;
|
||||
redraw_tabline = TRUE;
|
||||
if (h != tabline_height())
|
||||
shell_new_rows();
|
||||
}
|
||||
|
||||
// Free the memory used for the window.
|
||||
|
||||
Reference in New Issue
Block a user