changeset 26954:11ee2667a09a v8.2.4006

patch 8.2.4006: Vim9: crash when declaring variable on the command line Commit: https://github.com/vim/vim/commit/c653e4a2bd4099e2fac8e1c448a0f34581d5a658 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Jan 5 10:16:30 2022 +0000 patch 8.2.4006: Vim9: crash when declaring variable on the command line Problem: Vim9: crash when declaring variable on the command line. Solution: Use a temporary type list. (closes https://github.com/vim/vim/issues/9474)
author Bram Moolenaar <Bram@vim.org>
date Wed, 05 Jan 2022 11:30:04 +0100
parents 32a59c0bf26c
children fe5fc1a23b09
files src/eval.c src/testdir/test_vim9_assign.vim src/version.c
diffstat 3 files changed, 39 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/eval.c
+++ b/src/eval.c
@@ -889,8 +889,9 @@ get_lval(
 	    }
 	    if (*p == ':')
 	    {
-		scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
-		char_u	     *tp = skipwhite(p + 1);
+		garray_T    tmp_type_list;
+		garray_T    *type_list;
+		char_u	    *tp = skipwhite(p + 1);
 
 		if (tp == p + 1 && !quiet)
 		{
@@ -898,11 +899,26 @@ get_lval(
 		    return NULL;
 		}
 
+		if (SCRIPT_ID_VALID(current_sctx.sc_sid))
+		    type_list = &SCRIPT_ITEM(current_sctx.sc_sid)->sn_type_list;
+		else
+		{
+		    type_list = &tmp_type_list;
+		    ga_init2(type_list, sizeof(type_T), 10);
+		}
+
 		// parse the type after the name
-		lp->ll_type = parse_type(&tp, &si->sn_type_list, !quiet);
+		lp->ll_type = parse_type(&tp, type_list, !quiet);
 		if (lp->ll_type == NULL && !quiet)
 		    return NULL;
 		lp->ll_name_end = tp;
+
+		// drop the type when not in a script
+		if (type_list == &tmp_type_list)
+		{
+		    lp->ll_type = NULL;
+		    clear_type_list(type_list);
+		}
 	    }
 	}
     }
--- a/src/testdir/test_vim9_assign.vim
+++ b/src/testdir/test_vim9_assign.vim
@@ -2,6 +2,7 @@
 
 source check.vim
 source vim9.vim
+source term_util.vim
 
 let s:appendToMe = 'xxx'
 let s:addToMe = 111
@@ -2281,6 +2282,23 @@ def Test_abort_after_error()
   delete('Xtestscript')
 enddef
 
+func Test_declare_command_line()
+  CheckRunVimInTerminal
+  call Run_Test_declare_command_line()
+endfunc
+
+def Run_Test_declare_command_line()
+  # On the command line the type is parsed but not used.
+  # To get rid of the script context have to run this in another Vim instance.
+  var buf = RunVimInTerminal('', {'rows': 6})
+  term_sendkeys(buf, ":vim9 var abc: list<list<number>> = [ [1, 2, 3], [4, 5, 6] ]\<CR>")
+  TermWait(buf)
+  term_sendkeys(buf, ":echo abc\<CR>")
+  TermWait(buf)
+  WaitForAssert(() => assert_match('\[\[1, 2, 3\], \[4, 5, 6\]\]', term_getline(buf, 6)))
+  StopVimInTerminal(buf)
+enddef
+
 
 
 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    4006,
+/**/
     4005,
 /**/
     4004,