aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2022-06-13 06:02:00 +0800
committerGitHub <noreply@github.com>2022-06-12 15:02:00 -0700
commit429c40cce3fce3b5391afef8208d65a80a316018 (patch)
treef468e6244bc01662180306904c0c008999713d22
parentfeba56af7d032c948a78c21735502bebe45f8361 (diff)
downloadrneovim-429c40cce3fce3b5391afef8208d65a80a316018.tar.gz
rneovim-429c40cce3fce3b5391afef8208d65a80a316018.tar.bz2
rneovim-429c40cce3fce3b5391afef8208d65a80a316018.zip
fix(buffer): disable buffer-updates before removing from window #18933
There can be other places that access window buffer info (e.g. `tabpagebuflist()`), so checking `w_closing` in `win_findbuf()` doesn't solve the crash in all cases, and may also cause Nvim's behavior to diverge from Vim. Fix #14998
-rw-r--r--src/nvim/buffer.c8
-rw-r--r--src/nvim/window.c2
-rw-r--r--test/functional/lua/buffer_updates_spec.lua11
3 files changed, 13 insertions, 8 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 4c3f1308b3..921cd20943 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -575,6 +575,10 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i
return false;
}
+ // Disable buffer-updates for the current buffer.
+ // No need to check `unload_buf`: in that case the function returned above.
+ buf_updates_unload(buf, false);
+
if (win != NULL // Avoid bogus clang warning.
&& win_valid_any_tab(win)
&& win->w_buffer == buf) {
@@ -587,10 +591,6 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i
buf->b_nwindows--;
}
- // Disable buffer-updates for the current buffer.
- // No need to check `unload_buf`: in that case the function returned above.
- buf_updates_unload(buf, false);
-
// Remove the buffer from the list.
if (wipe_buf) {
// Do not wipe out the buffer if it is used in a window.
diff --git a/src/nvim/window.c b/src/nvim/window.c
index f429c493a7..e09a7cd97e 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -7297,7 +7297,7 @@ void win_findbuf(typval_T *argvars, list_T *list)
int bufnr = tv_get_number(&argvars[0]);
FOR_ALL_TAB_WINDOWS(tp, wp) {
- if (!wp->w_closing && wp->w_buffer->b_fnum == bufnr) {
+ if (wp->w_buffer->b_fnum == bufnr) {
tv_list_append_number(list, wp->handle);
}
}
diff --git a/test/functional/lua/buffer_updates_spec.lua b/test/functional/lua/buffer_updates_spec.lua
index cbd78ccd53..f32274468a 100644
--- a/test/functional/lua/buffer_updates_spec.lua
+++ b/test/functional/lua/buffer_updates_spec.lua
@@ -252,9 +252,8 @@ describe('lua buffer event callbacks: on_lines', function()
eq(2, meths.win_get_cursor(0)[1])
end)
- it('does not SEGFAULT when calling win_findbuf in on_detach', function()
-
- exec_lua[[
+ it('does not SEGFAULT when accessing window buffer info in on_detach #14998', function()
+ local code = [[
local buf = vim.api.nvim_create_buf(false, false)
vim.cmd"split"
@@ -262,13 +261,19 @@ describe('lua buffer event callbacks: on_lines', function()
vim.api.nvim_buf_attach(buf, false, {
on_detach = function(_, buf)
+ vim.fn.tabpagebuflist()
vim.fn.win_findbuf(buf)
end
})
]]
+ exec_lua(code)
command("q!")
helpers.assert_alive()
+
+ exec_lua(code)
+ command("bd!")
+ helpers.assert_alive()
end)
it('#12718 lnume', function()