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.
jmap-eventsource
Manos Pitsidianakis 2020-09-20 13:35:04 +03:00
parent a187cee1d3
commit 28deba708c
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
4 changed files with 19 additions and 2 deletions

View File

@ -1695,9 +1695,19 @@ async fn fetch_hlpr(state: &mut FetchState) -> Result<Vec<Envelope>> {
ref uid, ref uid,
ref mut envelope, ref mut envelope,
ref mut flags, ref mut flags,
ref raw_fetch_value,
.. ..
} in v.iter_mut() } 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 uid = uid.unwrap();
let env = envelope.as_mut().unwrap(); let env = envelope.as_mut().unwrap();
env.set_hash(generate_envelope_hash(&mailbox_path, &uid)); env.set_hash(generate_envelope_hash(&mailbox_path, &uid));

View File

@ -446,6 +446,7 @@ mod sqlite3_m {
flags: _, flags: _,
body: _, body: _,
envelope: Some(envelope), envelope: Some(envelope),
raw_fetch_value: _,
} = item } = item
{ {
max_uid = std::cmp::max(max_uid, *uid); max_uid = std::cmp::max(max_uid, *uid);

View File

@ -465,6 +465,7 @@ pub struct FetchResponse<'a> {
pub flags: Option<(Flag, Vec<String>)>, pub flags: Option<(Flag, Vec<String>)>,
pub body: Option<&'a [u8]>, pub body: Option<&'a [u8]>,
pub envelope: Option<Envelope>, pub envelope: Option<Envelope>,
pub raw_fetch_value: &'a [u8],
} }
pub fn fetch_response(input: &[u8]) -> ImapParseResult<FetchResponse<'_>> { pub fn fetch_response(input: &[u8]) -> ImapParseResult<FetchResponse<'_>> {
@ -520,6 +521,7 @@ pub fn fetch_response(input: &[u8]) -> ImapParseResult<FetchResponse<'_>> {
flags: None, flags: None,
body: None, body: None,
envelope: None, envelope: None,
raw_fetch_value: &[],
}; };
while input[i].is_ascii_digit() { while input[i].is_ascii_digit() {
@ -629,6 +631,7 @@ pub fn fetch_response(input: &[u8]) -> ImapParseResult<FetchResponse<'_>> {
)))); ))));
} }
} }
ret.raw_fetch_value = &input[..i];
if let Some(env) = ret.envelope.as_mut() { if let Some(env) = ret.envelope.as_mut() {
env.set_has_attachments(has_attachments); env.set_has_attachments(has_attachments);
@ -877,7 +880,8 @@ fn test_untagged_responses() {
modseq: Some(ModSequence(std::num::NonZeroU64::new(1365_u64).unwrap())), modseq: Some(ModSequence(std::num::NonZeroU64::new(1365_u64).unwrap())),
flags: Some((Flag::SEEN, vec![])), flags: Some((Flag::SEEN, vec![])),
body: None, body: None,
envelope: None envelope: None,
raw_fetch_value: &b"* 1079 FETCH (UID 1103 MODSEQ (1365) FLAGS (\\Seen))\r\n"[..],
}) })
); );
assert_eq!( assert_eq!(
@ -891,7 +895,8 @@ fn test_untagged_responses() {
modseq: None, modseq: None,
flags: Some((Flag::SEEN, vec![])), flags: Some((Flag::SEEN, vec![])),
body: None, body: None,
envelope: None envelope: None,
raw_fetch_value: &b"* 1 FETCH (FLAGS (\\Seen))\r\n"[..],
}) })
); );
} }

View File

@ -357,6 +357,7 @@ impl ImapConnection {
flags, flags,
body: _, body: _,
envelope: _, envelope: _,
raw_fetch_value: _,
}) => { }) => {
if let Some(flags) = flags { if let Some(flags) = flags {
let uid = if let Some(uid) = uid { let uid = if let Some(uid) = uid {