vim-patch:8.2.0381: using freed memory with :lvimgrep and autocommand

Problem:    Using freed memory with :lvimgrep and autocommand. (extracted from
            POC by Dominique Pelle)
Solution:   Avoid deleting a dummy buffer used in a window. (closes vim/vim#5777)
2573af3519
This commit is contained in:
Jan Edmund Lazo
2020-03-14 13:41:42 -04:00
parent e892dde369
commit 7ef2677ca6
2 changed files with 31 additions and 1 deletions

View File

@@ -5134,6 +5134,7 @@ theend:
// Restore current working directory to "dirname_start" if they differ, taking // Restore current working directory to "dirname_start" if they differ, taking
// into account whether it is set locally or globally. // into account whether it is set locally or globally.
static void restore_start_dir(char_u *dirname_start) static void restore_start_dir(char_u *dirname_start)
FUNC_ATTR_NONNULL_ALL
{ {
char_u *dirname_now = xmalloc(MAXPATHL); char_u *dirname_now = xmalloc(MAXPATHL);
@@ -5251,8 +5252,29 @@ load_dummy_buffer (
// directory to "dirname_start" prior to returning, if autocmds or the // directory to "dirname_start" prior to returning, if autocmds or the
// 'autochdir' option have changed it. // 'autochdir' option have changed it.
static void wipe_dummy_buffer(buf_T *buf, char_u *dirname_start) static void wipe_dummy_buffer(buf_T *buf, char_u *dirname_start)
FUNC_ATTR_NONNULL_ALL
{ {
if (curbuf != buf) { // safety check // If any autocommand opened a window on the dummy buffer, close that
// window. If we can't close them all then give up.
while (buf->b_nwindows > 0) {
bool did_one = false;
if (firstwin->w_next != NULL) {
for (win_T *wp = firstwin; wp != NULL; wp = wp->w_next) {
if (wp->w_buffer == buf) {
if (win_close(wp, false) == OK) {
did_one = true;
}
break;
}
}
}
if (!did_one) {
return;
}
}
if (curbuf != buf && buf->b_nwindows == 0) { // safety check
cleanup_T cs; cleanup_T cs;
// Reset the error/interrupt/exception state here so that aborting() // Reset the error/interrupt/exception state here so that aborting()

View File

@@ -3318,6 +3318,14 @@ func Test_lvimgrep_crash()
enew | only enew | only
endfunc endfunc
func Test_lvimgrep_crash2()
au BufNewFile x sfind
call assert_fails('lvimgrep x x', 'E480:')
call assert_fails('lvimgrep x x x', 'E480:')
au! BufNewFile
endfunc
" Test for the position of the quickfix and location list window " Test for the position of the quickfix and location list window
func Test_qfwin_pos() func Test_qfwin_pos()
" Open two windows " Open two windows