mirror of
https://github.com/neovim/neovim.git
synced 2024-12-19 18:55:14 -07:00
Merge pull request #20299 from zeertzjq/vim-9.0.0550
vim-patch:9.0.0550: crash when closing a tabpage and buffer is NULL
This commit is contained in:
commit
9aead1f670
@ -4696,7 +4696,6 @@ void tabpage_close(int forceit)
|
||||
void tabpage_close_other(tabpage_T *tp, int forceit)
|
||||
{
|
||||
int done = 0;
|
||||
int h = tabline_height();
|
||||
char prev_idx[NUMBUFLEN];
|
||||
|
||||
// Limit to 1000 windows, autocommands may add a window while we close
|
||||
@ -4712,11 +4711,6 @@ void tabpage_close_other(tabpage_T *tp, int forceit)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
redraw_tabline = true;
|
||||
if (h != tabline_height()) {
|
||||
win_new_screen_rows();
|
||||
}
|
||||
}
|
||||
|
||||
/// ":only".
|
||||
|
@ -447,6 +447,26 @@ func Test_WinClosed_throws_with_tabs()
|
||||
augroup! test-WinClosed
|
||||
endfunc
|
||||
|
||||
" This used to trigger WinClosed twice for the same window, and the window's
|
||||
" buffer was NULL in the second autocommand.
|
||||
func Test_WinClosed_switch_tab()
|
||||
edit Xa
|
||||
split Xb
|
||||
split Xc
|
||||
tab split
|
||||
new
|
||||
augroup test-WinClosed
|
||||
autocmd WinClosed * tabprev | bwipe!
|
||||
augroup END
|
||||
close
|
||||
" Check that the tabline has been fully removed
|
||||
call assert_equal([1, 1], win_screenpos(0))
|
||||
|
||||
autocmd! test-WinClosed
|
||||
augroup! test-WinClosed
|
||||
%bwipe!
|
||||
endfunc
|
||||
|
||||
func s:AddAnAutocmd()
|
||||
augroup vimBarTest
|
||||
au BufReadCmd * echo 'hello'
|
||||
|
@ -2439,7 +2439,6 @@ void curwin_init(void)
|
||||
void close_windows(buf_T *buf, bool keep_curwin)
|
||||
{
|
||||
tabpage_T *tp, *nexttp;
|
||||
int h = tabline_height();
|
||||
|
||||
RedrawingDisabled++;
|
||||
|
||||
@ -2480,11 +2479,6 @@ void close_windows(buf_T *buf, bool keep_curwin)
|
||||
}
|
||||
|
||||
RedrawingDisabled--;
|
||||
|
||||
redraw_tabline = true;
|
||||
if (h != tabline_height()) {
|
||||
win_new_screen_rows();
|
||||
}
|
||||
}
|
||||
|
||||
/// Check that the specified window is the last one.
|
||||
@ -2575,7 +2569,6 @@ static bool close_last_window_tabpage(win_T *win, bool free_buf, tabpage_T *prev
|
||||
// Don't trigger autocommands yet, they may use wrong values, so do
|
||||
// that below.
|
||||
goto_tabpage_tp(alt_tabpage(), false, true);
|
||||
redraw_tabline = true;
|
||||
|
||||
// save index for tabclosed event
|
||||
char_u prev_idx[NUMBUFLEN];
|
||||
@ -2584,12 +2577,7 @@ static bool close_last_window_tabpage(win_T *win, bool free_buf, tabpage_T *prev
|
||||
// Safety check: Autocommands may have closed the window when jumping
|
||||
// to the other tab page.
|
||||
if (valid_tabpage(prev_curtab) && prev_curtab->tp_firstwin == win) {
|
||||
int h = tabline_height();
|
||||
|
||||
win_close_othertab(win, free_buf, prev_curtab);
|
||||
if (h != tabline_height()) {
|
||||
win_new_screen_rows();
|
||||
}
|
||||
}
|
||||
entering_window(curwin);
|
||||
|
||||
@ -2793,7 +2781,10 @@ int win_close(win_T *win, bool free_buf, bool force)
|
||||
if (curtab != prev_curtab && win_valid_any_tab(win)
|
||||
&& win->w_buffer == NULL) {
|
||||
// Need to close the window anyway, since the buffer is NULL.
|
||||
// Don't trigger autocmds with a NULL buffer.
|
||||
block_autocmds();
|
||||
win_close_othertab(win, false, prev_curtab);
|
||||
unblock_autocmds();
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
@ -2990,6 +2981,8 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp)
|
||||
vim_snprintf(prev_idx, NUMBUFLEN, "%i", tabpage_index(tp));
|
||||
}
|
||||
|
||||
int h = tabline_height();
|
||||
|
||||
if (tp == first_tabpage) {
|
||||
first_tabpage = tp->tp_next;
|
||||
} else {
|
||||
@ -3004,6 +2997,10 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp)
|
||||
ptp->tp_next = tp->tp_next;
|
||||
}
|
||||
free_tp = true;
|
||||
redraw_tabline = true;
|
||||
if (h != tabline_height()) {
|
||||
win_new_screen_rows();
|
||||
}
|
||||
|
||||
if (has_event(EVENT_TABCLOSED)) {
|
||||
apply_autocmds(EVENT_TABCLOSED, prev_idx, prev_idx, false, win->w_buffer);
|
||||
|
@ -9,6 +9,9 @@ local feed = helpers.feed
|
||||
local eval = helpers.eval
|
||||
local exec = helpers.exec
|
||||
local funcs = helpers.funcs
|
||||
local meths = helpers.meths
|
||||
local curwin = helpers.curwin
|
||||
local assert_alive = helpers.assert_alive
|
||||
|
||||
describe('tabpage', function()
|
||||
before_each(clear)
|
||||
@ -54,6 +57,45 @@ describe('tabpage', function()
|
||||
neq(999, eval('g:win_closed'))
|
||||
end)
|
||||
|
||||
it('no segfault with strange WinClosed autocommand #20290', function()
|
||||
pcall(exec, [[
|
||||
set nohidden
|
||||
edit Xa
|
||||
split Xb
|
||||
tab split
|
||||
new
|
||||
autocmd WinClosed * tabprev | bwipe!
|
||||
close
|
||||
]])
|
||||
assert_alive()
|
||||
end)
|
||||
|
||||
it('nvim_win_close and nvim_win_hide update tabline #20285', function()
|
||||
eq(1, #meths.list_tabpages())
|
||||
eq({1, 1}, funcs.win_screenpos(0))
|
||||
local win1 = curwin().id
|
||||
|
||||
command('tabnew')
|
||||
eq(2, #meths.list_tabpages())
|
||||
eq({2, 1}, funcs.win_screenpos(0))
|
||||
local win2 = curwin().id
|
||||
|
||||
meths.win_close(win1, true)
|
||||
eq(win2, curwin().id)
|
||||
eq(1, #meths.list_tabpages())
|
||||
eq({1, 1}, funcs.win_screenpos(0))
|
||||
|
||||
command('tabnew')
|
||||
eq(2, #meths.list_tabpages())
|
||||
eq({2, 1}, funcs.win_screenpos(0))
|
||||
local win3 = curwin().id
|
||||
|
||||
meths.win_close(win2, true)
|
||||
eq(win3, curwin().id)
|
||||
eq(1, #meths.list_tabpages())
|
||||
eq({1, 1}, funcs.win_screenpos(0))
|
||||
end)
|
||||
|
||||
it('switching tabpage after setting laststatus=3 #19591', function()
|
||||
local screen = Screen.new(40, 8)
|
||||
screen:set_default_attr_ids({
|
||||
|
@ -4,6 +4,7 @@ local assert_alive = helpers.assert_alive
|
||||
local feed, clear, nvim = helpers.feed, helpers.clear, helpers.nvim
|
||||
local poke_eventloop = helpers.poke_eventloop
|
||||
local eval, feed_command, source = helpers.eval, helpers.feed_command, helpers.source
|
||||
local pcall_err = helpers.pcall_err
|
||||
local eq, neq = helpers.eq, helpers.neq
|
||||
local meths = helpers.meths
|
||||
local retry = helpers.retry
|
||||
@ -339,6 +340,11 @@ describe(':terminal buffer', function()
|
||||
]]}
|
||||
eq('t', funcs.mode(1))
|
||||
end)
|
||||
|
||||
it('writing to an existing file with :w fails #13549', function()
|
||||
eq('Vim(write):E13: File exists (add ! to override)',
|
||||
pcall_err(command, 'write test/functional/fixtures/tty-test.c'))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('No heap-buffer-overflow when using', function()
|
||||
|
Loading…
Reference in New Issue
Block a user