[evolution-data-server] Enhance attachment detection in a MIME message



commit edb7a62490b1096fb378f9e8ee2a46e50730d56a
Author: Milan Crha <mcrha redhat com>
Date:   Thu Jul 26 14:15:39 2018 +0200

    Enhance attachment detection in a MIME message
    
    Related to https://gitlab.gnome.org/GNOME/evolution/issues/80

 src/camel/camel-mime-message.c                 | 22 ++++++++++++------
 src/camel/camel-mime-utils.c                   | 31 +++++++++++++++++++++-----
 src/camel/camel-mime-utils.h                   |  1 +
 src/camel/providers/imapx/camel-imapx-server.c |  2 +-
 4 files changed, 43 insertions(+), 13 deletions(-)
---
diff --git a/src/camel/camel-mime-message.c b/src/camel/camel-mime-message.c
index 2eebb1170..ee8093e72 100644
--- a/src/camel/camel-mime-message.c
+++ b/src/camel/camel-mime-message.c
@@ -834,11 +834,12 @@ camel_mime_message_get_source (CamelMimeMessage *mime_message)
        return src;
 }
 
-typedef gboolean (*CamelPartFunc)(CamelMimeMessage *, CamelMimePart *, gpointer data);
+typedef gboolean (*CamelPartFunc)(CamelMimeMessage *message, CamelMimePart *part, CamelMimePart 
*parent_part, gpointer data);
 
 static gboolean
 message_foreach_part_rec (CamelMimeMessage *msg,
                           CamelMimePart *part,
+                         CamelMimePart *parent_part,
                           CamelPartFunc callback,
                           gpointer data)
 {
@@ -846,7 +847,7 @@ message_foreach_part_rec (CamelMimeMessage *msg,
        gint parts, i;
        gint go = TRUE;
 
-       if (callback (msg, part, data) == FALSE)
+       if (callback (msg, part, parent_part, data) == FALSE)
                return FALSE;
 
        containee = camel_medium_get_content (CAMEL_MEDIUM (part));
@@ -860,10 +861,10 @@ message_foreach_part_rec (CamelMimeMessage *msg,
                for (i = 0; go && i < parts; i++) {
                        CamelMimePart *mpart = camel_multipart_get_part (CAMEL_MULTIPART (containee), i);
 
-                       go = message_foreach_part_rec (msg, mpart, callback, data);
+                       go = message_foreach_part_rec (msg, mpart, part, callback, data);
                }
        } else if (CAMEL_IS_MIME_MESSAGE (containee)) {
-               go = message_foreach_part_rec (msg, (CamelMimePart *) containee, callback, data);
+               go = message_foreach_part_rec (msg, (CamelMimePart *) containee, part, callback, data);
        }
 
        return go;
@@ -876,12 +877,13 @@ camel_mime_message_foreach_part (CamelMimeMessage *msg,
                                  CamelPartFunc callback,
                                  gpointer data)
 {
-       message_foreach_part_rec (msg, (CamelMimePart *) msg, callback, data);
+       message_foreach_part_rec (msg, (CamelMimePart *) msg, NULL, callback, data);
 }
 
 static gboolean
 check_8bit (CamelMimeMessage *msg,
             CamelMimePart *part,
+            CamelMimePart *parent_part,
             gpointer data)
 {
        CamelTransferEncoding encoding;
@@ -1065,6 +1067,7 @@ struct _enc_data {
 static gboolean
 best_encoding (CamelMimeMessage *msg,
                CamelMimePart *part,
+               CamelMimePart *parent_part,
                gpointer datap)
 {
        struct _enc_data *data = datap;
@@ -1161,6 +1164,7 @@ struct _check_content_id {
 static gboolean
 check_content_id (CamelMimeMessage *message,
                   CamelMimePart *part,
+                  CamelMimePart *parent_part,
                   gpointer data)
 {
        struct _check_content_id *check = (struct _check_content_id *) data;
@@ -1286,10 +1290,11 @@ camel_mime_message_build_mbox_from (CamelMimeMessage *message)
 static gboolean
 find_attachment (CamelMimeMessage *msg,
                  CamelMimePart *part,
+                 CamelMimePart *parent_part,
                  gpointer data)
 {
        const CamelContentDisposition *cd;
-       CamelContentType *ct;
+       CamelContentType *ct, *parent_ct = NULL;
        gboolean *found = (gboolean *) data;
 
        g_return_val_if_fail (part != NULL, FALSE);
@@ -1300,7 +1305,10 @@ find_attachment (CamelMimeMessage *msg,
        ct = camel_mime_part_get_content_type (part);
        cd = camel_mime_part_get_content_disposition (part);
 
-       *found = camel_content_disposition_is_attachment (cd, ct);
+       if (parent_part)
+               parent_ct = camel_mime_part_get_content_type (parent_part);
+
+       *found = camel_content_disposition_is_attachment_ex (cd, ct, parent_ct);
 
        return !(*found);
 }
diff --git a/src/camel/camel-mime-utils.c b/src/camel/camel-mime-utils.c
index 35d8eef68..ff515430a 100644
--- a/src/camel/camel-mime-utils.c
+++ b/src/camel/camel-mime-utils.c
@@ -3871,19 +3871,40 @@ gboolean
 camel_content_disposition_is_attachment (const CamelContentDisposition *disposition,
                                         const CamelContentType *content_type)
 {
-       if (!disposition)
-               return FALSE;
+       return camel_content_disposition_is_attachment_ex (disposition, content_type, NULL);
+}
 
+gboolean
+camel_content_disposition_is_attachment_ex (const CamelContentDisposition *disposition,
+                                           const CamelContentType *content_type,
+                                           const CamelContentType *parent_content_type)
+{
        if (content_type && (
            camel_content_type_is (content_type, "application", "xpkcs7mime") ||
            camel_content_type_is (content_type, "application", "x-pkcs7-mime") ||
-           camel_content_type_is (content_type, "application", "pkcs7-mime") ||
+           camel_content_type_is (content_type, "application", "pkcs7-mime")))
+               return FALSE;
+
+       if (content_type && (
+           camel_content_type_is (content_type, "application", "pgp-encrypted")))
+               return !parent_content_type || !camel_content_type_is (parent_content_type, "multipart", 
"encrypted");
+
+       if (content_type && camel_content_type_is (content_type, "application", "octet-stream") &&
+           parent_content_type && camel_content_type_is (parent_content_type, "multipart", "encrypted"))
+               return FALSE;
+
+       if (content_type && (
            camel_content_type_is (content_type, "application", "pkcs7-signature") ||
            camel_content_type_is (content_type, "application", "xpkcs7-signature") ||
            camel_content_type_is (content_type, "application", "x-pkcs7-signature") ||
            camel_content_type_is (content_type, "application", "pkcs7-signature") ||
-           camel_content_type_is (content_type, "application", "pgp-signature") ||
-           camel_content_type_is (content_type, "application", "pgp-encrypted")))
+           camel_content_type_is (content_type, "application", "pgp-signature")))
+               return !parent_content_type || !camel_content_type_is (parent_content_type, "multipart", 
"signed");
+
+       if (parent_content_type && content_type && camel_content_type_is (content_type, "message", "rfc822"))
+               return TRUE;
+
+       if (!disposition)
                return FALSE;
 
        if (disposition->disposition && g_ascii_strcasecmp (disposition->disposition, "attachment") == 0)
diff --git a/src/camel/camel-mime-utils.h b/src/camel/camel-mime-utils.h
index f0383a62c..fa50d614d 100644
--- a/src/camel/camel-mime-utils.h
+++ b/src/camel/camel-mime-utils.h
@@ -144,6 +144,7 @@ CamelContentDisposition *camel_content_disposition_ref (CamelContentDisposition
 void camel_content_disposition_unref (CamelContentDisposition *disposition);
 gchar *camel_content_disposition_format (CamelContentDisposition *disposition);
 gboolean camel_content_disposition_is_attachment (const CamelContentDisposition *disposition, const 
CamelContentType *content_type);
+gboolean camel_content_disposition_is_attachment_ex (const CamelContentDisposition *disposition, const 
CamelContentType *content_type, const CamelContentType *parent_content_type);
 
 /* decode the contents of a content-encoding header */
 gchar *camel_content_transfer_encoding_decode (const gchar *in);
diff --git a/src/camel/providers/imapx/camel-imapx-server.c b/src/camel/providers/imapx/camel-imapx-server.c
index b0321b25c..acf67ca3d 100644
--- a/src/camel/providers/imapx/camel-imapx-server.c
+++ b/src/camel/providers/imapx/camel-imapx-server.c
@@ -1065,7 +1065,7 @@ imapx_server_cinfo_has_attachment_cb (CamelMessageContentInfo *ci,
 
        g_return_val_if_fail (pbool != NULL, FALSE);
 
-       *pbool = camel_content_disposition_is_attachment (ci->disposition, ci->type);
+       *pbool = camel_content_disposition_is_attachment_ex (ci->disposition, ci->type, ci->parent ? 
ci->parent->type : NULL);
 
        return !*pbool;
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]