aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames McCoy <jamessan@jamessan.com>2017-01-12 18:24:19 -0500
committerGitHub <noreply@github.com>2017-01-12 18:24:19 -0500
commit802b49ee803aed63c15bd35ffc10e1ba2ba30e59 (patch)
tree99084f57c9836176a133ca4d47aa7f26ce7fc907
parent50d0d891299c111c5e349c084ef146facfaad009 (diff)
parent674db4b01fc6b899c7f56a40b77fa40c32466f6c (diff)
downloadrneovim-802b49ee803aed63c15bd35ffc10e1ba2ba30e59.tar.gz
rneovim-802b49ee803aed63c15bd35ffc10e1ba2ba30e59.tar.bz2
rneovim-802b49ee803aed63c15bd35ffc10e1ba2ba30e59.zip
Merge pull request #5935 from jamessan/dictwatcher-crash
eval: Remove dictwatcher from watchers queue before freeing it
-rw-r--r--src/nvim/eval.c2
-rw-r--r--test/functional/ex_cmds/dict_notifications_spec.lua17
2 files changed, 18 insertions, 1 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 1688a565c1..cdf60d9765 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -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);
diff --git a/test/functional/ex_cmds/dict_notifications_spec.lua b/test/functional/ex_cmds/dict_notifications_spec.lua
index e6f7609016..5e89986c0f 100644
--- a/test/functional/ex_cmds/dict_notifications_spec.lua
+++ b/test/functional/ex_cmds/dict_notifications_spec.lua
@@ -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)