1
0
forked from aniani/vim

patch 8.2.3364: Vim9: crash when :for is skipped

Problem:    Vim9: crash when :for is skipped.
Solution:   Skip more code generation. (Naruhiko Nishino, closes #8777)
This commit is contained in:
rbtnn
2021-08-21 17:26:50 +02:00
committed by Bram Moolenaar
parent b8bd2e6eba
commit bebf06954e
3 changed files with 210 additions and 138 deletions

View File

@@ -2552,6 +2552,70 @@ def Test_for_outside_of_function()
delete('Xvim9for.vim') delete('Xvim9for.vim')
enddef enddef
def Test_for_skipped_block()
# test skipped blocks at outside of function
var lines =<< trim END
var result = []
if true
for n in [1, 2]
result += [n]
endfor
else
for n in [3, 4]
result += [n]
endfor
endif
assert_equal([1, 2], result)
result = []
if false
for n in [1, 2]
result += [n]
endfor
else
for n in [3, 4]
result += [n]
endfor
endif
assert_equal([3, 4], result)
END
CheckDefAndScriptSuccess(lines)
# test skipped blocks at inside of function
lines =<< trim END
def DefTrue()
var result = []
if true
for n in [1, 2]
result += [n]
endfor
else
for n in [3, 4]
result += [n]
endfor
endif
assert_equal([1, 2], result)
enddef
DefTrue()
def DefFalse()
var result = []
if false
for n in [1, 2]
result += [n]
endfor
else
for n in [3, 4]
result += [n]
endfor
endif
assert_equal([3, 4], result)
enddef
DefFalse()
END
CheckDefAndScriptSuccess(lines)
enddef
def Test_for_loop() def Test_for_loop()
var lines =<< trim END var lines =<< trim END
var result = '' var result = ''

View File

@@ -755,6 +755,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 */
/**/
3364,
/**/ /**/
3363, 3363,
/**/ /**/

View File

@@ -8041,6 +8041,8 @@ compile_for(char_u *arg_start, cctx_T *cctx)
} }
arg_end = arg; arg_end = arg;
if (cctx->ctx_skip != SKIP_YES)
{
// If we know the type of "var" and it is a not a supported type we can // If we know the type of "var" and it is a not a supported type we can
// give an error now. // give an error now.
vartype = ((type_T **)stack->ga_data)[stack->ga_len - 1]; vartype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
@@ -8187,6 +8189,7 @@ compile_for(char_u *arg_start, cctx_T *cctx)
generate_instr_debug(cctx); generate_instr_debug(cctx);
cctx->ctx_prev_lnum = save_prev_lnum; cctx->ctx_prev_lnum = save_prev_lnum;
} }
}
return arg_end; return arg_end;
@@ -8217,6 +8220,8 @@ compile_endfor(char_u *arg, cctx_T *cctx)
} }
forscope = &scope->se_u.se_for; forscope = &scope->se_u.se_for;
cctx->ctx_scope = scope->se_outer; cctx->ctx_scope = scope->se_outer;
if (cctx->ctx_skip != SKIP_YES)
{
unwind_locals(cctx, scope->se_local_count); unwind_locals(cctx, scope->se_local_count);
// At end of ":for" scope jump back to the FOR instruction. // At end of ":for" scope jump back to the FOR instruction.
@@ -8232,6 +8237,7 @@ compile_endfor(char_u *arg, cctx_T *cctx)
// Below the ":for" scope drop the "expr" list from the stack. // Below the ":for" scope drop the "expr" list from the stack.
if (generate_instr_drop(cctx, ISN_DROP, 1) == NULL) if (generate_instr_drop(cctx, ISN_DROP, 1) == NULL)
return NULL; return NULL;
}
vim_free(scope); vim_free(scope);