forked from aniani/vim
patch 8.2.2371: Vim9: crash when using types in :for with unpack
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)
This commit is contained in:
@@ -1019,7 +1019,7 @@ skip_var_list(
|
|||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
p = skipwhite(p + 1); // skip whites after '[', ';' or ','
|
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 (s == p)
|
||||||
{
|
{
|
||||||
if (!silent)
|
if (!silent)
|
||||||
@@ -1067,11 +1067,14 @@ skip_var_one(char_u *arg, int include_type)
|
|||||||
return arg + 2;
|
return arg + 2;
|
||||||
end = find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg,
|
end = find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg,
|
||||||
NULL, NULL, FNE_INCL_BR | FNE_CHECK_START);
|
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())
|
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 == ':')
|
if (*end == ':')
|
||||||
end = skip_type(skipwhite(end + 1), FALSE);
|
end = skip_type(skipwhite(end + 1), FALSE);
|
||||||
}
|
}
|
||||||
|
@@ -2060,6 +2060,12 @@ def Test_for_loop()
|
|||||||
total += nr
|
total += nr
|
||||||
endfor
|
endfor
|
||||||
assert_equal(6, total)
|
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
|
enddef
|
||||||
|
|
||||||
def Test_for_loop_fails()
|
def Test_for_loop_fails()
|
||||||
|
@@ -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 */
|
||||||
|
/**/
|
||||||
|
2371,
|
||||||
/**/
|
/**/
|
||||||
2370,
|
2370,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -6884,6 +6884,8 @@ compile_for(char_u *arg_start, cctx_T *cctx)
|
|||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
p = skip_var_list(arg_start, TRUE, &var_count, &semicolon, FALSE);
|
p = skip_var_list(arg_start, TRUE, &var_count, &semicolon, FALSE);
|
||||||
|
if (p == NULL)
|
||||||
|
return NULL;
|
||||||
if (var_count == 0)
|
if (var_count == 0)
|
||||||
var_count = 1;
|
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);
|
generate_STORE(cctx, ISN_STORE, var_lvar->lv_idx, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*p == ':')
|
||||||
|
p = skip_type(skipwhite(p + 1), FALSE);
|
||||||
if (*p == ',' || *p == ';')
|
if (*p == ',' || *p == ';')
|
||||||
++p;
|
++p;
|
||||||
arg = skipwhite(p);
|
arg = skipwhite(p);
|
||||||
|
Reference in New Issue
Block a user