[evolution/gnome-3-30] [Composer] Draft email can lose attachments when opened
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/gnome-3-30] [Composer] Draft email can lose attachments when opened
- Date: Fri, 18 Jan 2019 10:30:36 +0000 (UTC)
commit 88170825f1b39e796cc518cb3e689af085ddfc8a
Author: Milan Crha <mcrha redhat com>
Date: Fri Jan 18 11:24:30 2019 +0100
[Composer] Draft email can lose attachments when opened
Parts with Content-ID or Content-Location had been considered as inline
content and not added into real attachments, even when not referenced
in the HTML body. This addresses it in a way that it's only for images
and the worse case is to add it to both inline images and attachments,
to not lose it.
Reported downstream as:
https://bugzilla.redhat.com/show_bug.cgi?id=1666572
src/composer/e-msg-composer.c | 86 +++++++++++++++++++++++++++++++------------
1 file changed, 63 insertions(+), 23 deletions(-)
---
diff --git a/src/composer/e-msg-composer.c b/src/composer/e-msg-composer.c
index 9f56b99426..89c1f69319 100644
--- a/src/composer/e-msg-composer.c
+++ b/src/composer/e-msg-composer.c
@@ -129,21 +129,25 @@ static void add_attachments_from_multipart (EMsgComposer *composer,
/* used by e_msg_composer_setup_with_message () */
static void handle_multipart (EMsgComposer *composer,
CamelMultipart *multipart,
+ CamelMimePart *parent_part,
gboolean keep_signature,
GCancellable *cancellable,
gint depth);
static void handle_multipart_alternative (EMsgComposer *composer,
CamelMultipart *multipart,
+ CamelMimePart *parent_part,
gboolean keep_signature,
GCancellable *cancellable,
gint depth);
static void handle_multipart_encrypted (EMsgComposer *composer,
CamelMimePart *multipart,
+ CamelMimePart *parent_part,
gboolean keep_signature,
GCancellable *cancellable,
gint depth);
static void handle_multipart_signed (EMsgComposer *composer,
CamelMultipart *multipart,
+ CamelMimePart *parent_part,
gboolean keep_signature,
GCancellable *cancellable,
gint depth);
@@ -3105,6 +3109,31 @@ e_msg_composer_flush_pending_body (EMsgComposer *composer)
g_object_set_data (G_OBJECT (composer), "body:text", NULL);
}
+static gboolean
+emc_is_attachment_part (CamelMimePart *mime_part,
+ CamelMimePart *parent_part)
+{
+ const CamelContentDisposition *cd;
+ CamelContentType *ct, *parent_ct = NULL;
+
+ g_return_val_if_fail (CAMEL_IS_MIME_PART (mime_part), FALSE);
+
+ ct = camel_mime_part_get_content_type (mime_part);
+ cd = camel_mime_part_get_content_disposition (mime_part);
+
+ if (parent_part)
+ parent_ct = camel_mime_part_get_content_type (parent_part);
+
+ if (!camel_content_disposition_is_attachment_ex (cd, ct, parent_ct))
+ return FALSE;
+
+ /* It looks like an attachment now. Make it an attachment for all but images
+ under multipart/related, to avoid this group of false positives. */
+ return !(parent_ct && ct &&
+ camel_content_type_is (parent_ct, "multipart", "related") &&
+ camel_content_type_is (ct, "image", "*"));
+}
+
static void
add_attachments_handle_mime_part (EMsgComposer *composer,
CamelMimePart *mime_part,
@@ -3131,8 +3160,9 @@ add_attachments_handle_mime_part (EMsgComposer *composer,
composer, (CamelMultipart *) wrapper,
just_inlines, depth + 1);
} else if (just_inlines) {
- if (camel_mime_part_get_content_id (mime_part) ||
- camel_mime_part_get_content_location (mime_part))
+ if (camel_content_type_is (content_type, "image", "*") && (
+ camel_mime_part_get_content_id (mime_part) ||
+ camel_mime_part_get_content_location (mime_part)))
e_content_editor_insert_image_from_mime_part (
cnt_editor, mime_part);
} else if (related && camel_content_type_is (content_type, "image", "*")) {
@@ -3208,6 +3238,7 @@ e_msg_composer_add_message_attachments (EMsgComposer *composer,
static void
handle_multipart_signed (EMsgComposer *composer,
CamelMultipart *multipart,
+ CamelMimePart *parent_part,
gboolean keep_signature,
GCancellable *cancellable,
gint depth)
@@ -3258,24 +3289,24 @@ handle_multipart_signed (EMsgComposer *composer,
/* Handle the signed content and configure
* the composer to sign outgoing messages. */
handle_multipart_signed (
- composer, multipart, keep_signature, cancellable, depth);
+ composer, multipart, parent_part, keep_signature, cancellable, depth);
} else if (CAMEL_IS_MULTIPART_ENCRYPTED (content)) {
/* Decrypt the encrypted content and configure
* the composer to encrypt outgoing messages. */
handle_multipart_encrypted (
- composer, mime_part, keep_signature, cancellable, depth);
+ composer, mime_part, parent_part, keep_signature, cancellable, depth);
} else if (camel_content_type_is (content_type, "multipart", "alternative")) {
/* This contains the text/plain and text/html
* versions of the message body. */
handle_multipart_alternative (
- composer, multipart, keep_signature, cancellable, depth);
+ composer, multipart, parent_part, keep_signature, cancellable, depth);
} else {
/* There must be attachments... */
handle_multipart (
- composer, multipart, keep_signature, cancellable, depth);
+ composer, multipart, parent_part, keep_signature, cancellable, depth);
}
} else if (camel_content_type_is (content_type, "text", "*")) {
@@ -3295,6 +3326,7 @@ handle_multipart_signed (EMsgComposer *composer,
static void
handle_multipart_encrypted (EMsgComposer *composer,
CamelMimePart *multipart,
+ CamelMimePart *parent_part,
gboolean keep_signature,
GCancellable *cancellable,
gint depth)
@@ -3357,24 +3389,24 @@ handle_multipart_encrypted (EMsgComposer *composer,
/* Handle the signed content and configure the
* composer to sign outgoing messages. */
handle_multipart_signed (
- composer, content_multipart, keep_signature, cancellable, depth);
+ composer, content_multipart, multipart, keep_signature, cancellable, depth);
} else if (CAMEL_IS_MULTIPART_ENCRYPTED (content)) {
/* Decrypt the encrypted content and configure the
* composer to encrypt outgoing messages. */
handle_multipart_encrypted (
- composer, mime_part, keep_signature, cancellable, depth);
+ composer, mime_part, multipart, keep_signature, cancellable, depth);
} else if (camel_content_type_is (content_type, "multipart", "alternative")) {
/* This contains the text/plain and text/html
* versions of the message body. */
handle_multipart_alternative (
- composer, content_multipart, keep_signature, cancellable, depth);
+ composer, content_multipart, multipart, keep_signature, cancellable, depth);
} else {
/* There must be attachments... */
handle_multipart (
- composer, content_multipart, keep_signature, cancellable, depth);
+ composer, content_multipart, multipart, keep_signature, cancellable, depth);
}
} else if (camel_content_type_is (content_type, "text", "*")) {
@@ -3396,6 +3428,7 @@ handle_multipart_encrypted (EMsgComposer *composer,
static void
handle_multipart_alternative (EMsgComposer *composer,
CamelMultipart *multipart,
+ CamelMimePart *parent_part,
gboolean keep_signature,
GCancellable *cancellable,
gint depth)
@@ -3428,20 +3461,20 @@ handle_multipart_alternative (EMsgComposer *composer,
/* Handle the signed content and configure
* the composer to sign outgoing messages. */
handle_multipart_signed (
- composer, mp, keep_signature, cancellable, depth + 1);
+ composer, mp, parent_part, keep_signature, cancellable, depth + 1);
} else if (CAMEL_IS_MULTIPART_ENCRYPTED (content)) {
/* Decrypt the encrypted content and configure
* the composer to encrypt outgoing messages. */
handle_multipart_encrypted (
- composer, mime_part, keep_signature,
+ composer, mime_part, parent_part, keep_signature,
cancellable, depth + 1);
} else {
/* Depth doesn't matter so long as we
* don't pass 0. */
handle_multipart (
- composer, mp, keep_signature, cancellable, depth + 1);
+ composer, mp, parent_part, keep_signature, cancellable, depth + 1);
}
} else if (camel_content_type_is (content_type, "text", "html")) {
@@ -3480,6 +3513,7 @@ handle_multipart_alternative (EMsgComposer *composer,
static void
handle_multipart (EMsgComposer *composer,
CamelMultipart *multipart,
+ CamelMimePart *parent_part,
gboolean keep_signature,
GCancellable *cancellable,
gint depth)
@@ -3510,25 +3544,25 @@ handle_multipart (EMsgComposer *composer,
/* Handle the signed content and configure
* the composer to sign outgoing messages. */
handle_multipart_signed (
- composer, mp, keep_signature, cancellable, depth + 1);
+ composer, mp, parent_part, keep_signature, cancellable, depth + 1);
} else if (CAMEL_IS_MULTIPART_ENCRYPTED (content)) {
/* Decrypt the encrypted content and configure
* the composer to encrypt outgoing messages. */
handle_multipart_encrypted (
- composer, mime_part, keep_signature,
+ composer, mime_part, parent_part, keep_signature,
cancellable, depth + 1);
} else if (camel_content_type_is (
content_type, "multipart", "alternative")) {
handle_multipart_alternative (
- composer, mp, keep_signature, cancellable, depth + 1);
+ composer, mp, parent_part, keep_signature, cancellable, depth + 1);
} else {
/* Depth doesn't matter so long as we
* don't pass 0. */
handle_multipart (
- composer, mp, keep_signature, cancellable, depth + 1);
+ composer, mp, parent_part, keep_signature, cancellable, depth + 1);
}
} else if (depth == 0 && i == 0) {
@@ -3542,8 +3576,9 @@ handle_multipart (EMsgComposer *composer,
e_msg_composer_set_pending_body (composer, html, length, TRUE);
- } else if (camel_mime_part_get_content_id (mime_part) ||
- camel_mime_part_get_content_location (mime_part)) {
+ } else if (camel_content_type_is (content_type, "image", "*") && (
+ camel_mime_part_get_content_id (mime_part) ||
+ camel_mime_part_get_content_location (mime_part))) {
/* special in-line attachment */
EHTMLEditor *editor;
EContentEditor *cnt_editor;
@@ -3552,6 +3587,11 @@ handle_multipart (EMsgComposer *composer,
cnt_editor = e_html_editor_get_content_editor (editor);
e_content_editor_insert_image_from_mime_part (cnt_editor, mime_part);
+
+ /* Add it to both, to not lose attachments not referenced in HTML body.
+ The inserted images are not included in the message when not referenced. */
+ if (emc_is_attachment_part (mime_part, parent_part))
+ e_msg_composer_attach (composer, mime_part);
} else {
/* normal attachment */
e_msg_composer_attach (composer, mime_part);
@@ -3958,25 +3998,25 @@ e_msg_composer_setup_with_message (EMsgComposer *composer,
/* Handle the signed content and configure the
* composer to sign outgoing messages. */
handle_multipart_signed (
- composer, multipart, keep_signature, cancellable, 0);
+ composer, multipart, mime_part, keep_signature, cancellable, 0);
} else if (CAMEL_IS_MULTIPART_ENCRYPTED (content)) {
/* Decrypt the encrypted content and configure the
* composer to encrypt outgoing messages. */
handle_multipart_encrypted (
- composer, mime_part, keep_signature, cancellable, 0);
+ composer, mime_part, mime_part, keep_signature, cancellable, 0);
} else if (camel_content_type_is (
content_type, "multipart", "alternative")) {
/* This contains the text/plain and text/html
* versions of the message body. */
handle_multipart_alternative (
- composer, multipart, keep_signature, cancellable, 0);
+ composer, multipart, mime_part, keep_signature, cancellable, 0);
} else {
/* There must be attachments... */
handle_multipart (
- composer, multipart, keep_signature, cancellable, 0);
+ composer, multipart, mime_part, keep_signature, cancellable, 0);
}
} else {
CamelMimePart *mime_part;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]