Using a for loop in interactive mode will crash because `state.ctx` is empty.
An implied for loop over $*, like `for (arg) echo $arg` would crash as well
because $* is not set in interactive mode.
---
interp/exec.ha | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/interp/exec.ha b/interp/exec.ha
index fafa10a..5965e5a 100644
--- a/interp/exec.ha
+++ b/interp/exec.ha
@@ -262,8 +262,9 @@ fn exec_for_loop(state: *state, cmd: *ast::for_loop) (int | error) = {
defer strings::freeall(iter);
if (len(cmd.values) == 0) {
- const args = get(state, "*") as *variable;
- iter = value_reduce(&args.value);
+ const args = get(state, "*");
+ if (args != null)
+ iter = value_reduce(&(args: *variable).value);
i = 1z;
} else {
let args: []value = [];
@@ -276,7 +277,10 @@ fn exec_for_loop(state: *state, cmd: *ast::for_loop) (int | error) = {
iter = value_reduce(&(args: value));
};
- let ctx = pushctx(state, context_type::LOOP, state.ctx[0].args);
+ let ctx = if (len(state.ctx) > 0)
+ pushctx(state, context_type::LOOP, state.ctx[0].args)
+ else
+ pushctx(state, context_type::LOOP, []);
defer popctx(state);
let st = 0;
--
2.42.0