Mercurial > vim
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; |