On Di, 04 Jul 2017, Christian Brabandt wrote:

> minibufexpl sets `bufhidden=delete` and also installs an QuitPre
> autocommand, that moves to another window. That confuses vim and makes
> the `wp` pointer from `ex_quit()` invalid. 


It is actually the QuitPre autocommand, that closes the current window 
and tabpage, that makes vim segfault. I attach a patch, that includes a 
test.

Best,
Christian
-- 
Hallo Bademantelträger!

-- 
-- 
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.
From 6a212f9aa6a539706b78fba7e531c8bafb1db330 Mon Sep 17 00:00:00 2001
From: Christian Brabandt <[email protected]>
Date: Wed, 5 Jul 2017 15:01:41 +0200
Subject: [PATCH] Fix crash when closing last window in BufQuitPre autocmd

When the last window of a tabpage is closed in a QuitePre autocommand,
we end up with an invalid window pointer, which we will later try to
access and possibly cause a segfault.

So make sure, the wp window pointer is still valid after the QuitPre
autocommand, if not, abort the issued `:q` command (so that only the
current tabpage has been closed, all other tabpages should be still
intact.)
---
 src/ex_docmd.c               |  6 +++++-
 src/testdir/test_tabpage.vim | 18 ++++++++++++++++++
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index bdd152dfd..280fc33f7 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -7269,7 +7269,11 @@ ex_quit(exarg_T *eap)
     /* Refuse to quit when locked or when the buffer in the last window is
      * being closed (can only happen in autocommands). */
     if (curbuf_locked() || (wp->w_buffer->b_nwindows == 1
-						&& wp->w_buffer->b_locked > 0))
+						&& wp->w_buffer->b_locked > 0)
+#ifdef FEAT_WINDOWS
+	    || !win_valid(wp)
+#endif
+	    )
 	return;
 #endif
 
diff --git a/src/testdir/test_tabpage.vim b/src/testdir/test_tabpage.vim
index c139958df..239b1b965 100644
--- a/src/testdir/test_tabpage.vim
+++ b/src/testdir/test_tabpage.vim
@@ -473,5 +473,23 @@ func Test_tabnext_on_buf_unload2()
   endwhile
 endfunc
 
+func Test_close_on_quitpre()
+  " This once caused a crash
+  new
+  only
+  set bufhidden=delete
+  au QuitPre <buffer> close
+  tabnew tab1
+  tabnew tab2
+  1tabn
+  q!
+  call assert_equal(1, tabpagenr())
+  call assert_equal(2, tabpagenr('$'))
+  " clean up
+  while tabpagenr('$') > 1
+    bwipe!
+  endwhile
+  1b
+endfunc
 
 " vim: shiftwidth=2 sts=2 expandtab
-- 
2.11.0

Raspunde prin e-mail lui