# HG changeset patch # User Bram Moolenaar # Date 1661631302 -7200 # Node ID c554ac4c17c316e69028eeb3300c5d7d335c347f # Parent e672be81c45aa2a80c1e34a9a46f26e50754a4af patch 9.0.0286: using freed memory when location list changed in autocmd Commit: https://github.com/vim/vim/commit/6d24a51b94beb1991cddce221f90b455e2d50db7 Author: Yegappan Lakshmanan Date: Sat Aug 27 20:59:57 2022 +0100 patch 9.0.0286: using freed memory when location list changed in autocmd Problem: Using freed memory when location list changed in autocmd. Solution: Return QF_ABORT and handle it. (Yegappan Lakshmanan, closes #10993) diff --git a/src/quickfix.c b/src/quickfix.c --- 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, in /* * 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) - { - // Quickfix/location list is freed by an autocmd + if (retval == QF_ABORT) + { + // 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 --- 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 --- a/src/version.c +++ b/src/version.c @@ -708,6 +708,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 286, +/**/ 285, /**/ 284,