comparison 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
comparison
equal deleted inserted replaced
11198:011eb80f6e66 11199:e08ead1d269f
2105 } 2105 }
2106 } 2106 }
2107 } 2107 }
2108 2108
2109 /* 2109 /*
2110 * close all windows for buffer 'buf' 2110 * Close all windows for buffer "buf".
2111 */ 2111 */
2112 void 2112 void
2113 close_windows( 2113 close_windows(
2114 buf_T *buf, 2114 buf_T *buf,
2115 int keep_curwin) /* don't close "curwin" */ 2115 int keep_curwin) /* don't close "curwin" */
2129 #ifdef FEAT_AUTOCMD 2129 #ifdef FEAT_AUTOCMD
2130 && !(wp->w_closing || wp->w_buffer->b_locked > 0) 2130 && !(wp->w_closing || wp->w_buffer->b_locked > 0)
2131 #endif 2131 #endif
2132 ) 2132 )
2133 { 2133 {
2134 win_close(wp, FALSE); 2134 if (win_close(wp, FALSE) == FAIL)
2135 /* If closing the window fails give up, to avoid looping
2136 * forever. */
2137 break;
2135 2138
2136 /* Start all over, autocommands may change the window layout. */ 2139 /* Start all over, autocommands may change the window layout. */
2137 wp = firstwin; 2140 wp = firstwin;
2138 } 2141 }
2139 else 2142 else
3754 3757
3755 FOR_ALL_TABPAGES(tp) 3758 FOR_ALL_TABPAGES(tp)
3756 if (tp == tpc) 3759 if (tp == tpc)
3757 return TRUE; 3760 return TRUE;
3758 return FALSE; 3761 return FALSE;
3762 }
3763
3764 /*
3765 * Return TRUE when "tpc" points to a valid tab page and at least one window is
3766 * valid.
3767 */
3768 int
3769 valid_tabpage_win(tabpage_T *tpc)
3770 {
3771 tabpage_T *tp;
3772 win_T *wp;
3773
3774 FOR_ALL_TABPAGES(tp)
3775 {
3776 if (tp == tpc)
3777 {
3778 FOR_ALL_WINDOWS_IN_TAB(tp, wp)
3779 {
3780 if (win_valid_any_tab(wp))
3781 return TRUE;
3782 }
3783 return FALSE;
3784 }
3785 }
3786 /* shouldn't happen */
3787 return FALSE;
3788 }
3789
3790 /*
3791 * Close tabpage "tab", assuming it has no windows in it.
3792 * There must be another tabpage or this will crash.
3793 */
3794 void
3795 close_tabpage(tabpage_T *tab)
3796 {
3797 tabpage_T *ptp;
3798
3799 if (tab == first_tabpage)
3800 {
3801 first_tabpage = tab->tp_next;
3802 ptp = first_tabpage;
3803 }
3804 else
3805 {
3806 for (ptp = first_tabpage; ptp != NULL && ptp->tp_next != tab;
3807 ptp = ptp->tp_next)
3808 ;
3809 ptp->tp_next = tab->tp_next;
3810 }
3811
3812 goto_tabpage_tp(ptp, FALSE, FALSE);
3813 free_tabpage(tab);
3759 } 3814 }
3760 3815
3761 /* 3816 /*
3762 * Find tab page "n" (first one is 1). Returns NULL when not found. 3817 * Find tab page "n" (first one is 1). Returns NULL when not found.
3763 */ 3818 */