To: vim_dev@googlegroups.com Subject: Patch 9.0.0286 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.0286 Problem: Using freed memory when location list changed in autocmd. Solution: Return QF_ABORT and handle it. (Yegappan Lakshmanan, closes #10993) Files: src/quickfix.c, src/testdir/test_quickfix.vim *** ../vim-9.0.0285/src/quickfix.c 2022-08-24 20:07:19.342558427 +0100 --- src/quickfix.c 2022-08-27 20:56:11.908359958 +0100 *************** *** 594,599 **** --- 594,600 ---- QF_NOMEM = 3, QF_IGNORE_LINE = 4, QF_MULTISCAN = 5, + QF_ABORT = 6 }; /* *************** *** 3153,3159 **** /* * 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 * when opening the buffer. */ static int --- 3154,3160 ---- /* * Edit the selected file or help file. * Returns OK if successfully edited the file, FAIL on failing to open the ! * buffer and QF_ABORT if the quickfix/location list was freed by an autocmd * when opening the buffer. */ static int *************** *** 3199,3212 **** { emsg(_(e_current_window_was_closed)); *opened_window = FALSE; ! return NOTDONE; } } if (qfl_type == QFLT_QUICKFIX && !qflist_valid(NULL, save_qfid)) { emsg(_(e_current_quickfix_list_was_changed)); ! return NOTDONE; } // Check if the list was changed. The pointers may happen to be identical, --- 3200,3213 ---- { emsg(_(e_current_window_was_closed)); *opened_window = FALSE; ! return QF_ABORT; } } if (qfl_type == QFLT_QUICKFIX && !qflist_valid(NULL, save_qfid)) { emsg(_(e_current_quickfix_list_was_changed)); ! return QF_ABORT; } // Check if the list was changed. The pointers may happen to be identical, *************** *** 3219,3225 **** emsg(_(e_current_quickfix_list_was_changed)); else emsg(_(e_current_location_list_was_changed)); ! return NOTDONE; } return retval; --- 3220,3226 ---- emsg(_(e_current_quickfix_list_was_changed)); else emsg(_(e_current_location_list_was_changed)); ! return QF_ABORT; } return retval; *************** *** 3317,3323 **** * 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. */ static int qf_jump_open_window( --- 3318,3325 ---- * 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. Returns QF_ABORT if the quickfix/location list was modified ! * by an autocmd. */ static int qf_jump_open_window( *************** *** 3344,3350 **** emsg(_(e_current_quickfix_list_was_changed)); else emsg(_(e_current_location_list_was_changed)); ! return FAIL; } // If currently in the quickfix window, find another window to show the --- 3346,3352 ---- emsg(_(e_current_quickfix_list_was_changed)); else emsg(_(e_current_location_list_was_changed)); ! return QF_ABORT; } // If currently in the quickfix window, find another window to show the *************** *** 3368,3374 **** emsg(_(e_current_quickfix_list_was_changed)); else emsg(_(e_current_location_list_was_changed)); ! return FAIL; } return OK; --- 3370,3376 ---- emsg(_(e_current_quickfix_list_was_changed)); else emsg(_(e_current_location_list_was_changed)); ! return QF_ABORT; } return OK; *************** *** 3379,3385 **** * 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 * the file. */ static int --- 3381,3387 ---- * 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 ! * QF_ABORT if the quickfix/location list is freed by an autocmd when opening * the file. */ static int *************** *** 3508,3521 **** retval = qf_jump_open_window(qi, qf_ptr, newwin, &opened_window); if (retval == FAIL) goto failed; 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 qi = NULL; qf_ptr = NULL; } --- 3510,3529 ---- 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 == QF_ABORT) { ! // Quickfix/location list was modified by an autocmd qi = NULL; qf_ptr = NULL; } *** ../vim-9.0.0285/src/testdir/test_quickfix.vim 2022-08-24 20:07:19.342558427 +0100 --- src/testdir/test_quickfix.vim 2022-08-27 20:56:11.908359958 +0100 *************** *** 6363,6367 **** --- 6363,6384 ---- 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 *** ../vim-9.0.0285/src/version.c 2022-08-27 12:22:19.979008597 +0100 --- src/version.c 2022-08-27 16:58:13.441095567 +0100 *************** *** 709,710 **** --- 709,712 ---- { /* Add new patch number below this line */ + /**/ + 286, /**/ -- "I know that there are people who don't love their fellow man, and I hate those people!" - Tom Lehrer /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///