]> granicus.if.org Git - vim/commitdiff
patch 9.0.1093: using freed memory of object member v9.0.1093
authorBram Moolenaar <Bram@vim.org>
Sat, 24 Dec 2022 21:24:06 +0000 (21:24 +0000)
committerBram Moolenaar <Bram@vim.org>
Sat, 24 Dec 2022 21:24:06 +0000 (21:24 +0000)
Problem:    Using freed memory of object member. (Yegappan Lakshmanan)
Solution:   Make a copy of the object member when getting it.

src/testdir/test_vim9_class.vim
src/version.c
src/vim9execute.c

index 88128e7454903bb556531c18ec262a47f4451748..c73e80fb629d5302af797d1c51f2da3281470ba5 100644 (file)
@@ -323,6 +323,32 @@ def Test_class_object_member_access()
       assert_fails('trip.four = 4', 'E1334')
   END
   v9.CheckScriptSuccess(lines)
+
+  lines =<< trim END
+      vim9script
+
+      class MyCar
+        this.make: string
+
+        def new(make_arg: string)
+          this.make = make_arg
+        enddef
+
+        def GetMake(): string
+          return $"make = {this.make}"
+        enddef
+      endclass
+
+      var c = MyCar.new("abc")
+      assert_equal('make = abc', c.GetMake())
+
+      c = MyCar.new("def")
+      assert_equal('make = def', c.GetMake())
+
+      var c2 = MyCar.new("123")
+      assert_equal('make = 123', c2.GetMake())
+  END
+  v9.CheckScriptSuccess(lines)
 enddef
 
 def Test_class_member_access()
index 53f00014bb737c820d8d167714b6fccf81a6d37c..5c21f7a9f236a0bcf3e6622b94479ed1d38366a5 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1093,
 /**/
     1092,
 /**/
index cdaeb5b844557589547b2234f167155542c8575f..a6d43b5c14b7b88a7eede3393e930971e6655645 100644 (file)
@@ -3799,7 +3799,7 @@ exec_instructions(ectx_T *ectx)
                tv->vval.v_number = iptr->isn_arg.storenr.stnr_val;
                break;
 
-           // store value in list or dict variable
+           // Store a value in a list, dict, blob or object variable.
            case ISN_STOREINDEX:
                {
                    int res = execute_storeindex(iptr, ectx);
@@ -5159,7 +5159,7 @@ exec_instructions(ectx_T *ectx)
                    object_T *obj = tv->vval.v_object;
                    // the members are located right after the object struct
                    typval_T *mtv = ((typval_T *)(obj + 1)) + idx;
-                   *tv = *mtv;
+                   copy_tv(mtv, tv);
 
                    // Unreference the object after getting the member, it may
                    // be freed.