]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0219: call stack can be corrupted v9.2.0219
authorSergey Vlasov <sergey@vlasov.me>
Fri, 20 Mar 2026 23:21:28 +0000 (23:21 +0000)
committerChristian Brabandt <cb@256bit.org>
Fri, 20 Mar 2026 23:21:28 +0000 (23:21 +0000)
Problem:  call stack can be corrupted, because calculated remaining
          capacity for call stack string can underflow (after v9.1.1983)
Solution: Calculate capacity against maximum capacity
          (Sergey Vlasov).

closes: #19759

Signed-off-by: Sergey Vlasov <sergey@vlasov.me>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/scriptfile.c
src/testdir/test_vim9_script.vim
src/version.c

index 7750ba08eb4228b782dfdf3da62d8aac3965396f..c6d2b737090fe5a6da5624acd9e5d3b2c4e79357 100644 (file)
@@ -230,7 +230,7 @@ estack_sfile(estack_arg_T which UNUSED)
            {
                added = vim_snprintf_safelen(
                    (char *)ga.ga_data + ga.ga_len,
-                   len - (size_t)ga.ga_len,
+                   ga.ga_maxlen - ga.ga_len,
                    "<SNR>%d_%s.",
                    entry->es_info.ufunc->uf_script_ctx.sc_sid,
                    class_name.string);
@@ -244,7 +244,7 @@ estack_sfile(estack_arg_T which UNUSED)
            {
                added = vim_snprintf_safelen(
                    (char *)ga.ga_data + ga.ga_len,
-                   len - (size_t)ga.ga_len,
+                   ga.ga_maxlen - ga.ga_len,
                    "[%ld]",
                    lnum);
 
index 022bdeb12bf368842b8eed837695435da41b3ead..eefb6174d84d4020b90dbba421c8207f8234d807 100644 (file)
@@ -5791,4 +5791,38 @@ def Test_substitute_cmd()
   source Xvim9lines
 enddef
 
+def Test_call_stack_string()
+  CheckScreendump
+  var lines =<< trim END
+    vim9script
+
+    def CheckStack(stack: string, expected: string)
+      const caller = stack->split('\.\.')[-1]->substitute('\[\d\+\]', '', '')
+      if caller !~ expected
+        throw 'fail'
+      endif
+    enddef
+
+    class C
+      static def ClassMethodX()
+        CheckStack(expand('<stack>'), '_C.ClassMethodX$')
+      enddef
+    endclass
+
+    def NormalFuncX()
+      CheckStack(expand('<stack>'), '_NormalFuncX$')
+    enddef
+
+    # creating function names of various lengths till the name in call stack is corrupt
+    for i in range(1, 20)
+      const name = 'Wrapper' .. repeat('A', i) .. 'func'
+      execute "def g:" .. name .. "(id: any)\n  NormalFuncX()\n  C.ClassMethodX()\nenddef"
+      execute "timer_start(0, g:" .. name .. ")"
+    endfor
+  END
+  writefile(lines, 'XTest_call_stack_string', 'D')
+  var buf = g:RunVimInTerminal('-S XTest_call_stack_string', {'rows': 20})
+  g:StopVimInTerminal(buf)
+enddef
+
 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
index db107b529b40db85470fbd0e0c4c23748723084e..3b956fd2d8949a48355e38e7e82a19c53b5b95a2 100644 (file)
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    219,
 /**/
     218,
 /**/