From 32538082eaaab10b3468532d5a807ee25a7f1bf2 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 21 Jul 2026 07:02:08 +0800 Subject: [PATCH] vim-patch:9.2.0813: dict_add_func() may corrupt funcref count on failure (#40877) Problem: dict_add_func() references the function only after a successful dict_add(), on failure dictitem_free() calls func_unref() without a matching func_ref(), corrupting the reference count of a lambda or numbered function. Solution: Take the reference before dict_add() so the unref on the failure path is balanced (Yasuhiro Matsumoto). related: vim/vim#20668 closes: vim/vim#20742 https://github.com/vim/vim/commit/4a403b48c653461f3c2fa331664d68585f59ea4c Co-authored-by: Yasuhiro Matsumoto --- src/nvim/eval/typval.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index c84c7a30ce..fc057f231a 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -2690,11 +2690,12 @@ int tv_dict_add_func(dict_T *const d, const char *const key, const size_t key_le item->di_tv.v_type = VAR_FUNC; item->di_tv.vval.v_string = xmemdupz(fp->uf_name, fp->uf_namelen); + // Reference before tv_dict_add() so tv_dict_item_free()'s unref stays balanced on failure. + func_ref(item->di_tv.vval.v_string); if (tv_dict_add(d, item) == FAIL) { tv_dict_item_free(item); return FAIL; } - func_ref(item->di_tv.vval.v_string); return OK; }