From 144fd744f3ce7106746646efa141e55d5a0e6d1f Mon Sep 17 00:00:00 2001 From: Robsdedude Date: Thu, 2 Nov 2023 11:05:29 +0100 Subject: [PATCH] Metadata: escape display name in email addresses --- src/metadata.rs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/metadata.rs b/src/metadata.rs index f8fa70d59..60b273a96 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -226,7 +226,7 @@ impl Metadata21 { for author in authors { match (&author.name, &author.email) { (Some(name), Some(email)) => { - emails.push(format!("{name} <{email}>")); + emails.push(format_email_with_display_name(name, email)); } (Some(name), None) => { names.push(name.as_str()); @@ -251,7 +251,7 @@ impl Metadata21 { for maintainer in maintainers { match (&maintainer.name, &maintainer.email) { (Some(name), Some(email)) => { - emails.push(format!("{name} <{email}>")); + emails.push(format_email_with_display_name(name, email)); } (Some(name), None) => { names.push(name.as_str()); @@ -555,6 +555,23 @@ impl Metadata21 { } } +/// Escape email addresses with display name if necessary +/// according to RFC 822 Section 3.3. "specials". +fn format_email_with_display_name(mut display_name: &str, email: &str) -> String { + if display_name.chars().any(|c| { + matches!( + c, + '(' | ')' | '<' | '>' | '@' | ',' | ';' | ':' | '\\' | '"' | '.' | '[' | ']' + ) + }) { + return format!( + "\"{}\" <{email}>", + display_name.replace("\\", "\\\\").replace("\"", "\\\"") + ); + } + format!("{display_name} <{email}>") +} + /// Fold long header field according to RFC 5322 section 2.2.3 /// https://datatracker.ietf.org/doc/html/rfc5322#section-2.2.3 fn fold_header(text: &str) -> String {