Shell: Make history range values larger than u32 a syntax error

Found by oss-fuzz:
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=29792&sort=reported&q=serenity
This commit is contained in:
AnotherTest 2021-02-02 20:20:05 +03:30 committed by Andreas Kling
parent d4dd4a82bb
commit e3ec759f97
3 changed files with 28 additions and 5 deletions

View file

@ -1364,6 +1364,10 @@ HistoryEvent::HistoryEvent(Position position, HistorySelector selector)
: Node(move(position))
, m_selector(move(selector))
{
if (m_selector.word_selector_range.start.syntax_error_node)
set_is_syntax_error(*m_selector.word_selector_range.start.syntax_error_node);
else if (m_selector.word_selector_range.end.has_value() && m_selector.word_selector_range.end->syntax_error_node)
set_is_syntax_error(*m_selector.word_selector_range.end->syntax_error_node);
}
HistoryEvent::~HistoryEvent()

View file

@ -908,6 +908,7 @@ struct HistorySelector {
WordSelectorKind kind { Index };
size_t selector { 0 };
Position position;
RefPtr<AST::SyntaxError> syntax_error_node;
size_t resolve(size_t size) const
{

View file

@ -1377,9 +1377,16 @@ RefPtr<AST::Node> Parser::parse_history_designator()
selector.event.kind = AST::HistorySelector::EventKind::StartingStringLookup;
selector.event.text_position = { m_offset, m_offset, m_line, m_line };
selector.word_selector_range = {
{ AST::HistorySelector::WordSelectorKind::Index, 0, { m_offset, m_offset, m_line, m_line } },
AST::HistorySelector::WordSelector {
AST::HistorySelector::WordSelectorKind::Last, 0, { m_offset, m_offset, m_line, m_line } },
AST::HistorySelector::WordSelectorKind::Index,
0,
{ m_offset, m_offset, m_line, m_line },
nullptr },
AST::HistorySelector::WordSelector {
AST::HistorySelector::WordSelectorKind::Last,
0,
{ m_offset, m_offset, m_line, m_line },
nullptr }
};
switch (peek()) {
@ -1433,10 +1440,19 @@ RefPtr<AST::Node> Parser::parse_history_designator()
if (isdigit(c)) {
auto num = consume_while(is_digit);
auto value = num.to_uint();
if (!value.has_value()) {
return AST::HistorySelector::WordSelector {
AST::HistorySelector::WordSelectorKind::Index,
0,
{ m_rule_start_offsets.last(), m_offset, m_rule_start_lines.last(), line() },
create<AST::SyntaxError>("Word selector value invalid or out of range")
};
}
return AST::HistorySelector::WordSelector {
AST::HistorySelector::WordSelectorKind::Index,
value.value(),
{ m_rule_start_offsets.last(), m_offset, m_rule_start_lines.last(), line() }
{ m_rule_start_offsets.last(), m_offset, m_rule_start_lines.last(), line() },
nullptr
};
}
if (c == '^') {
@ -1444,7 +1460,8 @@ RefPtr<AST::Node> Parser::parse_history_designator()
return AST::HistorySelector::WordSelector {
AST::HistorySelector::WordSelectorKind::Index,
0,
{ m_rule_start_offsets.last(), m_offset, m_rule_start_lines.last(), line() }
{ m_rule_start_offsets.last(), m_offset, m_rule_start_lines.last(), line() },
nullptr
};
}
if (c == '$') {
@ -1452,7 +1469,8 @@ RefPtr<AST::Node> Parser::parse_history_designator()
return AST::HistorySelector::WordSelector {
AST::HistorySelector::WordSelectorKind::Last,
0,
{ m_rule_start_offsets.last(), m_offset, m_rule_start_lines.last(), line() }
{ m_rule_start_offsets.last(), m_offset, m_rule_start_lines.last(), line() },
nullptr
};
}
return {};