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:
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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.
|
||||||
|
@@ -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);
|
||||||
|
@@ -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.
|
||||||
|
@@ -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,
|
||||||
/**/
|
/**/
|
||||||
|
10
src/window.c
10
src/window.c
@@ -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.
|
||||||
|
Reference in New Issue
Block a user