mirror of
https://github.com/neovim/neovim.git
synced 2025-09-20 02:08:17 +00:00
@@ -1200,6 +1200,7 @@ void tv_dict_watcher_notify(dict_T *const dict, const char *const key,
|
||||
|
||||
typval_T rettv;
|
||||
|
||||
dict->dv_refcount++;
|
||||
QUEUE *w;
|
||||
QUEUE_FOREACH(w, &dict->watchers) {
|
||||
DictWatcher *watcher = tv_dict_watcher_node_data(w);
|
||||
@@ -1211,6 +1212,7 @@ void tv_dict_watcher_notify(dict_T *const dict, const char *const key,
|
||||
tv_clear(&rettv);
|
||||
}
|
||||
}
|
||||
tv_dict_unref(dict);
|
||||
|
||||
for (size_t i = 1; i < ARRAY_SIZE(argv); i++) {
|
||||
tv_clear(argv + i);
|
||||
|
@@ -357,4 +357,18 @@ describe('VimL dictionary notifications', function()
|
||||
eq(2, eval('1+1')) -- Still alive?
|
||||
end)
|
||||
|
||||
it('does not cause use-after-free when unletting from callback', function()
|
||||
source([[
|
||||
let g:called = 0
|
||||
function W(...) abort
|
||||
unlet g:d
|
||||
let g:called = 1
|
||||
endfunction
|
||||
let g:d = {}
|
||||
call dictwatcheradd(g:d, '*', function('W'))
|
||||
let g:d.foo = 123
|
||||
]])
|
||||
eq(1, eval('g:called'))
|
||||
end)
|
||||
|
||||
end)
|
||||
|
Reference in New Issue
Block a user