vim-patch:9.2.0771: dict_add_list() has inconsistent ownership on failure

Problem:  dict_add_list() frees the passed list on 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 list after a failure.
Solution: On failure leave the passed list untouched and owned by the
          caller; only take a reference on success.

related: vim/vim#20668

Supported by AI.

3ae1443d10

Co-authored-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
zeertzjq
2026-07-03 15:19:24 +08:00
parent 6f98352163
commit b856d5080d

View File

@@ -2494,11 +2494,14 @@ int tv_dict_add_list(dict_T *const d, const char *const key, const size_t key_le
item->di_tv.v_type = VAR_LIST;
item->di_tv.vval.v_list = list;
tv_list_ref(list);
if (tv_dict_add(d, item) == FAIL) {
// Detach "list" so tv_dict_item_free() does not unref it: on failure
// ownership stays with the caller.
item->di_tv.vval.v_list = NULL;
tv_dict_item_free(item);
return FAIL;
}
tv_list_ref(list);
return OK;
}