comparison src/popupwin.c @ 19629:804322d6c6ba v8.2.0371

patch 8.2.0371: crash with combination of terminal popup and autocmd Commit: https://github.com/vim/vim/commit/cee52204ca030ce7814844e4dab8b4ed897ba3cc Author: Bram Moolenaar <Bram@vim.org> Date: Wed Mar 11 14:19:58 2020 +0100 patch 8.2.0371: crash with combination of terminal popup and autocmd Problem: Crash with combination of terminal popup and autocmd. Solution: Disallow closing a popup that is the current window. Add a check that the current buffer is valid. (closes #5754)
author Bram Moolenaar <Bram@vim.org>
date Wed, 11 Mar 2020 14:30:04 +0100
parents 5ad7a406647a
children 8de319d1b82c
comparison
equal deleted inserted replaced
19628:a9fb9a329b79 19629:804322d6c6ba
2133 owp = owp->w_next) 2133 owp = owp->w_next)
2134 if (owp != curwin && owp->w_buffer->b_term != NULL) 2134 if (owp != curwin && owp->w_buffer->b_term != NULL)
2135 break; 2135 break;
2136 if (owp != NULL) 2136 if (owp != NULL)
2137 win_enter(owp, FALSE); 2137 win_enter(owp, FALSE);
2138 else if (win_valid(prevwin)) 2138 else if (win_valid(prevwin) && wp != prevwin)
2139 win_enter(prevwin, FALSE); 2139 win_enter(prevwin, FALSE);
2140 else 2140 else
2141 win_enter(firstwin, FALSE); 2141 win_enter(firstwin, FALSE);
2142 } 2142 }
2143 } 2143 }
2145 2145
2146 // Just in case a check higher up is missing. 2146 // Just in case a check higher up is missing.
2147 if (wp == curwin && ERROR_IF_POPUP_WINDOW) 2147 if (wp == curwin && ERROR_IF_POPUP_WINDOW)
2148 return; 2148 return;
2149 2149
2150 CHECK_CURBUF;
2150 if (wp->w_close_cb.cb_name != NULL) 2151 if (wp->w_close_cb.cb_name != NULL)
2151 // Careful: This may make "wp" invalid. 2152 // Careful: This may make "wp" invalid.
2152 invoke_popup_callback(wp, arg); 2153 invoke_popup_callback(wp, arg);
2153 2154
2154 popup_close(id); 2155 popup_close(id);
2156 CHECK_CURBUF;
2155 } 2157 }
2156 2158
2157 void 2159 void
2158 popup_close_with_retval(win_T *wp, int retval) 2160 popup_close_with_retval(win_T *wp, int retval)
2159 { 2161 {
2503 2505
2504 // go through global popups 2506 // go through global popups
2505 for (wp = first_popupwin; wp != NULL; prev = wp, wp = wp->w_next) 2507 for (wp = first_popupwin; wp != NULL; prev = wp, wp = wp->w_next)
2506 if (wp->w_id == id) 2508 if (wp->w_id == id)
2507 { 2509 {
2510 if (wp == curwin)
2511 {
2512 ERROR_IF_ANY_POPUP_WINDOW;
2513 return;
2514 }
2508 if (prev == NULL) 2515 if (prev == NULL)
2509 first_popupwin = wp->w_next; 2516 first_popupwin = wp->w_next;
2510 else 2517 else
2511 prev->w_next = wp->w_next; 2518 prev->w_next = wp->w_next;
2512 popup_free(wp); 2519 popup_free(wp);
2529 win_T *prev = NULL; 2536 win_T *prev = NULL;
2530 2537
2531 for (wp = *root; wp != NULL; prev = wp, wp = wp->w_next) 2538 for (wp = *root; wp != NULL; prev = wp, wp = wp->w_next)
2532 if (wp->w_id == id) 2539 if (wp->w_id == id)
2533 { 2540 {
2541 if (wp == curwin)
2542 {
2543 ERROR_IF_ANY_POPUP_WINDOW;
2544 return;
2545 }
2534 if (prev == NULL) 2546 if (prev == NULL)
2535 *root = wp->w_next; 2547 *root = wp->w_next;
2536 else 2548 else
2537 prev->w_next = wp->w_next; 2549 prev->w_next = wp->w_next;
2538 popup_free(wp); 2550 popup_free(wp);
2879 int 2891 int
2880 error_if_popup_window(int also_with_term UNUSED) 2892 error_if_popup_window(int also_with_term UNUSED)
2881 { 2893 {
2882 // win_execute() may set "curwin" to a popup window temporarily, but many 2894 // win_execute() may set "curwin" to a popup window temporarily, but many
2883 // commands are disallowed then. When a terminal runs in the popup most 2895 // commands are disallowed then. When a terminal runs in the popup most
2884 // things are allowed. 2896 // things are allowed. When a terminal is finished it can be closed.
2885 if (WIN_IS_POPUP(curwin) 2897 if (WIN_IS_POPUP(curwin)
2886 # ifdef FEAT_TERMINAL 2898 # ifdef FEAT_TERMINAL
2887 && (also_with_term || curbuf->b_term == NULL) 2899 && (also_with_term || curbuf->b_term == NULL)
2900 && !term_is_finished(curbuf)
2888 # endif 2901 # endif
2889 ) 2902 )
2890 { 2903 {
2891 emsg(_("E994: Not allowed in a popup window")); 2904 emsg(_("E994: Not allowed in a popup window"));
2892 return TRUE; 2905 return TRUE;