]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0780: Memory leak in evalvars.c on alloc failure v9.2.0780
authorChristian Brabandt <cb@256bit.org>
Thu, 2 Jul 2026 20:06:33 +0000 (20:06 +0000)
committerChristian Brabandt <cb@256bit.org>
Thu, 2 Jul 2026 20:06:33 +0000 (20:06 +0000)
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 <cb@256bit.org>
src/alloc.h
src/evalvars.c
src/testdir/test_tuple.vim
src/tuple.c
src/version.c

index f3a27f621288439c3f71d2b4eeb1f7df27f32b38..3d740bca3e1728f67520f82edfbdfdfb8426bf69 100644 (file)
@@ -46,5 +46,6 @@ typedef enum {
     aid_blob_alloc,
     aid_get_func,
     aid_defer,
+    aid_tuple_append,
     aid_last
 } alloc_id_T;
index 9b98ae731011aa3b0d4bc222a348cf65a5c38f82..f74b1c76ad3b5a86157917c988101946e82f202b 100644 (file)
@@ -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++;
                }
 
index 26609a20fe0ce1d6e7ffc694d76c6e9a773abff2..68bdca08c2ec879bb5d87f32db2b6cbf527eb3e7 100644 (file)
@@ -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
index b7a420e9412408eac9d4032a3d8fbbc293f898bc..8e5a9fcfadfc22f40457fbc1ce5474f1392a7c61 100644 (file)
@@ -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);
index 1d6c351a70b6e26e729f38bf6659822c911d0021..27c2bfe527215628cbe985ea63700dc961f2c45b 100644 (file)
@@ -759,6 +759,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    780,
 /**/
     779,
 /**/