Mercurial > vim
diff src/window.c @ 11199:e08ead1d269f v8.0.0486
patch 8.0.0486: crash and endless loop when closing windows in autocmd
commit https://github.com/vim/vim/commit/8c752bd6c4af54c0b7bac35a39acc2bf16015f85
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Mar 19 17:09:56 2017 +0100
patch 8.0.0486: crash and endless loop when closing windows in autocmd
Problem: Crash and endless loop when closing windows in a SessionLoadPost
autocommand.
Solution: Check for valid tabpage. (partly neovim #6308)
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sun, 19 Mar 2017 17:15:05 +0100 |
parents | 75ccc8a15a51 |
children | e6140f3d2be7 |
line wrap: on
line diff
--- a/src/window.c +++ b/src/window.c @@ -2107,7 +2107,7 @@ win_equal_rec( } /* - * close all windows for buffer 'buf' + * Close all windows for buffer "buf". */ void close_windows( @@ -2131,7 +2131,10 @@ close_windows( #endif ) { - win_close(wp, FALSE); + if (win_close(wp, FALSE) == FAIL) + /* If closing the window fails give up, to avoid looping + * forever. */ + break; /* Start all over, autocommands may change the window layout. */ wp = firstwin; @@ -3759,6 +3762,58 @@ valid_tabpage(tabpage_T *tpc) } /* + * Return TRUE when "tpc" points to a valid tab page and at least one window is + * valid. + */ + int +valid_tabpage_win(tabpage_T *tpc) +{ + tabpage_T *tp; + win_T *wp; + + FOR_ALL_TABPAGES(tp) + { + if (tp == tpc) + { + FOR_ALL_WINDOWS_IN_TAB(tp, wp) + { + if (win_valid_any_tab(wp)) + return TRUE; + } + return FALSE; + } + } + /* shouldn't happen */ + return FALSE; +} + +/* + * Close tabpage "tab", assuming it has no windows in it. + * There must be another tabpage or this will crash. + */ + void +close_tabpage(tabpage_T *tab) +{ + tabpage_T *ptp; + + if (tab == first_tabpage) + { + first_tabpage = tab->tp_next; + ptp = first_tabpage; + } + else + { + for (ptp = first_tabpage; ptp != NULL && ptp->tp_next != tab; + ptp = ptp->tp_next) + ; + ptp->tp_next = tab->tp_next; + } + + goto_tabpage_tp(ptp, FALSE, FALSE); + free_tabpage(tab); +} + +/* * Find tab page "n" (first one is 1). Returns NULL when not found. */ tabpage_T *