From 954476ac84bcb80d554ad7043b8525d3987929e1 Mon Sep 17 00:00:00 2001 From: SanderBaan Date: Wed, 11 Mar 2026 17:32:27 +0100 Subject: [PATCH 1/2] Get filename by contentDisposition instead of contentType header if available --- src/modules/imap/section.rs | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/modules/imap/section.rs b/src/modules/imap/section.rs index 5977740..ff95996 100644 --- a/src/modules/imap/section.rs +++ b/src/modules/imap/section.rs @@ -9,7 +9,7 @@ use async_imap::{ }, types::Fetch, }; -use imap_proto::ContentType; +use imap_proto::{ContentDisposition, ContentType}; use mail_parser::decoders::{ base64::base64_decode_stream, quoted_printable::quoted_printable_decode, }; @@ -337,7 +337,7 @@ impl<'a> SectionExtractor<'a> { Self::recursive_parse_body(self.structure, SegmentPath::new(Vec::new())) } - /// Retrieves the file name from the content disposition if it exists. + /// Retrieves the file name from the content type if it exists. fn get_file_name(disposition: &ContentType<'a>) -> Option { disposition .params @@ -352,6 +352,25 @@ impl<'a> SectionExtractor<'a> { }) } + /// Retrieves the file name from the content disposition if it exists. + fn get_file_name_disposition(disposition_option: &Option>) -> Option { + if let Some(disposition) = &disposition_option { + disposition + .params + .as_ref()? + .iter() + .find_map(|(key, value)| { + if key.eq_ignore_ascii_case("filename") { + Some(try_decode_string(value.trim())) + } else { + None + } + }) + } else { + return None; + } + } + /// Parses a single attachment from the body content. #[inline] fn parse_attachment( @@ -366,10 +385,14 @@ impl<'a> SectionExtractor<'a> { let attachment_encoding: Encoding = (&other.transfer_encoding).into(); let content_id = other.id.clone().map(|cow| cow.into_owned()); let inline = disposition.ty.eq_ignore_ascii_case("inline"); + let mut filename = Self::get_file_name_disposition(&common.disposition); + if filename.is_none() { + filename = Self::get_file_name(&common.ty) + } Some(ImapAttachment::new( segment, - Self::get_file_name(&common.ty), + filename, other.octets as usize, common.ty.subtype.to_string(), attachment_encoding, From 711b113120a6799aefaaffa5244aa2831fff9916 Mon Sep 17 00:00:00 2001 From: SanderBaan Date: Thu, 26 Mar 2026 17:36:51 +0100 Subject: [PATCH 2/2] rename disposition to ty --- src/modules/imap/section.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/imap/section.rs b/src/modules/imap/section.rs index ff95996..ba08f44 100644 --- a/src/modules/imap/section.rs +++ b/src/modules/imap/section.rs @@ -338,8 +338,8 @@ impl<'a> SectionExtractor<'a> { } /// Retrieves the file name from the content type if it exists. - fn get_file_name(disposition: &ContentType<'a>) -> Option { - disposition + fn get_file_name(ty: &ContentType<'a>) -> Option { + ty .params .as_ref()? .iter()