diff --git a/src/quickfix.c b/src/quickfix.c index 6af62e8dfe56d..78f6880d80206 100644 --- a/src/quickfix.c +++ b/src/quickfix.c @@ -594,6 +594,7 @@ enum { QF_NOMEM = 3, QF_IGNORE_LINE = 4, QF_MULTISCAN = 5, + QF_ABORT = 6 }; /* @@ -3153,7 +3154,7 @@ qf_jump_to_usable_window(int qf_fnum, int newwin, int *opened_window) /* * Edit the selected file or help file. * Returns OK if successfully edited the file, FAIL on failing to open the - * buffer and NOTDONE if the quickfix/location list was freed by an autocmd + * buffer and QF_ABORT if the quickfix/location list was freed by an autocmd * when opening the buffer. */ static int @@ -3199,14 +3200,14 @@ qf_jump_edit_buffer( { emsg(_(e_current_window_was_closed)); *opened_window = FALSE; - return NOTDONE; + return QF_ABORT; } } if (qfl_type == QFLT_QUICKFIX && !qflist_valid(NULL, save_qfid)) { emsg(_(e_current_quickfix_list_was_changed)); - return NOTDONE; + return QF_ABORT; } // Check if the list was changed. The pointers may happen to be identical, @@ -3219,7 +3220,7 @@ qf_jump_edit_buffer( emsg(_(e_current_quickfix_list_was_changed)); else emsg(_(e_current_location_list_was_changed)); - return NOTDONE; + return QF_ABORT; } return retval; @@ -3317,7 +3318,8 @@ qf_jump_print_msg( * a new window. * Returns OK if successfully jumped or opened a window. Returns FAIL if not * able to jump/open a window. Returns NOTDONE if a file is not associated - * with the entry. + * with the entry. Returns QF_ABORT if the quickfix/location list was modified + * by an autocmd. */ static int qf_jump_open_window( @@ -3344,7 +3346,7 @@ qf_jump_open_window( emsg(_(e_current_quickfix_list_was_changed)); else emsg(_(e_current_location_list_was_changed)); - return FAIL; + return QF_ABORT; } // If currently in the quickfix window, find another window to show the @@ -3368,7 +3370,7 @@ qf_jump_open_window( emsg(_(e_current_quickfix_list_was_changed)); else emsg(_(e_current_location_list_was_changed)); - return FAIL; + return QF_ABORT; } return OK; @@ -3379,7 +3381,7 @@ qf_jump_open_window( * particular line/column, adjust the folds and display a message about the * jump. * Returns OK on success and FAIL on failing to open the file/buffer. Returns - * NOTDONE if the quickfix/location list is freed by an autocmd when opening + * QF_ABORT if the quickfix/location list is freed by an autocmd when opening * the file. */ static int @@ -3508,14 +3510,20 @@ qf_jump_newwin(qf_info_T *qi, retval = qf_jump_open_window(qi, qf_ptr, newwin, &opened_window); if (retval == FAIL) goto failed; + if (retval == QF_ABORT) + { + qi = NULL; + qf_ptr = NULL; + goto theend; + } if (retval == NOTDONE) goto theend; retval = qf_jump_to_buffer(qi, qf_index, qf_ptr, forceit, prev_winid, &opened_window, old_KeyTyped, print_message); - if (retval == NOTDONE) + if (retval == QF_ABORT) { - // Quickfix/location list is freed by an autocmd + // Quickfix/location list was modified by an autocmd qi = NULL; qf_ptr = NULL; } diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim index 762fa8d8d0e3c..31d36ef1d63c6 100644 --- a/src/testdir/test_quickfix.vim +++ b/src/testdir/test_quickfix.vim @@ -6363,5 +6363,22 @@ func Test_quickfixtextfunc_recursive() cclose endfunc +" Test for replacing the location list from an autocmd. This used to cause a +" read from freed memory. +func Test_loclist_replace_autocmd() + %bw! + call setloclist(0, [], 'f') + let s:bufnr = bufnr() + cal setloclist(0, [{'0': 0, '': ''}]) + au BufEnter * cal setloclist(1, [{'t': ''}, {'bufnr': s:bufnr}], 'r') + lopen + try + exe "norm j\" + catch + endtry + lnext + %bw! + call setloclist(0, [], 'f') +endfunc " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c index 6b4bdfab29b24..206548373a013 100644 --- a/src/version.c +++ b/src/version.c @@ -707,6 +707,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 286, /**/ 285, /**/