Merge pull request #5935 from jamessan/dictwatcher-crash

eval: Remove dictwatcher from watchers queue before freeing it
This commit is contained in:
James McCoy 2017-01-12 18:24:19 -05:00 committed by GitHub
commit 802b49ee80
2 changed files with 18 additions and 1 deletions

View File

@ -6410,8 +6410,8 @@ static void dict_free_contents(dict_T *d) {
while (!QUEUE_EMPTY(&d->watchers)) {
QUEUE *w = QUEUE_HEAD(&d->watchers);
DictWatcher *watcher = dictwatcher_node_data(w);
dictwatcher_free(watcher);
QUEUE_REMOVE(w);
dictwatcher_free(watcher);
}
hash_clear(&d->dv_hashtab);

View File

@ -3,6 +3,7 @@ local clear, nvim, source = helpers.clear, helpers.nvim, helpers.source
local eq, next_msg = helpers.eq, helpers.next_message
local exc_exec = helpers.exc_exec
local command = helpers.command
local eval = helpers.eval
describe('dictionary change notifications', function()
@ -255,5 +256,21 @@ describe('dictionary change notifications', function()
eq({'notification', '2b', {'key', {old = 'v2', new = 'value'}}}, next_msg())
end)
it('does not crash when freeing a watched dictionary', function()
source([[
function! Watcher(dict, key, value)
echo a:key string(a:value)
endfunction
function! MakeWatch()
let d = {'foo': 'bar'}
call dictwatcheradd(d, 'foo', function('Watcher'))
endfunction
]])
command('call MakeWatch()')
eq(2, eval('1+1')) -- Still alive?
end)
end)
end)