Hi Dominique and list, 2016-3-19(Sat) 10:01:43 UTC+9 h_east: > Hi, > > 2016-3-19(Sat) 5:18:03 UTC+9 Dominique Pelle: > > Hi > > > > afl-fuzz found another case that crashes > > Vim-7.4.1591 and older. > > > > $ cat > crash.vim <<EOF > > fun R(n) > > wincmd p > > only > > endfun > > > > helpgrep quickfix > > autocmd BufReadCmd * call R(expand("<amatch>")) > > let s = [""] > > let q = [] > > for w in s > > call add(q, {'filename': 't' }) > > call setloclist(0, q) > > endfor > > lrewind > > EOF > > > > $ vim -u NONE -S crash.vim > > Vim: Caught deadly signal SEGV > > > > Vim: Finished. > > Segmentation fault (core dumped) > > > > Valgrind says: > > > > ==4729== Memcheck, a memory error detector > > ==4729== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. > > ==4729== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info > > ==4729== Command: ./vim -u NONE -S crash.vim > > ==4729== Parent PID: 2749 > > ==4729== > > ==4729== Invalid read of size 8 > > ==4729== at 0x53CDF1: qf_jump (quickfix.c:1808) > > ==4729== by 0x49F6F7: do_one_cmd (ex_docmd.c:2921) > > ==4729== by 0x49F6F7: do_cmdline (ex_docmd.c:1107) > > ==4729== by 0x493951: do_source (ex_cmds2.c:3895) > > ==4729== by 0x4942EB: cmd_source (ex_cmds2.c:3508) > > ==4729== by 0x49F6F7: do_one_cmd (ex_docmd.c:2921) > > ==4729== by 0x49F6F7: do_cmdline (ex_docmd.c:1107) > > ==4729== by 0x43D891: exe_commands (main.c:2925) > > ==4729== by 0x43D891: main (main.c:955) > > ==4729== Address 0x10b4c0f8 is 40 bytes inside a block of size 64 free'd > > ==4729== at 0x4C2BDEC: free (in > > /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) > > ==4729== by 0x53A237: qf_free (quickfix.c:2142) > > ==4729== by 0x53A2FC: ll_free_all (quickfix.c:953) > > ==4729== by 0x53C7A4: qf_free_all (quickfix.c:967) > > ==4729== by 0x5C0480: win_free (window.c:4726) > > ==4729== by 0x5C174E: win_free_mem (window.c:2614) > > ==4729== by 0x5C1C46: win_close (window.c:2455) > > ==4729== by 0x5C34C3: close_others (window.c:3429) > > ==4729== by 0x49F6F7: do_one_cmd (ex_docmd.c:2921) > > ==4729== by 0x49F6F7: do_cmdline (ex_docmd.c:1107) > > ==4729== by 0x474024: call_user_func (eval.c:24927) > > ==4729== by 0x474024: call_func (eval.c:8868) > > ==4729== by 0x47872F: get_func_tv (eval.c:8657) > > ==4729== by 0x4800FB: ex_call (eval.c:3535) > > ==4729== by 0x49F6F7: do_one_cmd (ex_docmd.c:2921) > > ==4729== by 0x49F6F7: do_cmdline (ex_docmd.c:1107) > > ==4729== by 0x4B52CC: apply_autocmds_group (fileio.c:9451) > > ==4729== by 0x4B7B77: apply_autocmds_exarg (fileio.c:9018) > > ==4729== by 0x4B7B77: readfile (fileio.c:383) > > ==4729== by 0x44517F: open_buffer (buffer.c:151) > > ==4729== by 0x486F8A: do_ecmd (ex_cmds.c:3768) > > ==4729== by 0x487330: getfile (ex_cmds.c:3190) > > ==4729== by 0x43FB81: buflist_getfile (buffer.c:2094) > > ==4729== by 0x53D026: qf_jump (quickfix.c:1798) > > ==4729== by 0x49F6F7: do_one_cmd (ex_docmd.c:2921) > > ==4729== by 0x49F6F7: do_cmdline (ex_docmd.c:1107) > > ==4729== by 0x493951: do_source (ex_cmds2.c:3895) > > ==4729== by 0x4942EB: cmd_source (ex_cmds2.c:3508) > > ==4729== by 0x49F6F7: do_one_cmd (ex_docmd.c:2921) > > ==4729== by 0x49F6F7: do_cmdline (ex_docmd.c:1107) > > ==4729== by 0x43D891: exe_commands (main.c:2925) > > ==4729== by 0x43D891: main (main.c:955) > > (more errors after that) > > > > Code in quickfix.c: > > > > 1424 void > > 1425 qf_jump( > > .... > > 1797 else > > !!1798 ok = buflist_getfile(qf_ptr->qf_fnum, > > 1799 (linenr_T)1, GETF_SETMARK | > > GETF_SWITCH, forceit); > > 1800 } > > 1801 > > 1802 if (ok == OK) > > 1803 { > > 1804 /* When not switched to another buffer, still need to > > set pc mark */ > > 1805 if (curbuf == old_curbuf) > > 1806 setpcmark(); > > 1807 > > !!1808 if (qf_ptr->qf_pattern == NULL) > > > > Memory used at line quickfix.c:1808 was previously freed > > a few lines above at quickfix.c:1798 which triggered an > > autocommand. > > > > I don't understand the code enough to see how to fix it. > > I've already written a patch. > I am writing a test now. > > Please wait for a few hours.
An attached patch may fix this problem. I was wondering if anyone could confirm this. Thanks. -- 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 3d42337..13a2ff7 100644 --- a/runtime/doc/quickfix.txt +++ b/runtime/doc/quickfix.txt @@ -55,6 +55,9 @@ list is destroyed. The following quickfix commands can be used. The location list commands are similar to the quickfix commands, replacing the 'c' prefix in the quickfix command with 'l'. + *E924* +If current window was closed by |autocommand| in the location list command +proccess, it will be aborted. *:cc* :cc[!] [nr] Display error [nr]. If [nr] is omitted, the same diff --git a/src/globals.h b/src/globals.h index bd9ef5c..e3ee91b 100644 --- a/src/globals.h +++ b/src/globals.h @@ -1511,6 +1511,7 @@ EXTERN char_u e_prev_dir[] INIT(= N_("E459: Cannot go back to previous directory #ifdef FEAT_QUICKFIX EXTERN char_u e_quickfix[] INIT(= N_("E42: No Errors")); EXTERN char_u e_loclist[] INIT(= N_("E776: No location list")); +EXTERN char_u e_curwinclosed[] INIT(= N_("E924: Current window was closed")); #endif EXTERN char_u e_re_damg[] INIT(= N_("E43: Damaged match string")); EXTERN char_u e_re_corr[] INIT(= N_("E44: Corrupted regexp program")); diff --git a/src/quickfix.c b/src/quickfix.c index 8dfad2e..cfa8db6 100644 --- a/src/quickfix.c +++ b/src/quickfix.c @@ -1795,8 +1795,18 @@ win_found: oldwin == curwin ? curwin : NULL); } else + { ok = buflist_getfile(qf_ptr->qf_fnum, (linenr_T)1, GETF_SETMARK | GETF_SWITCH, forceit); + if (qi != &ql_info && !win_valid(oldwin)) + { + EMSG(_(e_curwinclosed)); + ok = FALSE; + qi = NULL; + qf_ptr = NULL; + } + } + } if (ok == OK) @@ -1899,7 +1909,7 @@ win_found: if (opened_window) win_close(curwin, TRUE); /* Close opened window */ #endif - if (qf_ptr->qf_fnum != 0) + if (qf_ptr != NULL && qf_ptr->qf_fnum != 0) { /* * Couldn't open file, so put index back where it was. This could @@ -1913,8 +1923,11 @@ failed: } } theend: - qi->qf_lists[qi->qf_curlist].qf_ptr = qf_ptr; - qi->qf_lists[qi->qf_curlist].qf_index = qf_index; + if (qi != NULL) + { + qi->qf_lists[qi->qf_curlist].qf_ptr = qf_ptr; + qi->qf_lists[qi->qf_curlist].qf_index = qf_index; + } #ifdef FEAT_WINDOWS if (p_swb != old_swb && opened_window) { diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim index 5982aee..22a7e67 100644 --- a/src/testdir/test_quickfix.vim +++ b/src/testdir/test_quickfix.vim @@ -495,3 +495,22 @@ function Test_locationlist() augroup! testgroup endfunction + +function Test_locationlist_curwin_was_closed() + augroup testgroup + au! + autocmd BufReadCmd t call R(expand("<amatch>")) + augroup END + + function R(n) + quit + endfunc + + new + let q = [] + call add(q, {'filename': 't' }) + call setloclist(0, q) + call assert_fails('lrewind', 'E924:') + + augroup! testgroup +endfunction