Commit: patch 9.2.0813: dict_add_func() may corrupt funcref count on failure

2 views
Skip to first unread message

Christian Brabandt

unread,
Jul 20, 2026, 12:15:16 PM (yesterday) Jul 20
to vim...@googlegroups.com
patch 9.2.0813: dict_add_func() may corrupt funcref count on failure

Commit: https://github.com/vim/vim/commit/4a403b48c653461f3c2fa331664d68585f59ea4c
Author: Yasuhiro Matsumoto <matt...@gmail.com>
Date: Mon Jul 20 16:02:56 2026 +0000

patch 9.2.0813: dict_add_func() may corrupt funcref count on failure

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: #20668
closes: #20742

Signed-off-by: Yasuhiro Matsumoto <matt...@gmail.com>
Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/src/dict.c b/src/dict.c
index ac1fb3841..5531cc72a 100644
--- a/src/dict.c
+++ b/src/dict.c
@@ -552,12 +552,13 @@ dict_add_func(dict_T *d, char *key, ufunc_T *fp)
return FAIL;
item->di_tv.v_type = VAR_FUNC;
item->di_tv.vval.v_string = vim_strnsave(fp->uf_name, fp->uf_namelen);
+ // Reference before dict_add() so dictitem_free()'s unref stays balanced on failure.
+ func_ref(item->di_tv.vval.v_string);
if (dict_add(d, item) == FAIL)
{
dictitem_free(item);
return FAIL;
}
- func_ref(item->di_tv.vval.v_string);
return OK;
}

diff --git a/src/version.c b/src/version.c
index 333bbc87d..178090f6b 100644
--- a/src/version.c
+++ b/src/version.c
@@ -759,6 +759,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 813,
/**/
812,
/**/
Reply all
Reply to author
Forward
0 new messages