Skip to content

Commit

Permalink
patch 8.2.4631: crash when switching window in BufWipeout autocommand
Browse files Browse the repository at this point in the history
Problem:    Crash when switching window in BufWipeout autocommand.
Solution:   Put any buffer in the window to avoid it being NULL.
            (closes #10024)
  • Loading branch information
brammool committed Mar 26, 2022
1 parent bf269ed commit 347538f
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 35 deletions.
4 changes: 4 additions & 0 deletions src/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,10 @@ close_buffer(
*/
if (wipe_buf)
{
// Do not wipe out the buffer if it is used in a window.
if (buf->b_nwindows > 0)
return FALSE;

if (action == DOBUF_WIPE_REUSE)
{
// we can re-use this buffer number, store it
Expand Down
17 changes: 17 additions & 0 deletions src/testdir/test_autocmd.vim
Original file line number Diff line number Diff line change
Expand Up @@ -2990,4 +2990,21 @@ func Test_closing_autocmd_window()
bwipe Xb.txt
endfunc

func Test_bufwipeout_changes_window()
" This should not crash, but we don't have any expectations about what
" happens, changing window in BufWipeout has unpredictable results.
tabedit
let g:window_id = win_getid()
topleft new
setlocal bufhidden=wipe
autocmd BufWipeout <buffer> call win_gotoid(g:window_id)
tabprevious
+tabclose

unlet g:window_id
au! BufWipeout
%bwipe!
endfunc


" vim: shiftwidth=2 sts=2 expandtab
2 changes: 2 additions & 0 deletions src/version.c
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
4631,
/**/
4630,
/**/
Expand Down
80 changes: 45 additions & 35 deletions src/window.c
Original file line number Diff line number Diff line change
Expand Up @@ -2285,6 +2285,41 @@ entering_window(win_T *win)
}
#endif

static void
win_init_empty(win_T *wp)
{
redraw_win_later(wp, NOT_VALID);
wp->w_lines_valid = 0;
wp->w_cursor.lnum = 1;
wp->w_curswant = wp->w_cursor.col = 0;
wp->w_cursor.coladd = 0;
wp->w_pcmark.lnum = 1; // pcmark not cleared but set to line 1
wp->w_pcmark.col = 0;
wp->w_prev_pcmark.lnum = 0;
wp->w_prev_pcmark.col = 0;
wp->w_topline = 1;
#ifdef FEAT_DIFF
wp->w_topfill = 0;
#endif
wp->w_botline = 2;
#if defined(FEAT_SYN_HL) || defined(FEAT_SPELL)
wp->w_s = &wp->w_buffer->b_s;
#endif
#ifdef FEAT_TERMINAL
term_reset_wincolor(wp);
#endif
}

/*
* Init the current window "curwin".
* Called when a new file is being edited.
*/
void
curwin_init(void)
{
win_init_empty(curwin);
}

/*
* Close all windows for buffer "buf".
*/
Expand Down Expand Up @@ -2786,7 +2821,17 @@ win_close_othertab(win_T *win, int free_buf, tabpage_T *tp)
for (ptp = first_tabpage; ptp != NULL && ptp != tp; ptp = ptp->tp_next)
;
if (ptp == NULL || tp == curtab)
{
// If the buffer was removed from the window we have to give it any
// buffer.
if (win_valid_any_tab(win) && win->w_buffer == NULL)
{
win->w_buffer = firstbuf;
++firstbuf->b_nwindows;
win_init_empty(win);
}
return;
}

// Autocommands may have closed the window already.
for (wp = tp->tp_firstwin; wp != NULL && wp != win; wp = wp->w_next)
Expand Down Expand Up @@ -3685,41 +3730,6 @@ close_others(
emsg(_(e_other_window_contains_changes));
}

static void
win_init_empty(win_T *wp)
{
redraw_win_later(wp, NOT_VALID);
wp->w_lines_valid = 0;
wp->w_cursor.lnum = 1;
wp->w_curswant = wp->w_cursor.col = 0;
wp->w_cursor.coladd = 0;
wp->w_pcmark.lnum = 1; // pcmark not cleared but set to line 1
wp->w_pcmark.col = 0;
wp->w_prev_pcmark.lnum = 0;
wp->w_prev_pcmark.col = 0;
wp->w_topline = 1;
#ifdef FEAT_DIFF
wp->w_topfill = 0;
#endif
wp->w_botline = 2;
#if defined(FEAT_SYN_HL) || defined(FEAT_SPELL)
wp->w_s = &wp->w_buffer->b_s;
#endif
#ifdef FEAT_TERMINAL
term_reset_wincolor(wp);
#endif
}

/*
* Init the current window "curwin".
* Called when a new file is being edited.
*/
void
curwin_init(void)
{
win_init_empty(curwin);
}

/*
* Allocate the first window and put an empty buffer in it.
* Called from main().
Expand Down

0 comments on commit 347538f

Please sign in to comment.