Patch 7.4.1640
Problem:    Crash when an autocommand changes a quickfix list. (Dominique)
Solution:   Check wether an entry is still valid. (Yegappan Lakshmanan,
            Hirohito Higashi)
Files:      src/quickfix.c, src/testdir/test_quickfix.vim


*** ../vim-7.4.1639/src/quickfix.c      2016-03-19 22:11:47.428674921 +0100
--- src/quickfix.c      2016-03-23 20:53:38.972104091 +0100
***************
*** 1413,1418 ****
--- 1413,1445 ----
  }
  
  /*
+  * 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,1811 ****
        }
        else
        {
            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"));
                ok = FALSE;
                qi = NULL;
                qf_ptr = NULL;
-               opened_window = FALSE;
            }
        }
- 
      }
  
      if (ok == OK)
--- 1821,1854 ----
        }
        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;
+               opened_window = FALSE;
+           }
+           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;
            }
        }
      }
  
      if (ok == OK)
*** ../vim-7.4.1639/src/testdir/test_quickfix.vim       2016-03-19 
22:53:54.229469402 +0100
--- src/testdir/test_quickfix.vim       2016-03-23 20:46:19.100519650 +0100
***************
*** 504,510 ****
        autocmd BufReadCmd t call R(expand("<amatch>"))
      augroup END
  
!     function R(n)
        quit
      endfunc
  
--- 504,510 ----
        autocmd BufReadCmd t call R(expand("<amatch>"))
      augroup END
  
!     function! R(n)
        quit
      endfunc
  
***************
*** 637,639 ****
--- 637,681 ----
      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
*** ../vim-7.4.1639/src/version.c       2016-03-22 22:33:59.214427026 +0100
--- src/version.c       2016-03-23 20:47:39.943713815 +0100
***************
*** 750,751 ****
--- 750,753 ----
  {   /* Add new patch number below this line */
+ /**/
+     1640,
  /**/

-- 
A meeting is an event at which the minutes are kept and the hours are lost.

 /// 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.

Raspunde prin e-mail lui