From 28deba708c464ee8bacb62b890e7d9422127f6d1 Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Sun, 20 Sep 2020 13:35:04 +0300 Subject: [PATCH] melib/imap: check if FETCH reply was intended for us After sending a FETCH, the command results might be mixed with unsolicited FETCH replies. Check if that happens. --- melib/src/backends/imap.rs | 10 ++++++++++ melib/src/backends/imap/cache.rs | 1 + melib/src/backends/imap/protocol_parser.rs | 9 +++++++-- melib/src/backends/imap/untagged.rs | 1 + 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/melib/src/backends/imap.rs b/melib/src/backends/imap.rs index 219946e4..1358727e 100644 --- a/melib/src/backends/imap.rs +++ b/melib/src/backends/imap.rs @@ -1695,9 +1695,19 @@ async fn fetch_hlpr(state: &mut FetchState) -> Result> { ref uid, ref mut envelope, ref mut flags, + ref raw_fetch_value, .. } in v.iter_mut() { + if uid.is_none() || envelope.is_none() || flags.is_none() { + debug!("in fetch is none"); + debug!(uid); + debug!(envelope); + debug!(flags); + debug!("response was: {}", String::from_utf8_lossy(&response)); + debug!(conn.process_untagged(raw_fetch_value).await)?; + continue; + } let uid = uid.unwrap(); let env = envelope.as_mut().unwrap(); env.set_hash(generate_envelope_hash(&mailbox_path, &uid)); diff --git a/melib/src/backends/imap/cache.rs b/melib/src/backends/imap/cache.rs index d89512f2..d27c474e 100644 --- a/melib/src/backends/imap/cache.rs +++ b/melib/src/backends/imap/cache.rs @@ -446,6 +446,7 @@ mod sqlite3_m { flags: _, body: _, envelope: Some(envelope), + raw_fetch_value: _, } = item { max_uid = std::cmp::max(max_uid, *uid); diff --git a/melib/src/backends/imap/protocol_parser.rs b/melib/src/backends/imap/protocol_parser.rs index ef38ab44..6010e52c 100644 --- a/melib/src/backends/imap/protocol_parser.rs +++ b/melib/src/backends/imap/protocol_parser.rs @@ -465,6 +465,7 @@ pub struct FetchResponse<'a> { pub flags: Option<(Flag, Vec)>, pub body: Option<&'a [u8]>, pub envelope: Option, + pub raw_fetch_value: &'a [u8], } pub fn fetch_response(input: &[u8]) -> ImapParseResult> { @@ -520,6 +521,7 @@ pub fn fetch_response(input: &[u8]) -> ImapParseResult> { flags: None, body: None, envelope: None, + raw_fetch_value: &[], }; while input[i].is_ascii_digit() { @@ -629,6 +631,7 @@ pub fn fetch_response(input: &[u8]) -> ImapParseResult> { )))); } } + ret.raw_fetch_value = &input[..i]; if let Some(env) = ret.envelope.as_mut() { env.set_has_attachments(has_attachments); @@ -877,7 +880,8 @@ fn test_untagged_responses() { modseq: Some(ModSequence(std::num::NonZeroU64::new(1365_u64).unwrap())), flags: Some((Flag::SEEN, vec![])), body: None, - envelope: None + envelope: None, + raw_fetch_value: &b"* 1079 FETCH (UID 1103 MODSEQ (1365) FLAGS (\\Seen))\r\n"[..], }) ); assert_eq!( @@ -891,7 +895,8 @@ fn test_untagged_responses() { modseq: None, flags: Some((Flag::SEEN, vec![])), body: None, - envelope: None + envelope: None, + raw_fetch_value: &b"* 1 FETCH (FLAGS (\\Seen))\r\n"[..], }) ); } diff --git a/melib/src/backends/imap/untagged.rs b/melib/src/backends/imap/untagged.rs index 021fa28b..536b18b3 100644 --- a/melib/src/backends/imap/untagged.rs +++ b/melib/src/backends/imap/untagged.rs @@ -357,6 +357,7 @@ impl ImapConnection { flags, body: _, envelope: _, + raw_fetch_value: _, }) => { if let Some(flags) = flags { let uid = if let Some(uid) = uid {