From: Christian Brabandt Date: Thu, 2 Jul 2026 20:06:33 +0000 (+0000) Subject: patch 9.2.0780: Memory leak in evalvars.c on alloc failure X-Git-Tag: v9.2.0780^0 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f2156161c52548af2a502858b59f48ea2fb33bb2;p=thirdparty%2Fvim.git patch 9.2.0780: Memory leak in evalvars.c on alloc failure Problem: Memory leak in evalvars.c on alloc failure (Ao Xijie) Solution: free new_tuple when tuple_append_tv() fails and clear typeval, add a test. closes: #20668 Supported by AI. Signed-off-by: Christian Brabandt --- diff --git a/src/alloc.h b/src/alloc.h index f3a27f6212..3d740bca3e 100644 --- a/src/alloc.h +++ b/src/alloc.h @@ -46,5 +46,6 @@ typedef enum { aid_blob_alloc, aid_get_func, aid_defer, + aid_tuple_append, aid_last } alloc_id_T; diff --git a/src/evalvars.c b/src/evalvars.c index 9b98ae7310..f74b1c76ad 100644 --- a/src/evalvars.c +++ b/src/evalvars.c @@ -1363,7 +1363,11 @@ ex_let_vars( copy_tv(TUPLE_ITEM(tuple, idx), &new_tv); if (tuple_append_tv(new_tuple, &new_tv) == FAIL) + { + clear_tv(&new_tv); + tuple_unref(new_tuple); return FAIL; + } idx++; } diff --git a/src/testdir/test_tuple.vim b/src/testdir/test_tuple.vim index 26609a20fe..68bdca08c2 100644 --- a/src/testdir/test_tuple.vim +++ b/src/testdir/test_tuple.vim @@ -2463,4 +2463,12 @@ func Test_tuple_multi_assign_in_for_loop_from_import() call v9.CheckSourceScriptSuccess(lines) endfunc +" Memory allocation failure while collecting the rest of a tuple in an unpack +func Test_tuple_unpack_memory_fail() + let t = ('1', '2', '3') + call test_alloc_fail(GetAllocId('tuple_append'), 0, 0) + call assert_fails('let [a; rest] = t', 'E342:') + unlet t +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/tuple.c b/src/tuple.c index b7a420e941..8e5a9fcfad 100644 --- a/src/tuple.c +++ b/src/tuple.c @@ -291,7 +291,7 @@ tuple_find(tuple_T *tuple, long n) int tuple_append_tv(tuple_T *tuple, typval_T *tv) { - if (ga_grow(&tuple->tv_items, 1) == FAIL) + if (ga_grow_id(&tuple->tv_items, 1, aid_tuple_append) == FAIL) return FAIL; tuple_set_item(tuple, TUPLE_LEN(tuple), tv); diff --git a/src/version.c b/src/version.c index 1d6c351a70..27c2bfe527 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 */ +/**/ + 780, /**/ 779, /**/