]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.0.2000: Vim9: use-after-free in deep call stack v9.0.2000
authorYegappan Lakshmanan <yegappan@yahoo.com>
Sat, 7 Oct 2023 20:03:18 +0000 (22:03 +0200)
committerChristian Brabandt <cb@256bit.org>
Sat, 7 Oct 2023 20:03:18 +0000 (22:03 +0200)
Problem:  Vim9: use-after-free in deep call stack
Solution: Get the objct pointer from execution stack

closes: #13296

Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
src/testdir/test_vim9_class.vim
src/version.c
src/vim9execute.c

index 0c8fd7057a2712ed90a7f686b57b340611236b61..0e70c9f6fe3ef076d8e830d450a477f93f8e9af1 100644 (file)
@@ -6989,4 +6989,44 @@ func Test_object_variable_complex_type_check()
   call v9.CheckSourceSuccess(lines)
 endfunc
 
+" Test for recursively calling an object method.  This used to cause an
+" use-after-free error.
+def Test_recursive_object_method_call()
+  var lines =<< trim END
+    vim9script
+    class A
+      this.val: number = 0
+      def Foo(): number
+        if this.val >= 90
+          return this.val
+        endif
+        this.val += 1
+        return this.Foo()
+      enddef
+    endclass
+    var a = A.new()
+    assert_equal(90, a.Foo())
+  END
+  v9.CheckSourceSuccess(lines)
+enddef
+
+" Test for recursively calling a class method.
+def Test_recursive_class_method_call()
+  var lines =<< trim END
+    vim9script
+    class A
+      static val: number = 0
+      static def Foo(): number
+        if val >= 90
+          return val
+        endif
+        val += 1
+        return Foo()
+      enddef
+    endclass
+    assert_equal(90, A.Foo())
+  END
+  v9.CheckSourceSuccess(lines)
+enddef
+
 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
index 8dea204b2b340f245cfc29d386ceed52d5142b15..5d1c1c9441ccc2b2bb941725148b3a8986862ed7 100644 (file)
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2000,
 /**/
     1999,
 /**/
index f237132a896d3543796a1fab4ad209670a9a3700..826282241ba785ea7697f872c54cab30d2bd58c3 100644 (file)
@@ -559,6 +559,12 @@ call_dfunc(
                                     arg_to_add + STACK_FRAME_SIZE + varcount))
        return FAIL;
 
+    // The object pointer is in the execution typval stack.  The GA_GROW call
+    // above may have reallocated the execution typval stack.  So the object
+    // pointer may not be valid anymore.  Get the object pointer again from the
+    // execution stack.
+    obj = STACK_TV_BOT(0) - argcount - vararg_count - 1;
+
     // If depth of calling is getting too high, don't execute the function.
     if (funcdepth_increment() == FAIL)
        return FAIL;