From 353f1dc77db5c16a7e3324632f76870d8ec17024 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jagoda=20Estera=20=C5=9Al=C4=85zak?= <128227338+j-g00da@users.noreply.github.com> Date: Wed, 21 Jan 2026 14:06:20 +0100 Subject: [PATCH] fix: Improve address extraction from SMTP commands (#14) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prevents extraction failing on SRS. Fixes: #9 Signed-off-by: Jagoda Ślązak --- filtermail/src/utils.rs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/filtermail/src/utils.rs b/filtermail/src/utils.rs index 526339e1..356270c7 100644 --- a/filtermail/src/utils.rs +++ b/filtermail/src/utils.rs @@ -7,20 +7,15 @@ use std::error::Error; /// /// Returns the first address if multiple are present. pub fn extract_address(input: &str) -> Option { - // TODO: at this point it's probably simpler to use regex ;p let input_lower = input.to_lowercase(); let mut trimmed = input_lower .trim_start_matches("mail from:") .trim_start_matches("rcpt to:"); + + let addr_end = trimmed.find('>').unwrap_or(trimmed.len() - 1); trimmed = trimmed - .split_once("=") - .map(|(address_raw, _)| { - address_raw - .rsplit_once(' ') - .map(|(addr, _)| addr) - .unwrap_or(address_raw) - .trim() - }) + .split_at_checked(addr_end + 1) + .map(|(address_raw, _)| address_raw) .unwrap_or(trimmed); mailparse::addrparse(trimmed) @@ -63,6 +58,8 @@ mod tests { #[rstest] #[case("MAIL FROM:", Some("t1@example.org".to_string()))] #[case("MAIL FROM: SOMETHING=SOMETHING OTHER=OTHER", Some("t2@example.org".to_string()))] + #[case("MAIL FROM: abc=def", Some("srs1=hhh=example.com==hhh=tt=example.org=alice@example.net".to_string()))] + #[case("MAIL FROM: abc=def", Some("abc+alice@example.net".to_string()))] #[case("RCPT TO:", Some("t3@example.org".to_string()))] #[case("mail from:", Some("t4@example.org".to_string()))] #[case("Foo Bar ", Some("t5@example.org".to_string()))]