0
0
mirror of https://github.com/vim/vim.git synced 2025-09-25 03:54:15 -04:00

patch 8.2.1859: Vim9: crash in unpack assignment

Problem:    Vim9: crash in unpack assignment.
Solution:   Make sure an error message is turned into an exception.
            (closes #7159)
This commit is contained in:
Bram Moolenaar
2020-10-17 22:04:08 +02:00
parent 403dc31f5a
commit 352134bbfb
4 changed files with 47 additions and 0 deletions

View File

@@ -622,6 +622,9 @@ def Test_assignment_failure()
CheckDefExecFailure(['var x: number', CheckDefExecFailure(['var x: number',
'var y: number', 'var y: number',
'[x, y] = [1]'], 'E1093:') '[x, y] = [1]'], 'E1093:')
CheckDefExecFailure(['var x: string',
'var y: string',
'[x, y] = ["x"]'], 'E1093:')
CheckDefExecFailure(['var x: number', CheckDefExecFailure(['var x: number',
'var y: number', 'var y: number',
'var z: list<number>', 'var z: list<number>',

View File

@@ -620,6 +620,7 @@ def Test_throw_vimscript()
lines =<< trim END lines =<< trim END
vim9script vim9script
@r = ''
def Func() def Func()
throw @r throw @r
enddef enddef
@@ -2818,6 +2819,27 @@ def Test_script_var_scope()
CheckScriptFailure(lines, 'E121:', 6) CheckScriptFailure(lines, 'E121:', 6)
enddef enddef
def Test_catch_exception_in_callback()
var lines =<< trim END
vim9script
def Callback(...l: any)
try
var x: string
var y: string
# this error should be caught with CHECKLEN
[x, y] = ['']
catch
g:caught = 'yes'
endtry
enddef
popup_menu('popup', #{callback: Callback})
feedkeys("\r", 'xt')
END
CheckScriptSuccess(lines)
unlet g:caught
enddef
" Keep this last, it messes up highlighting. " Keep this last, it messes up highlighting.
def Test_substitute_cmd() def Test_substitute_cmd()
new new

View File

@@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1859,
/**/ /**/
1858, 1858,
/**/ /**/

View File

@@ -830,6 +830,8 @@ call_def_function(
int breakcheck_count = 0; int breakcheck_count = 0;
int called_emsg_before = called_emsg; int called_emsg_before = called_emsg;
int save_suppress_errthrow = suppress_errthrow; int save_suppress_errthrow = suppress_errthrow;
msglist_T **saved_msg_list = NULL;
msglist_T *private_msg_list = NULL;
// Get pointer to item in the stack. // Get pointer to item in the stack.
#define STACK_TV(idx) (((typval_T *)ectx.ec_stack.ga_data) + idx) #define STACK_TV(idx) (((typval_T *)ectx.ec_stack.ga_data) + idx)
@@ -982,6 +984,11 @@ call_def_function(
current_sctx = ufunc->uf_script_ctx; current_sctx = ufunc->uf_script_ctx;
current_sctx.sc_version = SCRIPT_VERSION_VIM9; current_sctx.sc_version = SCRIPT_VERSION_VIM9;
// Use a specific location for storing error messages to be converted to an
// exception.
saved_msg_list = msg_list;
msg_list = &private_msg_list;
// Do turn errors into exceptions. // Do turn errors into exceptions.
suppress_errthrow = FALSE; suppress_errthrow = FALSE;
@@ -2819,6 +2826,19 @@ failed:
estack_pop(); estack_pop();
current_sctx = save_current_sctx; current_sctx = save_current_sctx;
if (*msg_list != NULL && saved_msg_list != NULL)
{
msglist_T **plist = saved_msg_list;
// Append entries from the current msg_list (uncaught exceptions) to
// the saved msg_list.
while (*plist != NULL)
plist = &(*plist)->next;
*plist = *msg_list;
}
msg_list = saved_msg_list;
failed_early: failed_early:
// Free all local variables, but not arguments. // Free all local variables, but not arguments.
for (idx = 0; idx < ectx.ec_stack.ga_len; ++idx) for (idx = 0; idx < ectx.ec_stack.ga_len; ++idx)