From 72c0f82b41602928b05d8490fb3004db45fe9810 Mon Sep 17 00:00:00 2001 From: "Dirk-Jan C. Binnema" Date: Sun, 10 Apr 2022 13:18:03 +0300 Subject: [PATCH] message: improve attachment,encrypted part detection --- lib/message/mu-message.cc | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/lib/message/mu-message.cc b/lib/message/mu-message.cc index 231214db..6929e5c7 100644 --- a/lib/message/mu-message.cc +++ b/lib/message/mu-message.cc @@ -250,7 +250,8 @@ get_mailing_list(const MimeMessage& mime_msg) } static bool /* heuristic */ -looks_like_attachment(const MimePart& part, const Option& ctype) +looks_like_attachment(const MimeObject& parent, + const MimePart& part, const MimeContentType& ctype) { constexpr std::array, 4> att_types = {{ {"image", "*"}, @@ -259,22 +260,30 @@ looks_like_attachment(const MimePart& part, const Option& ctype {"application", "x-patch"} }}; - if (part.is_attachment()) /* explicity set as attachment */ - return true; - else if (!ctype) - return false; + if (parent) { /* crypto multipart children are not considered attachments */ + if (const auto parent_ctype{parent.content_type()}; parent_ctype) { + if (parent_ctype->is_type("multipart", "signed") || + parent_ctype->is_type("multipart", "encrypted")) + return false; + } + } /* we also consider patches, images, audio, and non-pgp-signature * application attachments to be attachments... */ - if (ctype->is_type("*", "pgp-signature")) + if (ctype.is_type("*", "pgp-signature")) return false; /* don't consider as a signature */ - if (ctype->is_type("text", "*") && - (ctype->is_type("*", "plain") || ctype->is_type("*", "html"))) + if (ctype.is_type("text", "*") && + (ctype.is_type("*", "plain") || ctype.is_type("*", "html"))) return false; /* not a signature */ + /* if not one of those special types, consider it any attachment + * if it says so */ + if (part.is_attachment()) + return true; + const auto it = seq_find_if(att_types, [&](auto&& item){ - return ctype->is_type(item.first, item.second); + return ctype.is_type(item.first, item.second); }); return it != att_types.cend(); /* if found, it's an attachment */ } @@ -302,13 +311,14 @@ accumulate_text(const MimePart& part, Message::Private& info, } static void -process_part(const MimePart& part, Message::Private& info) +process_part(const MimeObject& parent, const MimePart& part, + Message::Private& info) { const auto ctype{part.content_type()}; if (!ctype) return; - if (looks_like_attachment(part, ctype)) + if (looks_like_attachment(parent, part, *ctype)) info.flags |= Flags::HasAttachment; // if there are text parts, gather. @@ -341,11 +351,12 @@ process_message(const MimeMessage& mime_msg, const std::string& path, if (part.is_part() || part.is_message_part() || - part.is_multipart_signed()) + part.is_multipart_signed() || + part.is_multipart_encrypted()) info.parts.emplace_back(part); if (part.is_part()) - process_part(part, info); + process_part(parent, part, info); if (part.is_multipart_signed()) info.flags |= Flags::Signed;