Skip to content

Commit

Permalink
patch 9.0.0550: crash when closing a tabpage and buffer is NULL
Browse files Browse the repository at this point in the history
Problem:    Crash when closing a tabpage and buffer is NULL.
Solution:   Adjust how autocommands are triggered when closing a window.
            (closes #11198, closes #11197)
  • Loading branch information
zeertzjq authored and brammool committed Sep 22, 2022
1 parent 5800c79 commit 62de54b
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 17 deletions.
5 changes: 0 additions & 5 deletions src/ex_docmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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...
Expand All @@ -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();
}

/*
Expand Down
20 changes: 20 additions & 0 deletions src/testdir/test_autocmd.vim
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
2 changes: 2 additions & 0 deletions src/version.c
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
550,
/**/
549,
/**/
Expand Down
20 changes: 8 additions & 12 deletions src/window.c
Original file line number Diff line number Diff line change
Expand Up @@ -2340,7 +2340,6 @@ close_windows(
{
win_T *wp;
tabpage_T *tp, *nexttp;
int h = tabline_height();
int count = tabpage_index(NULL);

++RedrawingDisabled;
Expand Down Expand Up @@ -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();
}

/*
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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
Expand All @@ -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.
Expand Down

0 comments on commit 62de54b

Please sign in to comment.