To: vim_dev@googlegroups.com Subject: Patch 7.4.1640 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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("")) augroup END ! function R(n) quit endfunc --- 504,510 ---- autocmd BufReadCmd t call R(expand("")) 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 -- Bram@Moolenaar.net -- 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 ///