commit 14d65dae91b108af8789cd04012437e260766555
parent 6ebeb07c561432b59f65a380a943e198d59ce348
Author: zeertzjq <zeertzjq@outlook.com>
Date: Mon, 1 Dec 2025 09:14:14 +0800
fix(buffer): don't allow changedtick watcher to delete buffer (#36764)
Diffstat:
2 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
@@ -4178,10 +4178,12 @@ void buf_set_changedtick(buf_T *const buf, const varnumber_T changedtick)
buf->changedtick_di.di_tv.vval.v_number = changedtick;
if (tv_dict_is_watched(buf->b_vars)) {
+ buf->b_locked++;
tv_dict_watcher_notify(buf->b_vars,
(char *)buf->changedtick_di.di_key,
&buf->changedtick_di.di_tv,
&old_val);
+ buf->b_locked--;
}
}
diff --git a/test/functional/ex_cmds/dict_notifications_spec.lua b/test/functional/ex_cmds/dict_notifications_spec.lua
@@ -428,6 +428,11 @@ describe('Vimscript dictionary notifications', function()
command([[call dictwatcherdel(b:, 'changedtick', 'OnTickChanged')]])
insert('t')
assert_alive()
+
+ command([[call dictwatcheradd(b:, 'changedtick', {-> execute('bwipe!')})]])
+ insert('t')
+ eq('E937: Attempt to delete a buffer that is in use: [No Name]', api.nvim_get_vvar('errmsg'))
+ assert_alive()
end)
it('does not cause use-after-free when unletting from callback', function()