0
0
mirror of https://github.com/vim/vim.git synced 2025-09-27 04:14:06 -04:00

patch 8.2.4739: accessing freed memory after WinScrolled autocmd event

Problem:    Accessing freed memory after WinScrolled autocmd event.
Solution:   Check the window pointer is still valid. (closes #10156)
            Remove the argument from may_trigger_winscrolled().
This commit is contained in:
zeertzjq
2022-04-12 11:32:48 +01:00
committed by Bram Moolenaar
parent 11a57dfd16
commit d58862d18f
7 changed files with 54 additions and 20 deletions

View File

@@ -1528,7 +1528,7 @@ ins_redraw(int ready) // not busy with something
} }
if (ready) if (ready)
may_trigger_winscrolled(curwin); may_trigger_winscrolled();
// Trigger SafeState if nothing is pending. // Trigger SafeState if nothing is pending.
may_trigger_safestate(ready may_trigger_safestate(ready

View File

@@ -5238,7 +5238,7 @@ gui_update_screen(void)
} }
if (!finish_op) if (!finish_op)
may_trigger_winscrolled(curwin); may_trigger_winscrolled();
# ifdef FEAT_CONCEAL # ifdef FEAT_CONCEAL
if (conceal_update_lines if (conceal_update_lines

View File

@@ -1342,7 +1342,7 @@ main_loop(
validate_cursor(); validate_cursor();
if (!finish_op) if (!finish_op)
may_trigger_winscrolled(curwin); may_trigger_winscrolled();
// If nothing is pending and we are going to wait for the user to // If nothing is pending and we are going to wait for the user to
// type a character, trigger SafeState. // type a character, trigger SafeState.

View File

@@ -17,7 +17,7 @@ void curwin_init(void);
void close_windows(buf_T *buf, int keep_curwin); void close_windows(buf_T *buf, int keep_curwin);
int one_window(void); int one_window(void);
int win_close(win_T *win, int free_buf); int win_close(win_T *win, int free_buf);
void may_trigger_winscrolled(win_T *wp); void may_trigger_winscrolled(void);
void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp); void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp);
void win_free_all(void); void win_free_all(void);
win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp); win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp);

View File

@@ -364,6 +364,30 @@ func Test_WinScrolled()
call delete('Xtest_winscrolled') call delete('Xtest_winscrolled')
endfunc endfunc
func Test_WinScrolled_close_curwin()
CheckRunVimInTerminal
let lines =<< trim END
set nowrap scrolloff=0
call setline(1, ['aaa', 'bbb'])
vsplit
au WinScrolled * close
au VimLeave * call writefile(['123456'], 'Xtestout')
END
call writefile(lines, 'Xtest_winscrolled_close_curwin')
let buf = RunVimInTerminal('-S Xtest_winscrolled_close_curwin', {'rows': 6})
" This was using freed memory
call term_sendkeys(buf, "\<C-E>")
call TermWait(buf)
call StopVimInTerminal(buf)
call assert_equal(['123456'], readfile('Xtestout'))
call delete('Xtest_winscrolled_close_curwin')
call delete('Xtestout')
endfunc
func Test_WinClosed() func Test_WinClosed()
" Test that the pattern is matched against the closed window's ID, and both " Test that the pattern is matched against the closed window's ID, and both
" <amatch> and <afile> are set to it. " <amatch> and <afile> are set to it.

View File

@@ -746,6 +746,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
4739,
/**/ /**/
4738, 4738,
/**/ /**/

View File

@@ -2784,9 +2784,13 @@ trigger_winclosed(win_T *win)
recursive = FALSE; recursive = FALSE;
} }
/*
* Trigger WinScrolled for "curwin" if needed.
*/
void void
may_trigger_winscrolled(win_T *wp) may_trigger_winscrolled(void)
{ {
win_T *wp = curwin;
static int recursive = FALSE; static int recursive = FALSE;
char_u winid[NUMBUFLEN]; char_u winid[NUMBUFLEN];
@@ -2804,12 +2808,16 @@ may_trigger_winscrolled(win_T *wp)
apply_autocmds(EVENT_WINSCROLLED, winid, winid, FALSE, wp->w_buffer); apply_autocmds(EVENT_WINSCROLLED, winid, winid, FALSE, wp->w_buffer);
recursive = FALSE; recursive = FALSE;
// an autocmd may close the window, "wp" may be invalid now
if (win_valid_any_tab(wp))
{
wp->w_last_topline = wp->w_topline; wp->w_last_topline = wp->w_topline;
wp->w_last_leftcol = wp->w_leftcol; wp->w_last_leftcol = wp->w_leftcol;
wp->w_last_width = wp->w_width; wp->w_last_width = wp->w_width;
wp->w_last_height = wp->w_height; wp->w_last_height = wp->w_height;
} }
} }
}
/* /*
* Close window "win" in tab page "tp", which is not the current tab page. * Close window "win" in tab page "tp", which is not the current tab page.