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.
This commit is contained in:
AnotherTest 2020-11-29 16:18:13 +03:30 committed by Andreas Kling
parent 4d7ba50dc7
commit e4bd5a5d69
Notes: sideshowbarker 2024-07-19 01:12:07 +09:00

View File

@ -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<AST::Node> 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<AST::SyntaxError>("Unexpected tokens past the end");
if (!toplevel)
toplevel = move(syntax_error_node);
@ -844,8 +848,7 @@ RefPtr<AST::Node> 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<AST::Node> Parser::parse_glob()
} else if (glob_after->is_bareword()) {
auto bareword = static_cast<AST::BarewordLiteral*>(glob_after.ptr());
textbuilder.append(bareword->text());
} else if (glob_after->is_tilde()) {
auto bareword = static_cast<AST::Tilde*>(glob_after.ptr());
textbuilder.append("~");
textbuilder.append(bareword->text());
} else {
ASSERT_NOT_REACHED();
return create<AST::SyntaxError>(String::formatted("Invalid node '{}' in glob position, escape shell special characters", glob_after->class_name()));
}
}
@ -1447,6 +1454,9 @@ RefPtr<AST::Node> Parser::parse_brace_expansion_spec()
StringView Parser::consume_while(Function<bool(char)> condition)
{
if (at_end())
return {};
auto start_offset = m_offset;
while (!at_end() && condition(peek()))