mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +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