changeset 13054:197a08152ad5 v8.0.1402

patch 8.0.1402: crash with nasty autocommand commit https://github.com/vim/vim/commit/9bca805ec49eb0d2d0d0b2093f418ff425500169 Author: Bram Moolenaar <Bram@vim.org> Date: Mon Dec 18 12:37:55 2017 +0100 patch 8.0.1402: crash with nasty autocommand Problem: Crash with nasty autocommand. (gy741, Dominique Pelle) Solution: Check that the new current buffer isn't wiped out. (closes https://github.com/vim/vim/issues/2447)
author Christian Brabandt <cb@256bit.org>
date Mon, 18 Dec 2017 12:45:05 +0100
parents 472e2cba236d
children cd0f518fd36c
files src/buffer.c src/testdir/test_autocmd.vim src/version.c
diffstat 3 files changed, 24 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1665,7 +1665,8 @@ set_curbuf(buf_T *buf, int action)
 #ifdef FEAT_SYN_HL
     long	old_tw = curbuf->b_p_tw;
 #endif
-    bufref_T	bufref;
+    bufref_T	newbufref;
+    bufref_T	prevbufref;
 
     setpcmark();
     if (!cmdmod.keepalt)
@@ -1675,18 +1676,22 @@ set_curbuf(buf_T *buf, int action)
     /* Don't restart Select mode after switching to another buffer. */
     VIsual_reselect = FALSE;
 
-    /* close_windows() or apply_autocmds() may change curbuf */
+    /* close_windows() or apply_autocmds() may change curbuf and wipe out "buf"
+     */
     prevbuf = curbuf;
-    set_bufref(&bufref, prevbuf);
+    set_bufref(&prevbufref, prevbuf);
+    set_bufref(&newbufref, buf);
 
 #ifdef FEAT_AUTOCMD
+    /* Autocommands may delete the curren buffer and/or the buffer we wan to go
+     * to.  In those cases don't close the buffer. */
     if (!apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf)
+	    || (bufref_valid(&prevbufref)
+		&& bufref_valid(&newbufref)
 # ifdef FEAT_EVAL
-	    || (bufref_valid(&bufref) && !aborting())
-# else
-	    || bufref_valid(&bufref)
+		&& !aborting()
 # endif
-       )
+	       ))
 #endif
     {
 #ifdef FEAT_SYN_HL
@@ -1696,9 +1701,9 @@ set_curbuf(buf_T *buf, int action)
 	if (unload)
 	    close_windows(prevbuf, FALSE);
 #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
-	if (bufref_valid(&bufref) && !aborting())
+	if (bufref_valid(&prevbufref) && !aborting())
 #else
-	if (bufref_valid(&bufref))
+	if (bufref_valid(&prevbufref))
 #endif
 	{
 	    win_T  *previouswin = curwin;
--- a/src/testdir/test_autocmd.vim
+++ b/src/testdir/test_autocmd.vim
@@ -1163,3 +1163,11 @@ func Test_TextYankPost()
   unlet g:event
   bwipe!
 endfunc
+
+func Test_nocatch_wipe_all_buffers()
+  " Real nasty autocommand: wipe all buffers on any event.
+  au * * bwipe *
+  call assert_fails('next x', 'E93')
+  bwipe
+  au!
+endfunc
--- a/src/version.c
+++ b/src/version.c
@@ -772,6 +772,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1402,
+/**/
     1401,
 /**/
     1400,