Skip to content

Commit 11fbc28

Browse files
committed
patch 7.4.2309
Problem: Crash when doing tabnext in a BufUnload autocmd. (Dominique Pelle) Solution: When detecting that the tab page changed, don't just abort but delete the window where w_buffer is NULL.
1 parent 44f660c commit 11fbc28

3 files changed

Lines changed: 35 additions & 7 deletions

File tree

src/testdir/test_tabpage.vim

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,4 +218,18 @@ function Test_tabpage_with_tab_modifier()
218218
bw!
219219
endfunction
220220

221+
func Test_tabnext_on_buf_unload()
222+
" This once caused a crash
223+
new
224+
tabedit
225+
tabfirst
226+
au BufUnload <buffer> tabnext
227+
q
228+
229+
while tabpagenr('$') > 1
230+
quit
231+
endwhile
232+
endfunc
233+
234+
221235
" vim: shiftwidth=2 sts=2 expandtab

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,8 @@ static char *(features[]) =
763763

764764
static int included_patches[] =
765765
{ /* Add new patch number below this line */
766+
/**/
767+
2309,
766768
/**/
767769
2308,
768770
/**/

src/window.c

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2379,7 +2379,7 @@ win_close(win_T *win, int free_buf)
23792379
#endif
23802380
close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, TRUE);
23812381
#ifdef FEAT_AUTOCMD
2382-
if (win_valid(win))
2382+
if (win_valid_any_tab(win))
23832383
win->w_closing = FALSE;
23842384
#endif
23852385
/* Make sure curbuf is valid. It can become invalid if 'bufhidden' is
@@ -2399,9 +2399,18 @@ win_close(win_T *win, int free_buf)
23992399
getout(0);
24002400
}
24012401

2402-
/* Autocommands may have closed the window already, or closed the only
2403-
* other window or moved to another tab page. */
2404-
else if (!win_valid(win) || last_window() || curtab != prev_curtab
2402+
/* Autocommands may have moved to another tab page. */
2403+
if (curtab != prev_curtab && win_valid_any_tab(win)
2404+
&& win->w_buffer == NULL)
2405+
{
2406+
/* Need to close the window anyway, since the buffer is NULL. */
2407+
win_close_othertab(win, FALSE, prev_curtab);
2408+
return FAIL;
2409+
}
2410+
2411+
/* Autocommands may have closed the window already or closed the only
2412+
* other window. */
2413+
if (!win_valid(win) || last_window()
24052414
|| close_last_window_tabpage(win, free_buf, prev_curtab))
24062415
return FAIL;
24072416

@@ -2492,12 +2501,15 @@ win_close_othertab(win_T *win, int free_buf, tabpage_T *tp)
24922501
int free_tp = FALSE;
24932502

24942503
#ifdef FEAT_AUTOCMD
2495-
if (win->w_closing || win->w_buffer->b_closing)
2504+
/* Get here with win->w_buffer == NULL when win_close() detects the tab
2505+
* page changed. */
2506+
if (win->w_closing || (win->w_buffer != NULL && win->w_buffer->b_closing))
24962507
return; /* window is already being closed */
24972508
#endif
24982509

2499-
/* Close the link to the buffer. */
2500-
close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, FALSE);
2510+
if (win->w_buffer != NULL)
2511+
/* Close the link to the buffer. */
2512+
close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, FALSE);
25012513

25022514
/* Careful: Autocommands may have closed the tab page or made it the
25032515
* current tab page. */

0 commit comments

Comments
 (0)