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:
		| @ -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>', | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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, | ||||||
| /**/ | /**/ | ||||||
|  | |||||||
| @ -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) | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user