dictwatcher: fix use-after-free #11495

fixes #11494
This commit is contained in:
erw7
2019-12-02 19:09:30 +09:00
committed by Justin M. Keyes
parent 735d89d09e
commit ab860cb5f6
2 changed files with 16 additions and 0 deletions

View File

@@ -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);

View File

@@ -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)