diff options
author | zeertzjq <zeertzjq@outlook.com> | 2022-09-22 18:08:37 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-09-22 18:08:37 +0100 |
commit | 62de54b48d6354d4622ec0b21ffa4cf3cf312505 (patch) | |
tree | 1aa6e8b6c74a1fa1514279b4389681c93fa8b413 /src | |
parent | 5800c798385b4a7eded9ea63cfd4f57d1499a673 (diff) | |
download | vim-git-62de54b48d6354d4622ec0b21ffa4cf3cf312505.tar.gz |
patch 9.0.0550: crash when closing a tabpage and buffer is NULLv9.0.0550
Problem: Crash when closing a tabpage and buffer is NULL.
Solution: Adjust how autocommands are triggered when closing a window.
(closes #11198, closes #11197)
Diffstat (limited to 'src')
-rw-r--r-- | src/ex_docmd.c | 5 | ||||
-rw-r--r-- | src/testdir/test_autocmd.vim | 20 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/window.c | 20 |
4 files changed, 30 insertions, 17 deletions
diff --git a/src/ex_docmd.c b/src/ex_docmd.c index a786ff0cc..912203917 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -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(); } /* diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim index 17bfd1b60..3c95f87a3 100644 --- a/src/testdir/test_autocmd.vim +++ b/src/testdir/test_autocmd.vim @@ -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' diff --git a/src/version.c b/src/version.c index e3a3a0e45..5d6951c87 100644 --- a/src/version.c +++ b/src/version.c @@ -700,6 +700,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 550, +/**/ 549, /**/ 548, diff --git a/src/window.c b/src/window.c index 3e1a3efd8..d73dfd9fd 100644 --- a/src/window.c +++ b/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. |