Mercurial > vim
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 */ |