fix(buffer): don't allow changedtick watcher to delete buffer (#36764)

(cherry picked from commit 14d65dae91)
This commit is contained in:
zeertzjq
2025-12-01 09:14:14 +08:00
committed by github-actions[bot]
parent fcd0517dee
commit 9fb49aacde
2 changed files with 7 additions and 0 deletions

View File

@@ -4160,9 +4160,11 @@ void buf_set_changedtick(buf_T *const buf, const varnumber_T changedtick)
buf->changedtick_di.di_tv.vval.v_number = changedtick; buf->changedtick_di.di_tv.vval.v_number = changedtick;
if (tv_dict_is_watched(buf->b_vars)) { if (tv_dict_is_watched(buf->b_vars)) {
buf->b_locked++;
tv_dict_watcher_notify(buf->b_vars, tv_dict_watcher_notify(buf->b_vars,
(char *)buf->changedtick_di.di_key, (char *)buf->changedtick_di.di_key,
&buf->changedtick_di.di_tv, &buf->changedtick_di.di_tv,
&old_val); &old_val);
buf->b_locked--;
} }
} }

View File

@@ -428,6 +428,11 @@ describe('Vimscript dictionary notifications', function()
command([[call dictwatcherdel(b:, 'changedtick', 'OnTickChanged')]]) command([[call dictwatcherdel(b:, 'changedtick', 'OnTickChanged')]])
insert('t') insert('t')
assert_alive() 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) end)
it('does not cause use-after-free when unletting from callback', function() it('does not cause use-after-free when unletting from callback', function()