eval: Remove dictwatcher from watchers queue before freeing it

This fixes a use-after-free noticed by ASAN which would occur when a
dictwatcher was still active on a dictionary when the dictionary was
freed.

    fun! MakeWatch()
      let d = {'foo': 'bar'}
      call dictwatcheradd(d, 'foo', function('...'))
    endfun

Patch-by: oni-link
Closes #5930
This commit is contained in:
James McCoy
2017-01-12 13:57:37 -05:00
parent 50d0d89129
commit 674db4b01f
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);