From 352134bbfbff4831a3f6a3383d9e2d8660016243 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 17 Oct 2020 22:04:08 +0200 Subject: [PATCH] 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) --- src/testdir/test_vim9_assign.vim | 3 +++ src/testdir/test_vim9_script.vim | 22 ++++++++++++++++++++++ src/version.c | 2 ++ src/vim9execute.c | 20 ++++++++++++++++++++ 4 files changed, 47 insertions(+) diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim index 5f5a45985..23ef0f256 100644 --- a/src/testdir/test_vim9_assign.vim +++ b/src/testdir/test_vim9_assign.vim @@ -622,6 +622,9 @@ def Test_assignment_failure() CheckDefExecFailure(['var x: number', 'var y: number', '[x, y] = [1]'], 'E1093:') + CheckDefExecFailure(['var x: string', + 'var y: string', + '[x, y] = ["x"]'], 'E1093:') CheckDefExecFailure(['var x: number', 'var y: number', 'var z: list', diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim index 9a2a48158..21de34482 100644 --- a/src/testdir/test_vim9_script.vim +++ b/src/testdir/test_vim9_script.vim @@ -620,6 +620,7 @@ def Test_throw_vimscript() lines =<< trim END vim9script + @r = '' def Func() throw @r enddef @@ -2818,6 +2819,27 @@ def Test_script_var_scope() CheckScriptFailure(lines, 'E121:', 6) 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. def Test_substitute_cmd() new diff --git a/src/version.c b/src/version.c index cdecc3ab4..342ad7cd9 100644 --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1859, /**/ 1858, /**/ diff --git a/src/vim9execute.c b/src/vim9execute.c index 27e636804..31b67d183 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -830,6 +830,8 @@ call_def_function( int breakcheck_count = 0; int called_emsg_before = called_emsg; 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. #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.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. suppress_errthrow = FALSE; @@ -2819,6 +2826,19 @@ failed: estack_pop(); 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: // Free all local variables, but not arguments. for (idx = 0; idx < ectx.ec_stack.ga_len; ++idx) -- 2.40.0