Mercurial > vim
comparison src/quickfix.c @ 22256:c3c9830c7cdc v8.2.1677
patch 8.2.1677: memory access errors when calling setloclist() in autocommand
Commit: https://github.com/vim/vim/commit/4d170af0a9379da64d67dc3fa7cc7297956c6f52
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Sep 13 22:21:22 2020 +0200
patch 8.2.1677: memory access errors when calling setloclist() in autocommand
Problem: Memory access errors when calling setloclist() in an autocommand.
Solution: Give an error if the list was changed unexpectedly. (closes https://github.com/vim/vim/issues/6946)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 13 Sep 2020 22:30:03 +0200 |
parents | faaf88167b58 |
children | 849c6f766b19 |
comparison
equal
deleted
inserted
replaced
22255:8b74d01f1dd6 | 22256:c3c9830c7cdc |
---|---|
214 * to make this a lot faster if there are multiple matches in the same file. | 214 * to make this a lot faster if there are multiple matches in the same file. |
215 */ | 215 */ |
216 static char_u *qf_last_bufname = NULL; | 216 static char_u *qf_last_bufname = NULL; |
217 static bufref_T qf_last_bufref = {NULL, 0, 0}; | 217 static bufref_T qf_last_bufref = {NULL, 0, 0}; |
218 | 218 |
219 static char *e_loc_list_changed = | 219 static char *e_current_quickfix_list_was_changed = |
220 N_("E925: Current quickfix list was changed"); | |
221 static char *e_current_location_list_was_changed = | |
220 N_("E926: Current location list was changed"); | 222 N_("E926: Current location list was changed"); |
221 | 223 |
222 /* | 224 /* |
223 * Maximum number of bytes allowed per line while reading a errorfile. | 225 * Maximum number of bytes allowed per line while reading a errorfile. |
224 */ | 226 */ |
3106 int forceit, | 3108 int forceit, |
3107 int prev_winid, | 3109 int prev_winid, |
3108 int *opened_window) | 3110 int *opened_window) |
3109 { | 3111 { |
3110 qf_list_T *qfl = qf_get_curlist(qi); | 3112 qf_list_T *qfl = qf_get_curlist(qi); |
3113 int old_changedtick = qfl->qf_changedtick; | |
3111 qfltype_T qfl_type = qfl->qfl_type; | 3114 qfltype_T qfl_type = qfl->qfl_type; |
3112 int retval = OK; | 3115 int retval = OK; |
3113 int old_qf_curlist = qi->qf_curlist; | 3116 int old_qf_curlist = qi->qf_curlist; |
3114 int save_qfid = qfl->qf_id; | 3117 int save_qfid = qfl->qf_id; |
3115 | 3118 |
3144 } | 3147 } |
3145 } | 3148 } |
3146 | 3149 |
3147 if (qfl_type == QFLT_QUICKFIX && !qflist_valid(NULL, save_qfid)) | 3150 if (qfl_type == QFLT_QUICKFIX && !qflist_valid(NULL, save_qfid)) |
3148 { | 3151 { |
3149 emsg(_("E925: Current quickfix was changed")); | 3152 emsg(_(e_current_quickfix_list_was_changed)); |
3150 return NOTDONE; | 3153 return NOTDONE; |
3151 } | 3154 } |
3152 | 3155 |
3156 // Check if the list was changed. The pointers may happen to be identical, | |
3157 // thus also check qf_changedtick. | |
3153 if (old_qf_curlist != qi->qf_curlist | 3158 if (old_qf_curlist != qi->qf_curlist |
3159 || old_changedtick != qfl->qf_changedtick | |
3154 || !is_qf_entry_present(qfl, qf_ptr)) | 3160 || !is_qf_entry_present(qfl, qf_ptr)) |
3155 { | 3161 { |
3156 if (qfl_type == QFLT_QUICKFIX) | 3162 if (qfl_type == QFLT_QUICKFIX) |
3157 emsg(_("E925: Current quickfix was changed")); | 3163 emsg(_(e_current_quickfix_list_was_changed)); |
3158 else | 3164 else |
3159 emsg(_(e_loc_list_changed)); | 3165 emsg(_(e_current_location_list_was_changed)); |
3160 return NOTDONE; | 3166 return NOTDONE; |
3161 } | 3167 } |
3162 | 3168 |
3163 return retval; | 3169 return retval; |
3164 } | 3170 } |
3262 qf_info_T *qi, | 3268 qf_info_T *qi, |
3263 qfline_T *qf_ptr, | 3269 qfline_T *qf_ptr, |
3264 int newwin, | 3270 int newwin, |
3265 int *opened_window) | 3271 int *opened_window) |
3266 { | 3272 { |
3273 qf_list_T *qfl = qf_get_curlist(qi); | |
3274 int old_changedtick = qfl->qf_changedtick; | |
3275 int old_qf_curlist = qi->qf_curlist; | |
3276 qfltype_T qfl_type = qfl->qfl_type; | |
3277 | |
3267 // For ":helpgrep" find a help window or open one. | 3278 // For ":helpgrep" find a help window or open one. |
3268 if (qf_ptr->qf_type == 1 && (!bt_help(curwin->w_buffer) || cmdmod.tab != 0)) | 3279 if (qf_ptr->qf_type == 1 && (!bt_help(curwin->w_buffer) || cmdmod.tab != 0)) |
3269 if (jump_to_help_window(qi, newwin, opened_window) == FAIL) | 3280 if (jump_to_help_window(qi, newwin, opened_window) == FAIL) |
3270 return FAIL; | 3281 return FAIL; |
3282 if (old_qf_curlist != qi->qf_curlist | |
3283 || old_changedtick != qfl->qf_changedtick | |
3284 || !is_qf_entry_present(qfl, qf_ptr)) | |
3285 { | |
3286 if (qfl_type == QFLT_QUICKFIX) | |
3287 emsg(_(e_current_quickfix_list_was_changed)); | |
3288 else | |
3289 emsg(_(e_current_location_list_was_changed)); | |
3290 return FAIL; | |
3291 } | |
3271 | 3292 |
3272 // If currently in the quickfix window, find another window to show the | 3293 // If currently in the quickfix window, find another window to show the |
3273 // file in. | 3294 // file in. |
3274 if (bt_quickfix(curbuf) && !*opened_window) | 3295 if (bt_quickfix(curbuf) && !*opened_window) |
3275 { | 3296 { |
3279 return NOTDONE; | 3300 return NOTDONE; |
3280 | 3301 |
3281 if (qf_jump_to_usable_window(qf_ptr->qf_fnum, newwin, | 3302 if (qf_jump_to_usable_window(qf_ptr->qf_fnum, newwin, |
3282 opened_window) == FAIL) | 3303 opened_window) == FAIL) |
3283 return FAIL; | 3304 return FAIL; |
3305 } | |
3306 if (old_qf_curlist != qi->qf_curlist | |
3307 || old_changedtick != qfl->qf_changedtick | |
3308 || !is_qf_entry_present(qfl, qf_ptr)) | |
3309 { | |
3310 if (qfl_type == QFLT_QUICKFIX) | |
3311 emsg(_(e_current_quickfix_list_was_changed)); | |
3312 else | |
3313 emsg(_(e_current_location_list_was_changed)); | |
3314 return FAIL; | |
3284 } | 3315 } |
3285 | 3316 |
3286 return OK; | 3317 return OK; |
3287 } | 3318 } |
3288 | 3319 |
5832 if (!qflist_valid(wp, qfid)) | 5863 if (!qflist_valid(wp, qfid)) |
5833 { | 5864 { |
5834 if (wp != NULL) | 5865 if (wp != NULL) |
5835 { | 5866 { |
5836 // An autocmd has freed the location list. | 5867 // An autocmd has freed the location list. |
5837 emsg(_(e_loc_list_changed)); | 5868 emsg(_(e_current_location_list_was_changed)); |
5838 return FALSE; | 5869 return FALSE; |
5839 } | 5870 } |
5840 else | 5871 else |
5841 { | 5872 { |
5842 // Quickfix list is not found, create a new one. | 5873 // Quickfix list is not found, create a new one. |