From 1a10a4e9119c7de9eb236ee00dd759189f674fd8 Mon Sep 17 00:00:00 2001 From: mdecimus Date: Fri, 31 Jan 2025 14:07:07 +0100 Subject: [PATCH] Fix flag parsing (closes #1138) --- crates/imap-proto/src/parser/mod.rs | 46 +++++++++++++++------------ crates/imap-proto/src/parser/store.rs | 2 +- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/crates/imap-proto/src/parser/mod.rs b/crates/imap-proto/src/parser/mod.rs index b809c9b7..917946e3 100644 --- a/crates/imap-proto/src/parser/mod.rs +++ b/crates/imap-proto/src/parser/mod.rs @@ -152,34 +152,38 @@ impl Flag { } pub fn parse_datetime(value: &[u8]) -> Result { - let datetime = std::str::from_utf8(value) - .map_err(|_| Cow::from("Expected date/time, found an invalid UTF-8 string."))? - .trim(); - DateTime::parse_from_str(datetime, "%d-%b-%Y %H:%M:%S %z") - .map_err(|_| Cow::from(format!("Failed to parse date/time '{}'.", datetime))) - .map(|dt| dt.timestamp()) + std::str::from_utf8(value) + .map_err(|_| Cow::from("Expected date/time, found an invalid UTF-8 string.")) + .and_then(|datetime| { + DateTime::parse_from_str(datetime.trim(), "%d-%b-%Y %H:%M:%S %z") + .map_err(|_| Cow::from(format!("Failed to parse date/time '{}'.", datetime))) + .map(|dt| dt.timestamp()) + }) } pub fn parse_date(value: &[u8]) -> Result { - let date = std::str::from_utf8(value) - .map_err(|_| Cow::from("Expected date, found an invalid UTF-8 string."))? - .trim(); - NaiveDate::parse_from_str(date, "%d-%b-%Y") - .map_err(|_| Cow::from(format!("Failed to parse date '{}'.", date))) - .map(|dt| { - dt.and_hms_opt(0, 0, 0) - .unwrap_or_default() - .and_utc() - .timestamp() + std::str::from_utf8(value) + .map_err(|_| Cow::from("Expected date, found an invalid UTF-8 string.")) + .and_then(|date| { + NaiveDate::parse_from_str(date.trim(), "%d-%b-%Y") + .map_err(|_| Cow::from(format!("Failed to parse date '{}'.", date))) + .map(|dt| { + dt.and_hms_opt(0, 0, 0) + .unwrap_or_default() + .and_utc() + .timestamp() + }) }) } pub fn parse_number(value: &[u8]) -> Result { - let string = std::str::from_utf8(value) - .map_err(|_| Cow::from("Expected a number, found an invalid UTF-8 string."))?; - string - .parse::() - .map_err(|_| Cow::from(format!("Expected a number, found {:?}.", string))) + std::str::from_utf8(value) + .map_err(|_| Cow::from("Expected a number, found an invalid UTF-8 string.")) + .and_then(|string| { + string + .parse::() + .map_err(|_| Cow::from(format!("Expected a number, found {:?}.", string))) + }) } pub fn parse_sequence_set(value: &[u8]) -> Result { diff --git a/crates/imap-proto/src/parser/store.rs b/crates/imap-proto/src/parser/store.rs index 21eb553f..b07dfc42 100644 --- a/crates/imap-proto/src/parser/store.rs +++ b/crates/imap-proto/src/parser/store.rs @@ -64,7 +64,7 @@ impl Request { .next() .ok_or_else(|| bad(self.tag.to_string(), "Missing message data item name."))? .unwrap_bytes(); - let (is_silent, operation) = hashify::tiny_map!(operation.as_slice(), + let (is_silent, operation) = hashify::tiny_map_ignore_case!(operation.as_slice(), "FLAGS" => (false, Operation::Set), "FLAGS.SILENT" => (true, Operation::Set), "+FLAGS" => (false, Operation::Add),