From 054cf987548de59c96c8caff3a8f1efe26b535e0 Mon Sep 17 00:00:00 2001 From: holger krekel Date: Tue, 10 Dec 2019 00:26:46 +0100 Subject: [PATCH] try to work around mailparser not decoding rfc2047 displaynames this pulls in changes in our fork of rust-email to also correctly generate rfc2047 encoding --- Cargo.lock | 4 +++- Cargo.toml | 1 + src/dc_receive_imf.rs | 12 ++++++++++-- src/mimefactory.rs | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0ce738a5c..c864a0f09 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -656,6 +656,7 @@ dependencies = [ "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "debug_stub_derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "deltachat_derive 0.1.0", + "email 0.0.21 (git+https://github.com/deltachat/rust-email)", "encoded-words 0.1.0 (git+https://github.com/async-email/encoded-words)", "escaper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -827,10 +828,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "email" version = "0.0.21" -source = "git+https://github.com/deltachat/rust-email#265a54a8c31355c506610c032c81112dc0953afb" +source = "git+https://github.com/deltachat/rust-email#b71c13d7d9a599ebc811a8e2ca350e2793fe58d3" dependencies = [ "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "encoded-words 0.1.0 (git+https://github.com/async-email/encoded-words)", "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 119d6b92a..deb1bd7b8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ reqwest = { version = "0.9.15", default-features = false, features = ["rustls-tl num-derive = "0.2.5" num-traits = "0.2.6" async-smtp = { git = "https://github.com/async-email/async-smtp" } +email = { git = "https://github.com/deltachat/rust-email" } lettre_email = { git = "https://github.com/deltachat/lettre", branch = "feat/mail" } async-imap = { git = "https://github.com/async-email/async-imap", branch="master" } async-tls = "0.6" diff --git a/src/dc_receive_imf.rs b/src/dc_receive_imf.rs index 2b5e90393..e4d2524c1 100644 --- a/src/dc_receive_imf.rs +++ b/src/dc_receive_imf.rs @@ -1583,6 +1583,10 @@ fn dc_add_or_lookup_contacts_by_address_list( origin: Origin, to_ids: &mut ContactIds, ) -> Result<()> { + // XXX we use manual decoding + // https://github.com/staktrace/mailparse/issues/50 + use email::rfc2047::decode_rfc2047; + let addrs = match mailparse::addrparse(addr_list_raw) { Ok(addrs) => addrs, Err(err) => { @@ -1597,18 +1601,22 @@ fn dc_add_or_lookup_contacts_by_address_list( for addr in addrs.iter() { match addr { mailparse::MailAddr::Single(info) => { + // mailparse does not give us decoded vals + let display_name = decode_rfc2047(&info.display_name.clone().unwrap_or_default()); to_ids.insert(add_or_lookup_contact_by_addr( context, - &info.display_name, + &display_name, &info.addr, origin, )?); } mailparse::MailAddr::Group(infos) => { for info in &infos.addrs { + let display_name = + decode_rfc2047(&info.display_name.clone().unwrap_or_default()); to_ids.insert(add_or_lookup_contact_by_addr( context, - &info.display_name, + &display_name, &info.addr, origin, )?); diff --git a/src/mimefactory.rs b/src/mimefactory.rs index 833f7eda4..e7ee8b40e 100644 --- a/src/mimefactory.rs +++ b/src/mimefactory.rs @@ -1051,3 +1051,40 @@ pub fn needs_encoding(to_check: impl AsRef) -> bool { !c.is_ascii_alphanumeric() && c != '-' && c != '_' && c != '.' && c != '~' && c != '%' }) } + +#[cfg(test)] +mod tests { + use super::*; + use email::rfc2047::decode_rfc2047; + use mailparse::{addrparse, MailAddr}; + + #[test] + fn test_render_email_address() { + let display_name = "รค space"; + let addr = "x@y.org"; + + assert!(!display_name.is_ascii()); + + let s = format!( + "{}", + Address::new_mailbox_with_name(display_name.to_string(), addr.to_string()) + ); + + println!("{}", s); + assert!(s.is_ascii()); + + assert_eq!(s, "=?utf-8?q?=C3=A4_space?= "); + + match &addrparse(&s).unwrap()[0] { + MailAddr::Single(info) => { + // XXX addrparse should not return rfc2047 encoding + // but the decoded string, see + // https://github.com/staktrace/mailparse/issues/50 + let s = decode_rfc2047(&info.display_name.clone().unwrap()); + assert_eq!(s, Some(display_name.to_string())); + assert_eq!(info.addr, addr.to_string()); + } + _ => panic!(), + } + } +}