From: Bram Moolenaar Date: Wed, 4 Nov 2020 10:03:12 +0000 (+0100) Subject: patch 8.2.1948: GUI: crash when handling message while closing a window X-Git-Tag: v8.2.1948 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4778b4d0e147793a4254cbda9c0e270250e970f5;p=vim patch 8.2.1948: GUI: crash when handling message while closing a window Problem: GUI: crash when handling message while closing a window. (Srinath Avadhanula) Solution: Don't handle message while closing a window. (closes #7250) --- diff --git a/src/getchar.c b/src/getchar.c index 6e469f49b..b0cc8c231 100644 --- a/src/getchar.c +++ b/src/getchar.c @@ -2155,7 +2155,8 @@ parse_queued_messages(void) // Do not handle messages while redrawing, because it may cause buffers to // change or be wiped while they are being redrawn. - if (updating_screen) + // Also bail out when parsing messages was explicitly disabled. + if (updating_screen || dont_parse_messages) return; // If memory allocation fails during startup we'll exit but curbuf or diff --git a/src/globals.h b/src/globals.h index 379a532fa..dd7fa4a53 100644 --- a/src/globals.h +++ b/src/globals.h @@ -581,6 +581,12 @@ EXTERN int diff_need_scrollbind INIT(= FALSE); // ('lines' and 'rows') must not be changed. EXTERN int updating_screen INIT(= FALSE); +#ifdef MESSAGE_QUEUE +// While closing windows or buffers messages should not be handled to avoid +// using invalid windows or buffers. +EXTERN int dont_parse_messages INIT(= FALSE); +#endif + #ifdef FEAT_MENU // The root of the menu hierarchy. EXTERN vimmenu_T *root_menu INIT(= NULL); diff --git a/src/version.c b/src/version.c index 015cf4cb1..d380452c4 100644 --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1948, /**/ 1947, /**/ diff --git a/src/window.c b/src/window.c index 9dbfae210..2cd06630f 100644 --- a/src/window.c +++ b/src/window.c @@ -2569,7 +2569,12 @@ win_close(win_T *win, int free_buf) // Now we are really going to close the window. Disallow any autocommand // to split a window to avoid trouble. + // Also bail out of parse_queued_messages() to avoid it tries to update the + // screen. ++split_disallowed; +#ifdef MESSAGE_QUEUE + ++dont_parse_messages; +#endif // Free the memory used for the window and get the window that received // the screen space. @@ -2626,6 +2631,9 @@ win_close(win_T *win, int free_buf) } --split_disallowed; +#ifdef MESSAGE_QUEUE + --dont_parse_messages; +#endif /* * If last window has a status line now and we don't want one,