From e4bd5a5d69e23c79fee71506eed4b866ea6e0dc3 Mon Sep 17 00:00:00 2001 From: AnotherTest Date: Sun, 29 Nov 2020 16:18:13 +0330 Subject: [PATCH] Shell: Fix some at_end() bugs and use syntax errors instead of asserting ...in cases where the assert can be directly caused by user input. --- Shell/Parser.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/Shell/Parser.cpp b/Shell/Parser.cpp index a6a59f5412e..d7d173cb98e 100644 --- a/Shell/Parser.cpp +++ b/Shell/Parser.cpp @@ -39,7 +39,7 @@ Parser::SavedOffset Parser::save_offset() const char Parser::peek() { - if (m_offset == m_input.length()) + if (at_end()) return 0; ASSERT(m_offset < m_input.length()); @@ -57,6 +57,9 @@ char Parser::peek() char Parser::consume() { + if (at_end()) + return 0; + auto ch = peek(); ++m_offset; @@ -142,7 +145,8 @@ RefPtr Parser::parse() if (m_offset < m_input.length()) { // Parsing stopped midway, this is a syntax error. auto error_start = push_start(); - consume_while([](auto) { return true; }); + while (!at_end()) + consume(); auto syntax_error_node = create("Unexpected tokens past the end"); if (!toplevel) toplevel = move(syntax_error_node); @@ -844,8 +848,7 @@ RefPtr Parser::parse_redirection() pipe_fd = -1; } else { auto fd = number.to_int(); - ASSERT(fd.has_value()); - pipe_fd = fd.value(); + pipe_fd = fd.value_or(-1); } switch (peek()) { @@ -1379,8 +1382,12 @@ RefPtr Parser::parse_glob() } else if (glob_after->is_bareword()) { auto bareword = static_cast(glob_after.ptr()); textbuilder.append(bareword->text()); + } else if (glob_after->is_tilde()) { + auto bareword = static_cast(glob_after.ptr()); + textbuilder.append("~"); + textbuilder.append(bareword->text()); } else { - ASSERT_NOT_REACHED(); + return create(String::formatted("Invalid node '{}' in glob position, escape shell special characters", glob_after->class_name())); } } @@ -1447,6 +1454,9 @@ RefPtr Parser::parse_brace_expansion_spec() StringView Parser::consume_while(Function condition) { + if (at_end()) + return {}; + auto start_offset = m_offset; while (!at_end() && condition(peek()))