From: Christian Brabandt Date: Thu, 2 Jul 2026 19:30:45 +0000 (+0000) Subject: patch 9.2.0770: dict_add_dict() has inconsistent ownership on failure X-Git-Tag: v9.2.0770^0 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=12dbe788d461f7f01a908e9e9ecc844f85d71cb4;p=thirdparty%2Fvim.git patch 9.2.0770: dict_add_dict() has inconsistent ownership on failure Problem: dict_add_dict() frees the passed dict on one failure path (when dict_add() fails) but not on the other (when dictitem_alloc() fails), so a caller cannot tell whether it still owns the dict after a failure. Callers that unref the dict on failure (e.g. in window.c) then double-free it when dict_add() fails. Solution: Make the failure contract consistent: on failure leave the passed dict untouched and owned by the caller; only take a reference on success. related: #20668 Supported by AI. Signed-off-by: Christian Brabandt --- diff --git a/src/dict.c b/src/dict.c index aea40b3389..c34ce29814 100644 --- a/src/dict.c +++ b/src/dict.c @@ -621,12 +621,15 @@ dict_add_dict(dict_T *d, char *key, dict_T *dict) return FAIL; item->di_tv.v_type = VAR_DICT; item->di_tv.vval.v_dict = dict; - ++dict->dv_refcount; if (dict_add(d, item) == FAIL) { + // Detach "dict" so dictitem_free() does not unref it: on failure + // ownership stays with the caller. + item->di_tv.vval.v_dict = NULL; dictitem_free(item); return FAIL; } + ++dict->dv_refcount; return OK; } diff --git a/src/version.c b/src/version.c index 0b3f91193a..c50ea41624 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 */ +/**/ + 770, /**/ 769, /**/