mirror of
https://github.com/neovim/neovim.git
synced 2024-12-19 18:55:14 -07:00
fix(nvim_open_win): crash if autocmds delete buffer/window #15549
win_set_buf can trigger autocmds if noautocmd=false. If they close the window,
code afterwards will dereference the freed win_T* wp pointer.
This interaction became possible after commit 1def3d1542
.
The reason deleting curbuf crashes, and not the buf passed to
`nvim_open_win`, is because the float initially edits curbuf (`win_init`)
until it's later set to edit buf (windows from `:new` and `:split <buf>`
behave similiarly: approx. `:split`, then `:buffer <buf>`).
`do_buffer` closes windows when their edited buffer is deleted (unless
it's the only window; N/A for floats), so the float closes when curbuf
is deleted, so we need to check `win_valid` after `win_set_buf` too.
Closes #15548
This commit is contained in:
parent
ad1c42a97d
commit
0c06da1f0a
@ -1439,13 +1439,14 @@ Window nvim_open_win(Buffer buffer, Boolean enter, Dictionary config, Error *err
|
||||
if (enter) {
|
||||
win_enter(wp, false);
|
||||
}
|
||||
// autocmds in win_enter or win_set_buf below may close the window
|
||||
if (win_valid(wp) && buffer > 0) {
|
||||
win_set_buf(wp->handle, buffer, fconfig.noautocmd, err);
|
||||
}
|
||||
if (!win_valid(wp)) {
|
||||
api_set_error(err, kErrorTypeException, "Window was closed immediately");
|
||||
return 0;
|
||||
}
|
||||
if (buffer > 0) {
|
||||
win_set_buf(wp->handle, buffer, fconfig.noautocmd, err);
|
||||
}
|
||||
|
||||
if (fconfig.style == kWinStyleMinimal) {
|
||||
win_set_minimal_style(wp);
|
||||
|
@ -109,6 +109,21 @@ describe('float window', function()
|
||||
assert_alive()
|
||||
end)
|
||||
|
||||
it('closed immediately by autocmd after win_enter #15548', function()
|
||||
eq('Error executing lua: [string "<nvim>"]:0: Window was closed immediately',
|
||||
pcall_err(exec_lua, [[
|
||||
vim.cmd "autocmd BufLeave * ++once quit!"
|
||||
local buf = vim.api.nvim_create_buf(true, true)
|
||||
vim.api.nvim_open_win(buf, true, {
|
||||
relative = "win",
|
||||
row = 0, col = 0,
|
||||
width = 1, height = 1,
|
||||
noautocmd = false,
|
||||
})
|
||||
]]))
|
||||
assert_alive()
|
||||
end)
|
||||
|
||||
it('opened with correct height', function()
|
||||
local height = exec_lua([[
|
||||
vim.api.nvim_set_option("winheight", 20)
|
||||
|
Loading…
Reference in New Issue
Block a user