From c653e4a2bd4099e2fac8e1c448a0f34581d5a658 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Wed, 5 Jan 2022 10:16:30 +0000 Subject: [PATCH] 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 #9474) --- src/eval.c | 22 +++++++++++++++++++--- src/testdir/test_vim9_assign.vim | 18 ++++++++++++++++++ src/version.c | 2 ++ 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/eval.c b/src/eval.c index a99d149a0..2e370c1b2 100644 --- 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); + } } } } diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim index c91cd6547..209ac95f8 100644 --- 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> = [ [1, 2, 3], [4, 5, 6] ]\") + TermWait(buf) + term_sendkeys(buf, ":echo abc\") + 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 diff --git a/src/version.c b/src/version.c index 9f17657fe..ad0d49e5d 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 */ +/**/ + 4006, /**/ 4005, /**/ -- 2.40.0