From cb79548c49d7144345a8c14c95475dd19dca5e8f Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Mon, 25 Oct 2021 12:22:51 -0700 Subject: [PATCH] Revert "break/continue: Stop checking if it's in a loop again" This reverts commit 61cd05efb0d9da46b49316be6343eb323ab5f817. It is true that we detect break and continue errors statically, but they can still be invoked dynamically, example: set sneaky break $sneaky # dynamically breaks from the loop or just `eval break`. A followup commit will add tests for this. --- src/builtin.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/builtin.cpp b/src/builtin.cpp index fcd65957d..78030a4d8 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -270,6 +270,21 @@ static maybe_t builtin_break_continue(parser_t &parser, io_streams_t &strea return STATUS_INVALID_ARGS; } + // Paranoia: ensure we have a real loop. + bool has_loop = false; + for (const auto &b : parser.blocks()) { + if (b.type() == block_type_t::while_block || b.type() == block_type_t::for_block) { + has_loop = true; + break; + } + if (b.is_function_call()) break; + } + if (!has_loop) { + wcstring error_message = format_string(_(L"%ls: Not inside of loop\n"), argv[0]); + builtin_print_help(parser, streams, argv[0], &error_message); + return STATUS_CMD_ERROR; + } + // Mark the status in the libdata. parser.libdata().loop_status = is_break ? loop_status_t::breaks : loop_status_t::continues; return STATUS_CMD_OK;