From 0e3b8f54d9da51c4c19c2bb4193e09c8946de1a6 Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Wed, 8 May 2019 18:00:35 +0300 Subject: [PATCH] melib: fix address_spec parse without displayname addresses like "" were parsed as "ser@domain.tld". Fix this by checking for displayname length. --- melib/src/mailbox/email.rs | 4 +- melib/src/mailbox/email/compose.rs | 2 +- melib/src/mailbox/email/parser.rs | 85 ++++++++++++++++++++++-------- 3 files changed, 67 insertions(+), 24 deletions(-) diff --git a/melib/src/mailbox/email.rs b/melib/src/mailbox/email.rs index 9152dcf6c..ee42ae505 100644 --- a/melib/src/mailbox/email.rs +++ b/melib/src/mailbox/email.rs @@ -101,10 +101,10 @@ impl PartialEq for Address { false } (Address::Mailbox(s), Address::Mailbox(o)) => { - s.address_spec.display(&s.raw) == o.address_spec.display(&o.raw) + s.address_spec.display_bytes(&s.raw) == o.address_spec.display_bytes(&o.raw) } (Address::Group(s), Address::Group(o)) => { - s.display_name.display(&s.raw) == o.display_name.display(&o.raw) + s.display_name.display_bytes(&s.raw) == o.display_name.display_bytes(&o.raw) && s.mailbox_list .iter() .zip(o.mailbox_list.iter()) diff --git a/melib/src/mailbox/email/compose.rs b/melib/src/mailbox/email/compose.rs index 6853a703f..7037a476e 100644 --- a/melib/src/mailbox/email/compose.rs +++ b/melib/src/mailbox/email/compose.rs @@ -279,8 +279,8 @@ fn ignore_header(header: &[u8]) -> bool { #[cfg(test)] mod tests { - use super::*; + use std::str::FromStr; #[test] fn test_new() { diff --git a/melib/src/mailbox/email/parser.rs b/melib/src/mailbox/email/parser.rs index 3be808e84..a75b16fc7 100644 --- a/melib/src/mailbox/email/parser.rs +++ b/melib/src/mailbox/email/parser.rs @@ -335,22 +335,24 @@ fn display_addr(input: &[u8]) -> IResult<&[u8], Address> { } } if flag { - let mut address_spec = StrBuilder { - offset: display_name.length + 2, - length: end, - }; match phrase(&input[0..end + display_name.length + 3]) { IResult::Error(e) => IResult::Error(e), IResult::Incomplete(i) => IResult::Incomplete(i), - IResult::Done(rest, raw) => { + IResult::Done(_, raw) => { display_name.length = raw.find(b"<").unwrap().saturating_sub(1); - address_spec.offset = display_name.length + 2; - address_spec.length = raw - .len() - .saturating_sub(display_name.length) - .saturating_sub(3); + let address_spec = if display_name.length == 0 { + StrBuilder { + offset: raw.find(b"<").map(|v| v + 1).unwrap_or(0), + length: end + 1, + } + } else { + StrBuilder { + offset: display_name.length + 2, + length: end, + } + }; IResult::Done( - rest, + &input[end + display_name.length + 3..], Address::Mailbox(MailboxAddress { raw, display_name, @@ -704,7 +706,7 @@ pub fn phrase(input: &[u8]) -> IResult<&[u8], Vec> { acc.push(b' '); } } - IResult::Done(&[], acc) + IResult::Done(&input[ptr..], acc) } #[cfg(test)] @@ -746,19 +748,61 @@ mod tests { =?iso-8859-7?b?U2VnIGZhdWx0IPP05+0g5er03evl8+cg9O/1?= =?iso-8859-7?q?_example_ru_n_=5Fsniper?="; - //TODO Fix this assert!( - "Re: [Advcomparch] Seg fault στην εκτέλεση του example run_sniper" + "Re: [Advcomparch] Seg fault στην εκτέλεση του example ru n _sniper" == std::str::from_utf8(&phrase(words).to_full_result().unwrap()).unwrap() ); } + macro_rules! make_address { + ($d:literal, $a:literal) => { + Address::Mailbox(if $d.is_empty() { + MailboxAddress { + raw: format!("<{}>", $a).into_bytes(), + display_name: StrBuilder { + offset: 0, + length: 0, + }, + address_spec: StrBuilder { + offset: 1, + length: $a.len(), + }, + } + } else { + MailboxAddress { + raw: format!("{} <{}>", $d, $a).into_bytes(), + display_name: StrBuilder { + offset: 0, + length: $d.len(), + }, + address_spec: StrBuilder { + offset: $d.len() + 2, + length: $a.len(), + }, + } + }) + }; + } + #[test] - fn test_address() { + fn test_address_list() { let s = b"Obit Oppidum , list , list2 , - Bobit Boppidum , Cobit Coppidum "; - println!("{:?}", rfc2822address_list(s).unwrap()); + Bobit Boppidum , Cobit Coppidum , "; + assert_eq!( + ( + &s[0..0], + vec![ + make_address!("Obit Oppidum", "user@domain"), + make_address!("list", "list@domain.tld"), + make_address!("list2", "list2@domain.tld"), + make_address!("Bobit Boppidum", "user@otherdomain.com"), + make_address!("Cobit Coppidum", "user2@otherdomain.com"), + make_address!("", "user@domain.tld") + ] + ), + rfc2822address_list(s).unwrap() + ); } #[test] @@ -775,11 +819,10 @@ mod tests { fn test_attachments() { use std::io::Read; let mut buffer: Vec = Vec::new(); - let _ = std::fs::File::open("./attachment_test") - .unwrap() - .read_to_end(&mut buffer); + //FIXME: add file + return; + let _ = std::fs::File::open("").unwrap().read_to_end(&mut buffer); let boundary = b"b1_4382d284f0c601a737bb32aaeda53160"; - let boundary_len = boundary.len(); let (_, body) = match mail(&buffer).to_full_result() { Ok(v) => v, Err(_) => panic!(),