mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
vim-patch:8.2.4739: accessing freed memory after WinScrolled autocmd event (#18090)
Problem: Accessing freed memory after WinScrolled autocmd event.
Solution: Check the window pointer is still valid. (closes vim/vim#10156)
Remove the argument from may_trigger_winscrolled().
d58862d18f
This commit is contained in:
parent
dbd5242d8e
commit
7e1e906738
@ -1545,7 +1545,7 @@ static void ins_redraw(bool ready)
|
||||
|
||||
if (ready) {
|
||||
// Trigger Scroll if viewport changed.
|
||||
may_trigger_winscrolled(curwin);
|
||||
may_trigger_winscrolled();
|
||||
}
|
||||
|
||||
// Trigger BufModified if b_changed_invalid is set.
|
||||
|
@ -1225,7 +1225,7 @@ static void normal_check_window_scrolled(NormalState *s)
|
||||
{
|
||||
if (!finish_op) {
|
||||
// Trigger Scroll if the viewport changed.
|
||||
may_trigger_winscrolled(curwin);
|
||||
may_trigger_winscrolled();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -315,6 +315,30 @@ func Test_WinScrolled()
|
||||
call delete('Xtest_winscrolled')
|
||||
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()
|
||||
" Test that the pattern is matched against the closed window's ID, and both
|
||||
" <amatch> and <afile> are set to it.
|
||||
|
@ -5246,8 +5246,8 @@ void shell_new_columns(void)
|
||||
win_reconfig_floats(); // The size of floats might change
|
||||
}
|
||||
|
||||
/// Trigger WinScrolled autocmd if window has scrolled.
|
||||
void may_trigger_winscrolled(win_T *wp)
|
||||
/// Trigger WinScrolled for "curwin" if needed.
|
||||
void may_trigger_winscrolled(void)
|
||||
{
|
||||
static bool recursive = false;
|
||||
|
||||
@ -5255,6 +5255,7 @@ void may_trigger_winscrolled(win_T *wp)
|
||||
return;
|
||||
}
|
||||
|
||||
win_T *wp = curwin;
|
||||
if (wp->w_last_topline != wp->w_topline
|
||||
|| wp->w_last_leftcol != wp->w_leftcol
|
||||
|| wp->w_last_width != wp->w_width
|
||||
@ -5266,12 +5267,15 @@ void may_trigger_winscrolled(win_T *wp)
|
||||
apply_autocmds(EVENT_WINSCROLLED, winid, winid, false, wp->w_buffer);
|
||||
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_leftcol = wp->w_leftcol;
|
||||
wp->w_last_width = wp->w_width;
|
||||
wp->w_last_height = wp->w_height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Save the size of all windows in "gap".
|
||||
|
@ -6,12 +6,14 @@ local eval = helpers.eval
|
||||
local command = helpers.command
|
||||
local feed = helpers.feed
|
||||
local meths = helpers.meths
|
||||
local assert_alive = helpers.assert_alive
|
||||
|
||||
before_each(clear)
|
||||
|
||||
describe('WinScrolled', function()
|
||||
local win_id
|
||||
|
||||
before_each(function()
|
||||
clear()
|
||||
win_id = meths.get_current_win().id
|
||||
command(string.format('autocmd WinScrolled %d let g:matched = v:true', win_id))
|
||||
command('let g:scrolled = 0')
|
||||
@ -72,3 +74,12 @@ describe('WinScrolled', function()
|
||||
eq(1, eval('g:scrolled'))
|
||||
end)
|
||||
end)
|
||||
|
||||
it('closing window in WinScrolled does not cause use-after-free #13265', function()
|
||||
local lines = {'aaa', 'bbb'}
|
||||
meths.buf_set_lines(0, 0, -1, true, lines)
|
||||
command('vsplit')
|
||||
command('autocmd WinScrolled * close')
|
||||
feed('<C-E>')
|
||||
assert_alive()
|
||||
end)
|
||||
|
Loading…
Reference in New Issue
Block a user