Commit: patch 9.2.0219: call stack can be corrupted

1 view
Skip to first unread message

Christian Brabandt

unread,
Mar 20, 2026, 7:32:10 PM (3 days ago) Mar 20
to vim...@googlegroups.com
patch 9.2.0219: call stack can be corrupted

Commit: https://github.com/vim/vim/commit/8e0483c2f484c2d99b99f0672eed6e726dceea6f
Author: Sergey Vlasov <ser...@vlasov.me>
Date: Fri Mar 20 23:21:28 2026 +0000

patch 9.2.0219: call stack can be corrupted

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 <ser...@vlasov.me>
Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/src/scriptfile.c b/src/scriptfile.c
index 7750ba08e..c6d2b7370 100644
--- a/src/scriptfile.c
+++ b/src/scriptfile.c
@@ -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);

diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index 022bdeb12..eefb6174d 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -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)
NormalFuncX()
C.ClassMethodX()
enddef"
+ 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
diff --git a/src/version.c b/src/version.c
index db107b529..3b956fd2d 100644
--- a/src/version.c
+++ b/src/version.c
@@ -734,6 +734,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 219,
/**/
218,
/**/
Reply all
Reply to author
Forward
0 new messages