From 5daf5d397ad23c05e6891a8cde13df36a2ffce87 Mon Sep 17 00:00:00 2001 From: Paolo Barbolini Date: Tue, 26 Apr 2022 12:18:12 +0200 Subject: [PATCH] Fix parsing Mailboxes with a comma in the name (#760) --- src/message/header/mailbox.rs | 27 ++++++++++++++++++++++++++ src/message/mailbox/types.rs | 36 ++++++++++++++++++++++++++++++----- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/src/message/header/mailbox.rs b/src/message/header/mailbox.rs index 9c17e13..05fa41a 100644 --- a/src/message/header/mailbox.rs +++ b/src/message/header/mailbox.rs @@ -296,4 +296,31 @@ mod test { assert_eq!(headers.get::(), Some(From(from.into()))); } + + #[test] + fn parse_multi_with_name_containing_comma() { + let from: Vec = vec![ + "Test, test <1@example.com>".parse().unwrap(), + "Test2, test2 <2@example.com>".parse().unwrap(), + ]; + + let mut headers = Headers::new(); + headers.insert_raw(HeaderValue::new( + HeaderName::new_from_ascii_str("From"), + "Test, test <1@example.com>, Test2, test2 <2@example.com>".to_string(), + )); + + assert_eq!(headers.get::(), Some(From(from.into()))); + } + + #[test] + fn parse_multi_with_name_containing_comma_last_broken() { + let mut headers = Headers::new(); + headers.insert_raw(HeaderValue::new( + HeaderName::new_from_ascii_str("From"), + "Test, test <1@example.com>, Test2, test2".to_string(), + )); + + assert_eq!(headers.get::(), None); + } } diff --git a/src/message/mailbox/types.rs b/src/message/mailbox/types.rs index abbf1db..64b1952 100644 --- a/src/message/mailbox/types.rs +++ b/src/message/mailbox/types.rs @@ -352,11 +352,37 @@ impl Display for Mailboxes { impl FromStr for Mailboxes { type Err = AddressError; - fn from_str(src: &str) -> Result { - src.split(',') - .map(|m| m.trim().parse()) - .collect::, _>>() - .map(Mailboxes) + fn from_str(mut src: &str) -> Result { + let mut mailboxes = Vec::new(); + + if !src.is_empty() { + // n-1 elements + let mut skip = 0; + while let Some(i) = src[skip..].find(',') { + let left = &src[..skip + i]; + + match left.trim().parse() { + Ok(mailbox) => { + mailboxes.push(mailbox); + + src = &src[left.len() + ",".len()..]; + skip = 0; + } + Err(AddressError::MissingParts) => { + skip = left.len() + ",".len(); + } + Err(err) => { + return Err(err); + } + } + } + + // last element + let mailbox = src.trim().parse()?; + mailboxes.push(mailbox); + } + + Ok(Mailboxes(mailboxes)) } }