summaryrefslogtreecommitdiff
path: root/src/quickfix.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2016-03-23 20:55:42 +0100
committerBram Moolenaar <Bram@vim.org>2016-03-23 20:55:42 +0100
commitffec3c53496d49668669deabc0724ec78e2274fd (patch)
treec6a1ae2246580463c724cefabc6c9d76b54588a1 /src/quickfix.c
parent5f436fcf9960c95702820d5ac1b8b612995f6c04 (diff)
downloadvim-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.c47
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)