Browse Source

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 ;)
Valtteri Koskivuori 2 years ago
parent
commit
35f1cec7ca
2 changed files with 18 additions and 18 deletions
  1. 17 17
      Userland/Libraries/LibIMAP/Parser.cpp
  2. 1 1
      Userland/Libraries/LibIMAP/Parser.h

+ 17 - 17
Userland/Libraries/LibIMAP/Parser.cpp

@@ -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()) };
     }
     }
 }
 }
 }
 }

+ 1 - 1
Userland/Libraries/LibIMAP/Parser.h

@@ -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();