summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-01-17 20:23:38 +0100
committerBram Moolenaar <Bram@vim.org>2021-01-17 20:23:38 +0100
commit036d07144efe213199b1ed8de998e6f12a056499 (patch)
treedbfcf44e135229e87a065801ac8a2e3d9b093b22
parent1430ceeb2d4185a8d60fa81007fbc8b74fd68c46 (diff)
patch 8.2.2371: Vim9: crash when using types in :for with unpackv8.2.2371
Problem: Vim9: crash when using types in :for with unpack. Solution: Check for skip_var_list() failing. Pass include_type to skip_var_one(). Skip type when compiling. (closes #7694)
-rw-r--r--src/evalvars.c11
-rw-r--r--src/testdir/test_vim9_script.vim6
-rw-r--r--src/version.c2
-rw-r--r--src/vim9compile.c4
4 files changed, 19 insertions, 4 deletions
diff --git a/src/evalvars.c b/src/evalvars.c
index 155f603b50..d98d9e4708 100644
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -1019,7 +1019,7 @@ skip_var_list(
for (;;)
{
p = skipwhite(p + 1); // skip whites after '[', ';' or ','
- s = skip_var_one(p, FALSE);
+ s = skip_var_one(p, include_type);
if (s == p)
{
if (!silent)
@@ -1067,11 +1067,14 @@ skip_var_one(char_u *arg, int include_type)
return arg + 2;
end = find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg,
NULL, NULL, FNE_INCL_BR | FNE_CHECK_START);
+
+ // "a: type" is declaring variable "a" with a type, not "a:".
+ // Same for "s: type".
+ if (end == arg + 2 && end[-1] == ':')
+ --end;
+
if (include_type && in_vim9script())
{
- // "a: type" is declaring variable "a" with a type, not "a:".
- if (end == arg + 2 && end[-1] == ':')
- --end;
if (*end == ':')
end = skip_type(skipwhite(end + 1), FALSE);
}
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index 478c394603..957671c53b 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -2060,6 +2060,12 @@ def Test_for_loop()
total += nr
endfor
assert_equal(6, total)
+
+ var res = ""
+ for [n: number, s: string] in [[1, 'a'], [2, 'b']]
+ res ..= n .. s
+ endfor
+ assert_equal('1a2b', res)
enddef
def Test_for_loop_fails()
diff --git a/src/version.c b/src/version.c
index ecb0c4355e..289854e89e 100644
--- 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 */
/**/
+ 2371,
+/**/
2370,
/**/
2369,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index fb7aeddd49..01bf2c19a8 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -6884,6 +6884,8 @@ compile_for(char_u *arg_start, cctx_T *cctx)
int idx;
p = skip_var_list(arg_start, TRUE, &var_count, &semicolon, FALSE);
+ if (p == NULL)
+ return NULL;
if (var_count == 0)
var_count = 1;
@@ -7018,6 +7020,8 @@ compile_for(char_u *arg_start, cctx_T *cctx)
generate_STORE(cctx, ISN_STORE, var_lvar->lv_idx, NULL);
}
+ if (*p == ':')
+ p = skip_type(skipwhite(p + 1), FALSE);
if (*p == ',' || *p == ';')
++p;
arg = skipwhite(p);