1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-22 12:57:34 +00:00

Shell: Make history index values not fitting in i32 a syntax error

A continuation of e3ec759.
Also found by oss-fuzz:
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=30405
This commit is contained in:
AnotherTest 2021-02-07 02:42:57 +03:30 committed by Andreas Kling
parent 885974fc3c
commit 5204c9062c

View file

@ -1373,7 +1373,7 @@ RefPtr<AST::Node> Parser::parse_history_designator()
// Event selector // Event selector
AST::HistorySelector selector; AST::HistorySelector selector;
RefPtr<AST::Node> syntax_error; RefPtr<AST::SyntaxError> syntax_error;
selector.event.kind = AST::HistorySelector::EventKind::StartingStringLookup; selector.event.kind = AST::HistorySelector::EventKind::StartingStringLookup;
selector.event.text_position = { m_offset, m_offset, m_line, m_line }; selector.event.text_position = { m_offset, m_offset, m_line, m_line };
selector.word_selector_range = { selector.word_selector_range = {
@ -1410,7 +1410,7 @@ RefPtr<AST::Node> Parser::parse_history_designator()
} }
selector.event.text = static_ptr_cast<AST::BarewordLiteral>(bareword)->text(); selector.event.text = static_ptr_cast<AST::BarewordLiteral>(bareword)->text();
selector.event.text_position = (bareword ?: syntax_error)->position(); selector.event.text_position = bareword->position();
auto it = selector.event.text.begin(); auto it = selector.event.text.begin();
bool is_negative = false; bool is_negative = false;
if (*it == '-') { if (*it == '-') {
@ -1422,14 +1422,22 @@ RefPtr<AST::Node> Parser::parse_history_designator()
selector.event.kind = AST::HistorySelector::EventKind::IndexFromEnd; selector.event.kind = AST::HistorySelector::EventKind::IndexFromEnd;
else else
selector.event.kind = AST::HistorySelector::EventKind::IndexFromStart; selector.event.kind = AST::HistorySelector::EventKind::IndexFromStart;
selector.event.index = abs(selector.event.text.to_int().value()); auto number = selector.event.text.to_int();
if (number.has_value())
selector.event.index = abs(number.value());
else
syntax_error = create<AST::SyntaxError>("History entry index value invalid or out of range");
} }
break; break;
} }
} }
if (peek() != ':') if (peek() != ':') {
return create<AST::HistoryEvent>(move(selector)); auto node = create<AST::HistoryEvent>(move(selector));
if (syntax_error)
node->set_is_syntax_error(*syntax_error);
return node;
}
consume(); consume();
@ -1445,14 +1453,14 @@ RefPtr<AST::Node> Parser::parse_history_designator()
AST::HistorySelector::WordSelectorKind::Index, AST::HistorySelector::WordSelectorKind::Index,
0, 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() },
create<AST::SyntaxError>("Word selector value invalid or out of range") syntax_error ? NonnullRefPtr(*syntax_error) : create<AST::SyntaxError>("Word selector value invalid or out of range")
}; };
} }
return AST::HistorySelector::WordSelector { return AST::HistorySelector::WordSelector {
AST::HistorySelector::WordSelectorKind::Index, AST::HistorySelector::WordSelectorKind::Index,
value.value(), 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 syntax_error
}; };
} }
if (c == '^') { if (c == '^') {
@ -1461,7 +1469,7 @@ RefPtr<AST::Node> Parser::parse_history_designator()
AST::HistorySelector::WordSelectorKind::Index, AST::HistorySelector::WordSelectorKind::Index,
0, 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 syntax_error
}; };
} }
if (c == '$') { if (c == '$') {
@ -1470,7 +1478,7 @@ RefPtr<AST::Node> Parser::parse_history_designator()
AST::HistorySelector::WordSelectorKind::Last, AST::HistorySelector::WordSelectorKind::Last,
0, 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 syntax_error
}; };
} }
return {}; return {};
@ -1478,9 +1486,10 @@ RefPtr<AST::Node> Parser::parse_history_designator()
auto start = parse_word_selector(); auto start = parse_word_selector();
if (!start.has_value()) { if (!start.has_value()) {
if (!syntax_error)
syntax_error = create<AST::SyntaxError>("Expected a word selector after ':' in a history event designator", true); syntax_error = create<AST::SyntaxError>("Expected a word selector after ':' in a history event designator", true);
auto node = create<AST::HistoryEvent>(move(selector)); auto node = create<AST::HistoryEvent>(move(selector));
node->set_is_syntax_error(syntax_error->syntax_error_node()); node->set_is_syntax_error(*syntax_error);
return node; return node;
} }
selector.word_selector_range.start = start.release_value(); selector.word_selector_range.start = start.release_value();
@ -1489,9 +1498,10 @@ RefPtr<AST::Node> Parser::parse_history_designator()
consume(); consume();
auto end = parse_word_selector(); auto end = parse_word_selector();
if (!end.has_value()) { if (!end.has_value()) {
if (!syntax_error)
syntax_error = create<AST::SyntaxError>("Expected a word selector after '-' in a history event designator word selector", true); syntax_error = create<AST::SyntaxError>("Expected a word selector after '-' in a history event designator word selector", true);
auto node = create<AST::HistoryEvent>(move(selector)); auto node = create<AST::HistoryEvent>(move(selector));
node->set_is_syntax_error(syntax_error->syntax_error_node()); node->set_is_syntax_error(*syntax_error);
return node; return node;
} }
selector.word_selector_range.end = move(end); selector.word_selector_range.end = move(end);
@ -1499,7 +1509,10 @@ RefPtr<AST::Node> Parser::parse_history_designator()
selector.word_selector_range.end.clear(); selector.word_selector_range.end.clear();
} }
return create<AST::HistoryEvent>(move(selector)); auto node = create<AST::HistoryEvent>(move(selector));
if (syntax_error)
node->set_is_syntax_error(*syntax_error);
return node;
} }
RefPtr<AST::Node> Parser::parse_comment() RefPtr<AST::Node> Parser::parse_comment()