diff options
author | Sean Dewar <seandewar@users.noreply.github.com> | 2021-10-03 03:10:59 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-02 19:10:59 -0700 |
commit | 0c06da1f0a0ebe45c92d2c1d63121c6ead604fe5 (patch) | |
tree | 9bbf5216964cf9ef451a00562cbfb29c37129667 /src/nvim/api/vim.c | |
parent | ad1c42a97d673b9fd2bf64b2382c87fbe65dfc73 (diff) | |
download | rneovim-0c06da1f0a0ebe45c92d2c1d63121c6ead604fe5.tar.gz rneovim-0c06da1f0a0ebe45c92d2c1d63121c6ead604fe5.tar.bz2 rneovim-0c06da1f0a0ebe45c92d2c1d63121c6ead604fe5.zip |
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 1def3d1542d6a65f057e743faea39a760b50db87.
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
Diffstat (limited to 'src/nvim/api/vim.c')
-rw-r--r-- | src/nvim/api/vim.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 8e0502e03b..e2d7c03307 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -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); |