To: vim_dev@googlegroups.com Subject: Patch 8.2.1677 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.1677 Problem: Memory access errors when calling setloclist() in an autocommand. Solution: Give an error if the list was changed unexpectedly. (closes #6946) Files: src/quickfix.c, src/testdir/test_quickfix.vim *** ../vim-8.2.1676/src/quickfix.c 2020-09-05 22:37:35.729976483 +0200 --- src/quickfix.c 2020-09-13 22:20:49.039109164 +0200 *************** *** 216,222 **** static char_u *qf_last_bufname = NULL; static bufref_T qf_last_bufref = {NULL, 0, 0}; ! static char *e_loc_list_changed = N_("E926: Current location list was changed"); /* --- 216,224 ---- static char_u *qf_last_bufname = NULL; static bufref_T qf_last_bufref = {NULL, 0, 0}; ! static char *e_current_quickfix_list_was_changed = ! N_("E925: Current quickfix list was changed"); ! static char *e_current_location_list_was_changed = N_("E926: Current location list was changed"); /* *************** *** 3108,3113 **** --- 3110,3116 ---- int *opened_window) { qf_list_T *qfl = qf_get_curlist(qi); + int old_changedtick = qfl->qf_changedtick; qfltype_T qfl_type = qfl->qfl_type; int retval = OK; int old_qf_curlist = qi->qf_curlist; *************** *** 3146,3162 **** if (qfl_type == QFLT_QUICKFIX && !qflist_valid(NULL, save_qfid)) { ! emsg(_("E925: Current quickfix was changed")); return NOTDONE; } if (old_qf_curlist != qi->qf_curlist || !is_qf_entry_present(qfl, qf_ptr)) { if (qfl_type == QFLT_QUICKFIX) ! emsg(_("E925: Current quickfix was changed")); else ! emsg(_(e_loc_list_changed)); return NOTDONE; } --- 3149,3168 ---- 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, + // thus also check qf_changedtick. if (old_qf_curlist != qi->qf_curlist + || old_changedtick != qfl->qf_changedtick || !is_qf_entry_present(qfl, qf_ptr)) { if (qfl_type == QFLT_QUICKFIX) ! emsg(_(e_current_quickfix_list_was_changed)); else ! emsg(_(e_current_location_list_was_changed)); return NOTDONE; } *************** *** 3264,3273 **** --- 3270,3294 ---- int newwin, int *opened_window) { + qf_list_T *qfl = qf_get_curlist(qi); + int old_changedtick = qfl->qf_changedtick; + int old_qf_curlist = qi->qf_curlist; + qfltype_T qfl_type = qfl->qfl_type; + // For ":helpgrep" find a help window or open one. if (qf_ptr->qf_type == 1 && (!bt_help(curwin->w_buffer) || cmdmod.tab != 0)) if (jump_to_help_window(qi, newwin, opened_window) == FAIL) return FAIL; + if (old_qf_curlist != qi->qf_curlist + || old_changedtick != qfl->qf_changedtick + || !is_qf_entry_present(qfl, qf_ptr)) + { + if (qfl_type == QFLT_QUICKFIX) + 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 // file in. *************** *** 3282,3287 **** --- 3303,3318 ---- opened_window) == FAIL) return FAIL; } + if (old_qf_curlist != qi->qf_curlist + || old_changedtick != qfl->qf_changedtick + || !is_qf_entry_present(qfl, qf_ptr)) + { + if (qfl_type == QFLT_QUICKFIX) + emsg(_(e_current_quickfix_list_was_changed)); + else + emsg(_(e_current_location_list_was_changed)); + return FAIL; + } return OK; } *************** *** 5834,5840 **** if (wp != NULL) { // An autocmd has freed the location list. ! emsg(_(e_loc_list_changed)); return FALSE; } else --- 5865,5871 ---- if (wp != NULL) { // An autocmd has freed the location list. ! emsg(_(e_current_location_list_was_changed)); return FALSE; } else *** ../vim-8.2.1676/src/testdir/test_quickfix.vim 2020-09-05 17:03:31.923261682 +0200 --- src/testdir/test_quickfix.vim 2020-09-13 22:08:55.409526770 +0200 *************** *** 1430,1435 **** --- 1430,1459 ---- call XquickfixChangedByAutocmd('l') endfunc + func Test_setloclist_in_autocommand() + call writefile(['test1', 'test2'], 'Xfile') + edit Xfile + let s:bufnr = bufnr() + call setloclist(1, + \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'}, + \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}]) + + augroup Test_LocList + au! + autocmd BufEnter * call setloclist(1, + \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'}, + \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}], 'r') + augroup END + + lopen + call assert_fails('exe "normal j\"', 'E926:') + + augroup Test_LocList + au! + augroup END + call delete('Xfile') + endfunc + func Test_caddbuffer_to_empty() helpgr quickfix call setqflist([], 'r') *** ../vim-8.2.1676/src/version.c 2020-09-13 22:00:08.983392136 +0200 --- src/version.c 2020-09-13 22:20:58.299078122 +0200 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 1677, /**/ -- Zen Microsystems: we're the om in .commmmmmmmm /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///