summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2018-07-26 14:15:39 +0200
committerMilan Crha <mcrha@redhat.com>2018-07-26 14:15:39 +0200
commitedb7a62490b1096fb378f9e8ee2a46e50730d56a (patch)
tree608a75d750f124b1f4e88c86fc390f876114fdad
parent3c6be739560203a6dee79b8f13fcbeeaed07242a (diff)
downloadevolution-data-server-edb7a62490b1096fb378f9e8ee2a46e50730d56a.tar.gz
Enhance attachment detection in a MIME message
Related to https://gitlab.gnome.org/GNOME/evolution/issues/80
-rw-r--r--src/camel/camel-mime-message.c22
-rw-r--r--src/camel/camel-mime-utils.c31
-rw-r--r--src/camel/camel-mime-utils.h1
-rw-r--r--src/camel/providers/imapx/camel-imapx-server.c2
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;
}