vim-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)

ffec3c5349
This commit is contained in:
James McCoy 2016-11-12 08:06:58 -05:00
parent aba853a156
commit 7231438f12
No known key found for this signature in database
GPG Key ID: DFE691AE331BA3DB
4 changed files with 92 additions and 3 deletions

View File

@ -53,6 +53,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

View File

@ -1254,6 +1254,32 @@ static char_u *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 bool 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
@ -1585,14 +1611,29 @@ win_found:
oldwin == curwin ? curwin : NULL);
}
} else {
int old_qf_curlist = qi->qf_curlist;
bool 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;
opened_window = false;
}
}
}

View File

@ -804,7 +804,7 @@ static int included_patches[] = {
1643,
1642,
1641,
// 1640,
1640,
// 1639,
// 1638,
// 1637 NA

View File

@ -265,7 +265,7 @@ describe('helpgrep', function()
autocmd BufReadCmd t call R(expand("<amatch>"))
augroup END
function R(n)
function! R(n)
quit
endfunc
@ -406,6 +406,43 @@ describe('helpgrep', function()
augroup END
augroup! QfBufWinEnter
endfunc
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
]])
end)
@ -478,6 +515,13 @@ describe('helpgrep', function()
call('Test_locationlist')
expected_empty()
end)
it('is changed by autocmd', function()
call('XquickfixChangedByAutocmd', 'c')
expected_empty()
call('XquickfixChangedByAutocmd', 'l')
expected_empty()
end)
end)
describe('errorformat', function()