Hi Yegappan and list,

2016-3-23(Wed) 14:39:31 UTC+9 h_east:
> Hi Yegappan,
> 
> 2016-3-23(Wed) 14:02:53 UTC+9 yega...@gmail.com:
> > Hi,
> > 
> > On Mon, Mar 21, 2016 at 2:45 AM, Dominique Pellé
> > <dominique.pe...@gmail.com> wrote:
> > > Hi
> > >
> > > afl-fuzz found another crash with use of freed memory in vim-7.4.1627
> > > (and older) in quickfix code. This is a different bug that the one fixed
> > > recently in Vim-7.4.1592:
> > >
> > 
> > The attached patch fixes this issue. These issues are caused by autocmds
> > modifying the location list while the location list is being used.
> 
> This issue also occurs with the quickfix.
> 
> ]$ vim -Nu NONE -S crash_qf.vim
> Vim: Caught deadly signal SEGV
> 
> Vim: Finished.
> Segmentation fault (core dumped)
> 
> 
> PS
> I think we should abort even if `qi->qf_curlist` has changed.
> 
> I'm sorry.  In fact, I have had already written a patch.
> But did not yet been submitted.
> I'll send patch later.

A patch is attached.
Please check it.

Yegappan>
I have modified to respect your patch.
Thank you for the nice patch.
After all, You are the quickfix wizard :-)

--
Best regards,
Hirohito Higashi (a.k.a. h_east)

-- 
-- 
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 vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
diff --git a/runtime/doc/quickfix.txt b/runtime/doc/quickfix.txt
index 0ca314d..fb23552 100644
--- a/runtime/doc/quickfix.txt
+++ b/runtime/doc/quickfix.txt
@@ -60,6 +60,10 @@ command with 'l'.
 If the current window was closed by an |autocommand| while processing a
 location list command, it will be aborted.
 
+							*E925* *E926*
+If the current quickfix or location list was changed by an |autocommand| while
+processing a quickfix or location list command, it will be aborted.
+
 							*:cc*
 :cc[!] [nr]		Display error [nr].  If [nr] is omitted, the same
 			error is displayed again.  Without [!] this doesn't
diff --git a/src/quickfix.c b/src/quickfix.c
index 06e50da..b95d1a7 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -1413,6 +1413,33 @@ qf_guess_filepath(char_u *filename)
 }
 
 /*
+ * When loading a file from the quickfix, the auto commands may modify it.
+ * This may invalidate the current quickfix entry.  This function checks
+ * whether a entry is still present in the quickfix.
+ * Similar to location list.
+ */
+    static int
+is_qf_entry_present(qf_info_T *qi, qfline_T *qf_ptr)
+{
+    qf_list_T	*qfl;
+    qfline_T	*qfp;
+    int		i;
+
+    qfl = &qi->qf_lists[qi->qf_curlist];
+
+    /* Search for the entry in the current list */
+    for (i = 0, qfp = qfl->qf_start; i < qfl->qf_count;
+	    ++i, qfp = qfp->qf_next)
+	if (qfp == qf_ptr)
+	    break;
+
+    if (i == qfl->qf_count) /* Entry is not found */
+	return FALSE;
+
+    return TRUE;
+}
+
+/*
  * jump to a quickfix line
  * if dir == FORWARD go "errornr" valid entries forward
  * if dir == BACKWARD go "errornr" valid entries backward
@@ -1794,18 +1821,34 @@ win_found:
 	}
 	else
 	{
+	    int old_qf_curlist = qi->qf_curlist;
+	    int is_abort = FALSE;
+
 	    ok = buflist_getfile(qf_ptr->qf_fnum,
 			    (linenr_T)1, GETF_SETMARK | GETF_SWITCH, forceit);
 	    if (qi != &ql_info && !win_valid(oldwin))
 	    {
 		EMSG(_("E924: Current window was closed"));
+		is_abort = TRUE;
+	    }
+	    else if (old_qf_curlist != qi->qf_curlist
+		    || !is_qf_entry_present(qi, qf_ptr))
+	    {
+		if (qi == &ql_info)
+		    EMSG(_("E925: Current quickfix was changed"));
+		else
+		    EMSG(_("E926: Current location list was changed"));
+		is_abort = TRUE;
+	    }
+
+	    if (is_abort)
+	    {
 		ok = FALSE;
 		qi = NULL;
 		qf_ptr = NULL;
 		opened_window = FALSE;
 	    }
 	}
-
     }
 
     if (ok == OK)
diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim
index 07c465d..667ece4 100644
--- a/src/testdir/test_quickfix.vim
+++ b/src/testdir/test_quickfix.vim
@@ -504,7 +504,7 @@ function Test_locationlist_curwin_was_closed()
       autocmd BufReadCmd t call R(expand("<amatch>"))
     augroup END
 
-    function R(n)
+    function! R(n)
       quit
     endfunc
 
@@ -637,3 +637,45 @@ function! Test_efm1()
     call delete('Xerrorfile2')
     call delete('Xtestfile')
 endfunction
+
+function XquickfixChangedByAutocmd(cchar)
+  let Xolder = a:cchar . 'older'
+  let Xgetexpr = a:cchar . 'getexpr'
+  let Xrewind = a:cchar . 'rewind'
+  if a:cchar == 'c'
+    let Xsetlist = 'setqflist('
+    let ErrorNr = 'E925'
+    function! ReadFunc()
+      colder
+      cgetexpr []
+    endfunc
+  else
+    let Xsetlist = 'setloclist(0,'
+    let ErrorNr = 'E926'
+    function! ReadFunc()
+      lolder
+      lgetexpr []
+    endfunc
+  endif
+
+  augroup testgroup
+    au!
+    autocmd BufReadCmd t call ReadFunc()
+  augroup END
+
+  bwipe!
+  let words = [ "a", "b" ]
+  let qflist = []
+  for word in words
+    call add(qflist, {'filename': 't'})
+    exec "call " . Xsetlist . "qflist, '')"
+  endfor
+  exec "call assert_fails('" . Xrewind . "', '" . ErrorNr . ":')"
+
+  augroup! testgroup
+endfunc
+
+function Test_quickfix_was_changed_by_autocmd()
+  call XquickfixChangedByAutocmd('c')
+  call XquickfixChangedByAutocmd('l')
+endfunction

Raspunde prin e-mail lui