]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0770: dict_add_dict() has inconsistent ownership on failure v9.2.0770
authorChristian Brabandt <cb@256bit.org>
Thu, 2 Jul 2026 19:30:45 +0000 (19:30 +0000)
committerChristian Brabandt <cb@256bit.org>
Thu, 2 Jul 2026 19:30:45 +0000 (19:30 +0000)
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 <cb@256bit.org>
src/dict.c
src/version.c

index aea40b33897a6c80100e4ab292a9403fd184d43c..c34ce2981469d5ca982694c9e7dc5df268b60542 100644 (file)
@@ -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;
 }
 
index 0b3f91193a6176ae05a51d245e39816ac33d0df8..c50ea41624959f7287f94a4cf2e25b435b552009 100644 (file)
@@ -759,6 +759,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    770,
 /**/
     769,
 /**/