patch 9.2.1222: Vim9: Stack corruption with :silent! causes a crash
Problem: Vim9: when a function called with :silent! fails to load
a variable, the value is missing from the stack causing a
crash (waroad).
Solution: Push a zero value.
closes: #21519
Assisted-by: Claude
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
3 files changed
+44
No files matched your search
@@ -5141,4 +5141,32 @@ def Test_lambda_type_error()
|
||||
v9.CheckSourceFailure(lines, 'E1180: Variable arguments type must be a list: number', 2)
|
||||
enddef
|
||||
|
||||
def Test_cmdmod_silent_nested_load_error()
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
var result = ''
|
||||
|
||||
def H(): number
|
||||
result ..= 'Hb'
|
||||
echo g:nosuch
|
||||
result ..= 'Ha'
|
||||
return 1
|
||||
enddef
|
||||
|
||||
def G()
|
||||
result ..= 'Gb'
|
||||
silent! H()
|
||||
silent! g:out->add(H())
|
||||
result ..= 'Ga'
|
||||
enddef
|
||||
|
||||
g:out = []
|
||||
G()
|
||||
assert_equal('GbHbHaHbHaGa', result)
|
||||
assert_equal([1], g:out)
|
||||
unlet g:out
|
||||
END
|
||||
v9.CheckScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
|
||||
@@ -743,6 +743,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1222,
|
||||
/**/
|
||||
1221,
|
||||
/**/
|
||||
|
||||
@@ -3306,6 +3306,13 @@ load_namespace_var(ectx_T *ectx, isntype_T isn_type, isn_T *iptr)
|
||||
else
|
||||
semsg(_(e_undefined_variable_char_str),
|
||||
namespace, iptr->isn_arg.string);
|
||||
// Push a value anyway, the stack must have the expected size when the
|
||||
// error is ignored because of ":silent!" in a calling function.
|
||||
typval_T *tv = STACK_TV_BOT(0);
|
||||
tv->v_type = VAR_NUMBER;
|
||||
tv->v_lock = 0;
|
||||
tv->vval.v_number = 0;
|
||||
++ectx->ec_stack.ga_len;
|
||||
return FAIL;
|
||||
}
|
||||
else
|
||||
@@ -4268,7 +4275,14 @@ exec_instructions(ectx_T *ectx)
|
||||
SOURCING_LNUM = iptr->isn_lnum;
|
||||
if (eval_variable(name, (int)STRLEN(name), 0,
|
||||
STACK_TV_BOT(0), NULL, EVAL_VAR_VERBOSE) == FAIL)
|
||||
{
|
||||
tv = STACK_TV_BOT(0);
|
||||
tv->v_type = VAR_NUMBER;
|
||||
tv->v_lock = 0;
|
||||
tv->vval.v_number = 0;
|
||||
++ectx->ec_stack.ga_len;
|
||||
goto on_error;
|
||||
}
|
||||
++ectx->ec_stack.ga_len;
|
||||
}
|
||||
break;
|
||||
|
||||
Reference in new issue
Block a user