Patch 8.1.0342
Problem: Crash when a callback deletes a window that is being used.
Solution: Do not unload a buffer that is being displayed while redrawing the
screen. Also avoid invoking callbacks while redrawing.
(closes #2107)
Files: src/buffer.c, src/misc2.c
*** ../vim-8.1.0341/src/buffer.c 2018-08-21 18:50:11.153501902 +0200
--- src/buffer.c 2018-09-01 15:16:57.753412395 +0200
***************
*** 412,418 ****
hash_remove(&buf_hashtab, hi);
}
! static char *e_buflocked = N_("E937: Attempt to delete a buffer that is in
use");
/*
* Close the link to a buffer.
--- 412,439 ----
hash_remove(&buf_hashtab, hi);
}
! /*
! * Return TRUE when buffer "buf" can be unloaded.
! * Give an error message and return FALSE when the buffer is locked or the
! * screen is being redrawn and the buffer is in a window.
! */
! static int
! can_unload_buffer(buf_T *buf)
! {
! int can_unload = !buf->b_locked;
!
! if (can_unload && updating_screen)
! {
! win_T *wp;
!
! FOR_ALL_WINDOWS(wp)
! if (wp->w_buffer == buf)
! can_unload = FALSE;
! }
! if (!can_unload)
! EMSG(_("E937: Attempt to delete a buffer that is in use"));
! return can_unload;
! }
/*
* Close the link to a buffer.
***************
*** 474,484 ****
{
if (wipe_buf || unload_buf)
{
! if (buf->b_locked)
! {
! EMSG(_(e_buflocked));
return;
! }
/* Wiping out or unloading a terminal buffer kills the job. */
free_terminal(buf);
}
--- 495,503 ----
{
if (wipe_buf || unload_buf)
{
! if (!can_unload_buffer(buf))
return;
!
/* Wiping out or unloading a terminal buffer kills the job. */
free_terminal(buf);
}
***************
*** 501,511 ****
/* Disallow deleting the buffer when it is locked (already being closed or
* halfway a command that relies on it). Unloading is allowed. */
! if (buf->b_locked > 0 && (del_buf || wipe_buf))
! {
! EMSG(_(e_buflocked));
return;
- }
/* check no autocommands closed the window */
if (win != NULL && win_valid_any_tab(win))
--- 520,527 ----
/* Disallow deleting the buffer when it is locked (already being closed or
* halfway a command that relies on it). Unloading is allowed. */
! if ((del_buf || wipe_buf) && !can_unload_buffer(buf))
return;
/* check no autocommands closed the window */
if (win != NULL && win_valid_any_tab(win))
***************
*** 1196,1203 ****
return errormsg;
}
- static int empty_curbuf(int close_others, int forceit, int action);
-
/*
* Make the current buffer empty.
* Used when it is wiped out and it's the last buffer.
--- 1212,1217 ----
***************
*** 1238,1243 ****
--- 1252,1258 ----
need_fileinfo = FALSE;
return retval;
}
+
/*
* Implementation of the commands for the buffer list.
*
***************
*** 1359,1369 ****
int forward;
bufref_T bufref;
! if (buf->b_locked)
! {
! EMSG(_(e_buflocked));
return FAIL;
- }
set_bufref(&bufref, buf);
--- 1374,1381 ----
int forward;
bufref_T bufref;
! if (!can_unload_buffer(buf))
return FAIL;
set_bufref(&bufref, buf);
*** ../vim-8.1.0341/src/misc2.c 2018-07-29 16:09:14.636945607 +0200
--- src/misc2.c 2018-09-01 15:07:10.019535433 +0200
***************
*** 6366,6398 ****
{
win_T *old_curwin = curwin;
! /* For Win32 mch_breakcheck() does not check for input, do it here. */
# if defined(WIN32) && defined(FEAT_JOB_CHANNEL)
channel_handle_events(FALSE);
# endif
# ifdef FEAT_NETBEANS_INTG
! /* Process the queued netbeans messages. */
netbeans_parse_messages();
# endif
# ifdef FEAT_JOB_CHANNEL
! /* Write any buffer lines still to be written. */
channel_write_any_lines();
! /* Process the messages queued on channels. */
channel_parse_messages();
# endif
# if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11)
! /* Process the queued clientserver messages. */
server_parse_messages();
# endif
# ifdef FEAT_JOB_CHANNEL
! /* Check if any jobs have ended. */
job_check_ended();
# endif
! /* If the current window changed we need to bail out of the waiting loop.
! * E.g. when a job exit callback closes the terminal window. */
if (curwin != old_curwin)
ins_char_typebuf(K_IGNORE);
}
--- 6366,6403 ----
{
win_T *old_curwin = curwin;
! // Do not handle messages while redrawing, because it may cause buffers to
! // change or be wiped while they are being redrawn.
! if (updating_screen)
! return;
!
! // For Win32 mch_breakcheck() does not check for input, do it here.
# if defined(WIN32) && defined(FEAT_JOB_CHANNEL)
channel_handle_events(FALSE);
# endif
# ifdef FEAT_NETBEANS_INTG
! // Process the queued netbeans messages.
netbeans_parse_messages();
# endif
# ifdef FEAT_JOB_CHANNEL
! // Write any buffer lines still to be written.
channel_write_any_lines();
! // Process the messages queued on channels.
channel_parse_messages();
# endif
# if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11)
! // Process the queued clientserver messages.
server_parse_messages();
# endif
# ifdef FEAT_JOB_CHANNEL
! // Check if any jobs have ended.
job_check_ended();
# endif
! // If the current window changed we need to bail out of the waiting loop.
! // E.g. when a job exit callback closes the terminal window.
if (curwin != old_curwin)
ins_char_typebuf(K_IGNORE);
}
*** ../vim-8.1.0341/src/version.c 2018-08-31 23:06:18.735841246 +0200
--- src/version.c 2018-09-01 15:02:16.242604587 +0200
***************
*** 796,797 ****
--- 796,799 ----
{ /* Add new patch number below this line */
+ /**/
+ 342,
/**/
--
hundred-and-one symptoms of being an internet addict:
5. You find yourself brainstorming for new subjects to search.
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.