1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 04:27:44 +00:00

LibIMAP: Propagate errors from Parser::parse_number()

More error propagation is still needed, we really want the parser to
just crash early when it encounters unexpected input, instead of trying
to carry on like nothing happened.
I think ErrorOr<unsigned> is *much* better than returning (unsigned)-1
to indicate an error ;)
This commit is contained in:
Valtteri Koskivuori 2023-07-31 23:21:52 +03:00 committed by Andrew Kaster
parent 077a8058c3
commit 35f1cec7ca
2 changed files with 18 additions and 18 deletions

View file

@ -71,7 +71,7 @@ bool Parser::try_consume(StringView x)
void Parser::parse_response_done() void Parser::parse_response_done()
{ {
consume("A"sv); consume("A"sv);
auto tag = parse_number(); auto tag = MUST(parse_number());
consume(" "sv); consume(" "sv);
ResponseStatus status = parse_status(); ResponseStatus status = parse_status();
@ -119,12 +119,12 @@ Optional<unsigned> Parser::try_parse_number()
return number.to_uint(); return number.to_uint();
} }
unsigned Parser::parse_number() ErrorOr<unsigned> Parser::parse_number()
{ {
auto number = try_parse_number(); auto number = try_parse_number();
if (!number.has_value()) { if (!number.has_value()) {
m_parsing_failed = true; m_parsing_failed = true;
return -1; return Error::from_string_view("Failed to parse expected number"sv);
} }
return number.value(); return number.value();
@ -177,15 +177,15 @@ void Parser::parse_untagged()
// No-op. // No-op.
} else if (actual_type == "UIDNEXT"sv) { } else if (actual_type == "UIDNEXT"sv) {
consume(" "sv); consume(" "sv);
auto n = parse_number(); auto n = MUST(parse_number());
m_response.data().set_uid_next(n); m_response.data().set_uid_next(n);
} else if (actual_type == "UIDVALIDITY"sv) { } else if (actual_type == "UIDVALIDITY"sv) {
consume(" "sv); consume(" "sv);
auto n = parse_number(); auto n = MUST(parse_number());
m_response.data().set_uid_validity(n); m_response.data().set_uid_validity(n);
} else if (actual_type == "UNSEEN"sv) { } else if (actual_type == "UNSEEN"sv) {
consume(" "sv); consume(" "sv);
auto n = parse_number(); auto n = MUST(parse_number());
m_response.data().set_unseen(n); m_response.data().set_unseen(n);
} else if (actual_type == "PERMANENTFLAGS"sv) { } else if (actual_type == "PERMANENTFLAGS"sv) {
consume(" "sv); consume(" "sv);
@ -193,7 +193,7 @@ void Parser::parse_untagged()
m_response.data().set_permanent_flags(move(flags)); m_response.data().set_permanent_flags(move(flags));
} else if (actual_type == "HIGHESTMODSEQ"sv) { } else if (actual_type == "HIGHESTMODSEQ"sv) {
consume(" "sv); consume(" "sv);
parse_number(); MUST(parse_number());
// No-op for now. // No-op for now.
} else { } else {
dbgln("Unknown: {}", actual_type); dbgln("Unknown: {}", actual_type);
@ -207,7 +207,7 @@ void Parser::parse_untagged()
Vector<unsigned> ids; Vector<unsigned> ids;
while (!try_consume("\r\n"sv)) { while (!try_consume("\r\n"sv)) {
consume(" "sv); consume(" "sv);
auto id = parse_number(); auto id = MUST(parse_number());
ids.append(id); ids.append(id);
} }
m_response.data().set_search_results(move(ids)); m_response.data().set_search_results(move(ids));
@ -224,7 +224,7 @@ void Parser::parse_untagged()
while (!try_consume(")"sv)) { while (!try_consume(")"sv)) {
auto status_att = parse_atom(); auto status_att = parse_atom();
consume(" "sv); consume(" "sv);
auto value = parse_number(); auto value = MUST(parse_number());
auto type = StatusItemType::Recent; auto type = StatusItemType::Recent;
if (status_att == "MESSAGES"sv) { if (status_att == "MESSAGES"sv) {
@ -318,7 +318,7 @@ FetchResponseData Parser::parse_fetch_response()
} }
case FetchCommand::DataItemType::UID: { case FetchCommand::DataItemType::UID: {
consume(" "sv); consume(" "sv);
fetch_response.set_uid(parse_number()); fetch_response.set_uid(MUST(parse_number()));
break; break;
} }
case FetchCommand::DataItemType::PeekBody: case FetchCommand::DataItemType::PeekBody:
@ -439,9 +439,9 @@ BodyStructure Parser::parse_one_part_body()
consume(" "sv); consume(" "sv);
auto encoding = parse_string(); auto encoding = parse_string();
consume(" "sv); consume(" "sv);
auto num_octets = parse_number(); auto num_octets = MUST(parse_number());
consume(" "sv); consume(" "sv);
auto num_lines = parse_number(); auto num_lines = MUST(parse_number());
auto data = BodyStructureData { auto data = BodyStructureData {
type, type,
@ -501,7 +501,7 @@ BodyStructure Parser::parse_one_part_body()
consume(" "sv); consume(" "sv);
auto encoding = parse_string(); auto encoding = parse_string();
consume(" "sv); consume(" "sv);
auto num_octets = parse_number(); auto num_octets = MUST(parse_number());
consume(" "sv); consume(" "sv);
auto envelope = parse_envelope(); auto envelope = parse_envelope();
@ -528,7 +528,7 @@ BodyStructure Parser::parse_one_part_body()
consume(" "sv); consume(" "sv);
auto encoding = parse_string(); auto encoding = parse_string();
consume(" "sv); consume(" "sv);
auto num_octets = parse_number(); auto num_octets = MUST(parse_number());
consume(" "sv); consume(" "sv);
BodyStructureData data { BodyStructureData data {
@ -572,7 +572,7 @@ StringView Parser::parse_literal_string()
{ {
dbgln_if(IMAP_PARSER_DEBUG, "p: {}, parse_literal_string()", m_position); dbgln_if(IMAP_PARSER_DEBUG, "p: {}, parse_literal_string()", m_position);
consume("{"sv); consume("{"sv);
auto num_bytes = parse_number(); auto num_bytes = MUST(parse_number());
consume("}\r\n"sv); consume("}\r\n"sv);
if (m_buffer.size() < m_position + num_bytes) { if (m_buffer.size() < m_position + num_bytes) {
@ -772,7 +772,7 @@ FetchCommand::DataItem Parser::parse_fetch_data_item()
m_parsing_failed = true; m_parsing_failed = true;
} }
if (try_consume("<"sv)) { if (try_consume("<"sv)) {
auto start = parse_number(); auto start = MUST(parse_number());
data_item.partial_fetch = true; data_item.partial_fetch = true;
data_item.start = (int)start; data_item.start = (int)start;
consume(">"sv); consume(">"sv);
@ -876,7 +876,7 @@ BodyExtension Parser::parse_body_extension()
} else if (!at_end() && (m_buffer[m_position] == '"' || m_buffer[m_position] == '{')) { } else if (!at_end() && (m_buffer[m_position] == '"' || m_buffer[m_position] == '{')) {
return BodyExtension { { parse_string() } }; return BodyExtension { { parse_string() } };
} else { } else {
return BodyExtension { parse_number() }; return BodyExtension { MUST(parse_number()) };
} }
} }
} }

View file

@ -32,7 +32,7 @@ private:
bool at_end() { return m_position >= m_buffer.size(); } bool at_end() { return m_position >= m_buffer.size(); }
unsigned parse_number(); ErrorOr<unsigned> parse_number();
Optional<unsigned> try_parse_number(); Optional<unsigned> try_parse_number();
void parse_response_done(); void parse_response_done();