diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-09-13 22:21:22 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-09-13 22:21:22 +0200 |
commit | 4d170af0a9379da64d67dc3fa7cc7297956c6f52 (patch) | |
tree | eddc5d4efafaafd4e62e2181cf171f7bd387fdd4 /src | |
parent | a4224860a498eb870280130e00fe6f376b7a2e6b (diff) |
patch 8.2.1677: memory access errors when calling setloclist() in autocommandv8.2.1677
Problem: Memory access errors when calling setloclist() in an autocommand.
Solution: Give an error if the list was changed unexpectedly. (closes #6946)
Diffstat (limited to 'src')
-rw-r--r-- | src/quickfix.c | 41 | ||||
-rw-r--r-- | src/testdir/test_quickfix.vim | 24 | ||||
-rw-r--r-- | src/version.c | 2 |
3 files changed, 62 insertions, 5 deletions
diff --git a/src/quickfix.c b/src/quickfix.c index c8858b456e..43d2d3fbd5 100644 --- a/src/quickfix.c +++ b/src/quickfix.c @@ -216,7 +216,9 @@ static char_u *e_no_more_items = (char_u *)N_("E553: No more items"); static char_u *qf_last_bufname = NULL; static bufref_T qf_last_bufref = {NULL, 0, 0}; -static char *e_loc_list_changed = +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,6 +3110,7 @@ qf_jump_edit_buffer( 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,17 +3149,20 @@ qf_jump_edit_buffer( if (qfl_type == QFLT_QUICKFIX && !qflist_valid(NULL, save_qfid)) { - emsg(_("E925: Current quickfix was changed")); + 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(_("E925: Current quickfix was changed")); + emsg(_(e_current_quickfix_list_was_changed)); else - emsg(_(e_loc_list_changed)); + emsg(_(e_current_location_list_was_changed)); return NOTDONE; } @@ -3264,10 +3270,25 @@ qf_jump_open_window( 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,6 +3303,16 @@ qf_jump_open_window( 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,7 +5865,7 @@ vgr_qflist_valid( if (wp != NULL) { // An autocmd has freed the location list. - emsg(_(e_loc_list_changed)); + emsg(_(e_current_location_list_was_changed)); return FALSE; } else diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim index 1e753a467c..0d8e35538b 100644 --- a/src/testdir/test_quickfix.vim +++ b/src/testdir/test_quickfix.vim @@ -1430,6 +1430,30 @@ func Test_quickfix_was_changed_by_autocmd() 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\<CR>"', 'E926:') + + augroup Test_LocList + au! + augroup END + call delete('Xfile') +endfunc + func Test_caddbuffer_to_empty() helpgr quickfix call setqflist([], 'r') diff --git a/src/version.c b/src/version.c index b8891ff667..0d0ea4dd84 100644 --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1677, +/**/ 1676, /**/ 1675, |