diff options
author | Bram Moolenaar <Bram@vim.org> | 2016-03-23 20:55:42 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2016-03-23 20:55:42 +0100 |
commit | ffec3c53496d49668669deabc0724ec78e2274fd (patch) | |
tree | c6a1ae2246580463c724cefabc6c9d76b54588a1 /src/quickfix.c | |
parent | 5f436fcf9960c95702820d5ac1b8b612995f6c04 (diff) | |
download | vim-git-ffec3c53496d49668669deabc0724ec78e2274fd.tar.gz |
patch 7.4.1640v7.4.1640
Problem: Crash when an autocommand changes a quickfix list. (Dominique)
Solution: Check wether an entry is still valid. (Yegappan Lakshmanan,
Hirohito Higashi)
Diffstat (limited to 'src/quickfix.c')
-rw-r--r-- | src/quickfix.c | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/src/quickfix.c b/src/quickfix.c index 06e50da47..a2506e1a3 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; + 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; } } - } if (ok == OK) |