changeset 19649:d4baa35fea5d v8.2.0381

patch 8.2.0381: using freed memory with :lvimgrep and autocommand Commit: https://github.com/vim/vim/commit/2573af3519ad062ddad647b97e32090f106f2ac1 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Mar 14 17:21:34 2020 +0100 patch 8.2.0381: using freed memory with :lvimgrep and autocommand Problem: Using freed memory with :lvimgrep and autocommand. (extracted from POC by Dominique Pelle) Solution: Avoid deleting a dummy buffer used in a window. (closes #5777)
author Bram Moolenaar <Bram@vim.org>
date Sat, 14 Mar 2020 17:30:04 +0100
parents 50689415194e
children 1d036bf38467
files src/quickfix.c src/testdir/test_quickfix.vim src/version.c
diffstat 3 files changed, 30 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -6268,7 +6268,26 @@ load_dummy_buffer(
     static void
 wipe_dummy_buffer(buf_T *buf, char_u *dirname_start)
 {
-    if (curbuf != buf)		// safety check
+    // If any autocommand opened a window on the dummy buffer, close that
+    // window.  If we can't close them all then give up.
+    while (buf->b_nwindows > 0)
+    {
+	int	    did_one = FALSE;
+	win_T	    *wp;
+
+	if (firstwin->w_next != NULL)
+	    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+		if (wp->w_buffer == buf)
+		{
+		    if (win_close(wp, FALSE) == OK)
+			did_one = TRUE;
+		    break;
+		}
+	if (!did_one)
+	    return;
+    }
+
+    if (curbuf != buf && buf->b_nwindows == 0)	// safety check
     {
 #if defined(FEAT_EVAL)
 	cleanup_T   cs;
--- a/src/testdir/test_quickfix.vim
+++ b/src/testdir/test_quickfix.vim
@@ -3684,6 +3684,14 @@ func Test_lvimgrep_crash()
   enew | only
 endfunc
 
+func Test_lvimgrep_crash2()
+  au BufNewFile x sfind
+  call assert_fails('lvimgrep x x', 'E480:')
+  call assert_fails('lvimgrep x x x', 'E480:')
+
+  au! BufNewFile
+endfunc
+
 " Test for the position of the quickfix and location list window
 func Test_qfwin_pos()
   " Open two windows
--- a/src/version.c
+++ b/src/version.c
@@ -739,6 +739,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    381,
+/**/
     380,
 /**/
     379,