[evolution] I#1729 - Composer: Forward can lost unreferenced attachments with Content-ID
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution] I#1729 - Composer: Forward can lost unreferenced attachments with Content-ID
- Date: Fri, 10 Dec 2021 08:27:42 +0000 (UTC)
commit 622707b34fc715f82e2e19109a43a34a7ff14e11
Author: Milan Crha <mcrha redhat com>
Date: Fri Dec 10 09:25:53 2021 +0100
I#1729 - Composer: Forward can lost unreferenced attachments with Content-ID
Closes https://gitlab.gnome.org/GNOME/evolution/-/issues/1729
src/composer/e-msg-composer.c | 78 +++++++++++++++++++++++++++++++++++++++++++
src/composer/e-msg-composer.h | 3 +-
src/e-util/e-html-editor.c | 70 ++++++++++++++++++++++++++++++++++++++
src/e-util/e-html-editor.h | 4 +++
src/mail/em-composer-utils.c | 1 +
5 files changed, 155 insertions(+), 1 deletion(-)
---
diff --git a/src/composer/e-msg-composer.c b/src/composer/e-msg-composer.c
index ac2cd1ee8f..178ba8e1e4 100644
--- a/src/composer/e-msg-composer.c
+++ b/src/composer/e-msg-composer.c
@@ -3334,6 +3334,84 @@ e_msg_composer_add_attachments_from_part_list (EMsgComposer *composer,
g_hash_table_destroy (added_mime_parts);
}
+static void
+e_msg_composer_filter_inline_attachments (EMsgComposer *composer,
+ GSList *used_mime_parts) /* CamelMimePart * */
+{
+ GSList *removed_parts = NULL, *link;
+ gboolean been_changed;
+ EHTMLEditor *editor;
+ EContentEditor *content_editor;
+
+ editor = e_msg_composer_get_editor (composer);
+ content_editor = e_html_editor_get_content_editor (editor);
+
+ been_changed = e_content_editor_get_changed (content_editor);
+ e_html_editor_remove_unused_cid_parts (editor, used_mime_parts, &removed_parts);
+
+ for (link = removed_parts; link; link = g_slist_next (link)) {
+ CamelMimePart *mime_part = link->data;
+ e_msg_composer_attach (composer, mime_part);
+ }
+
+ g_slist_free_full (removed_parts, g_object_unref);
+
+ /* This is not a user change */
+ e_content_editor_set_changed (content_editor, been_changed);
+}
+
+static void
+e_mg_composer_got_used_inline_images_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ EMsgComposer *composer = user_data;
+ EContentEditorContentHash *content_hash;
+
+ content_hash = e_content_editor_get_content_finish (E_CONTENT_EDITOR (source_object), result, NULL);
+ if (content_hash) {
+ GSList *inline_images_parts;
+
+ inline_images_parts = e_content_editor_util_get_content_data (content_hash,
E_CONTENT_EDITOR_GET_INLINE_IMAGES);
+
+ e_msg_composer_filter_inline_attachments (composer, inline_images_parts);
+
+ g_hash_table_destroy (content_hash);
+ } else {
+ e_msg_composer_filter_inline_attachments (composer, NULL);
+ }
+
+ g_object_unref (composer);
+}
+
+/**
+ * e_msg_composer_check_inline_attachments:
+ * @composer: an #EMsgComposer
+ *
+ * Checks which inline attachments are referenced in the message body
+ * and those which are not referenced are added as regular attachments.
+ *
+ * Since: 3.44
+ **/
+void
+e_msg_composer_check_inline_attachments (EMsgComposer *composer)
+{
+ EHTMLEditor *editor;
+ EContentEditor *content_editor;
+
+ g_return_if_fail (E_IS_MSG_COMPOSER (composer));
+
+ editor = e_msg_composer_get_editor (composer);
+ content_editor = e_html_editor_get_content_editor (editor);
+
+ if (e_content_editor_get_html_mode (content_editor)) {
+ e_content_editor_get_content (content_editor, E_CONTENT_EDITOR_GET_INLINE_IMAGES,
+ "localhost", NULL, e_mg_composer_got_used_inline_images_cb, g_object_ref (composer));
+ } else {
+ e_msg_composer_filter_inline_attachments (composer, NULL);
+ }
+}
+
static void
handle_multipart_signed (EMsgComposer *composer,
CamelMultipart *multipart,
diff --git a/src/composer/e-msg-composer.h b/src/composer/e-msg-composer.h
index 2e4657b35d..fbbf6bea95 100644
--- a/src/composer/e-msg-composer.h
+++ b/src/composer/e-msg-composer.h
@@ -191,7 +191,8 @@ void e_msg_composer_add_attachments_from_part_list
(EMsgComposer *composer,
EMailPartList *part_list,
gboolean just_inlines);
-
+void e_msg_composer_check_inline_attachments
+ (EMsgComposer *composer);
void e_msg_composer_request_close (EMsgComposer *composer);
gboolean e_msg_composer_can_close (EMsgComposer *composer,
diff --git a/src/e-util/e-html-editor.c b/src/e-util/e-html-editor.c
index e4cdd319b1..04a6434a6e 100644
--- a/src/e-util/e-html-editor.c
+++ b/src/e-util/e-html-editor.c
@@ -1751,6 +1751,76 @@ e_html_editor_remove_all_cid_parts (EHTMLEditor *editor)
g_hash_table_remove_all (editor->priv->cid_parts);
}
+typedef struct _RemoveUnusedCidPartsData {
+ GHashTable *used_hash; /* CamelMimePart * ~> NULL */
+ GSList **out_removed_mime_parts;
+} RemoveUnusedCidPartsData;
+
+static gboolean
+remove_unused_cid_parts_cb (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ RemoveUnusedCidPartsData *data = user_data;
+ CamelMimePart *mime_part = value;
+ gboolean remove;
+
+ remove = !data->used_hash || !g_hash_table_contains (data->used_hash, mime_part);
+
+ if (remove && data->out_removed_mime_parts)
+ *data->out_removed_mime_parts = g_slist_prepend (*data->out_removed_mime_parts, g_object_ref
(mime_part));
+
+ return remove;
+}
+
+/**
+ * e_html_editor_remove_unused_cid_parts:
+ * @editor: an #EHTMLEditor
+ * @used_mime_parts: (nullable) (element-type CamelMimePart): list of used CamelMimePart-s to keep
+ * @out_removed_mime_parts: (out) (optional) (element-type CamelMimePart) (transfer full): list of removed
parts
+ *
+ * Traverses the list of "cid:" parts and removes all which are not part
+ * of the @used_mime_parts.
+ *
+ * The optional @out_removed_mime_parts is filled with the removed parts.
+ * Free it with g_slist_free_full (list, g_object_unref);, when no longer needed.
+ *
+ * Since: 3.44
+ **/
+void
+e_html_editor_remove_unused_cid_parts (EHTMLEditor *editor,
+ GSList *used_mime_parts,
+ GSList **out_removed_mime_parts)
+{
+ RemoveUnusedCidPartsData data;
+
+ g_return_if_fail (E_IS_HTML_EDITOR (editor));
+
+ if (out_removed_mime_parts)
+ *out_removed_mime_parts = NULL;
+
+ data.used_hash = NULL;
+ data.out_removed_mime_parts = out_removed_mime_parts;
+
+ if (used_mime_parts) {
+ GSList *link;
+
+ data.used_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+ for (link = used_mime_parts; link; link = g_slist_next (link)) {
+ g_hash_table_insert (data.used_hash, link->data, NULL);
+ }
+ }
+
+ g_hash_table_foreach_remove (editor->priv->cid_parts, remove_unused_cid_parts_cb, &data);
+
+ if (data.used_hash)
+ g_hash_table_destroy (data.used_hash);
+
+ if (out_removed_mime_parts)
+ *out_removed_mime_parts = g_slist_reverse (*out_removed_mime_parts);
+}
+
/**
* e_html_editor_ref_cid_part:
* @editor: an #EHTMLEditor
diff --git a/src/e-util/e-html-editor.h b/src/e-util/e-html-editor.h
index 8be1af19ea..b96ab542f9 100644
--- a/src/e-util/e-html-editor.h
+++ b/src/e-util/e-html-editor.h
@@ -120,6 +120,10 @@ void e_html_editor_add_cid_part (EHTMLEditor *editor,
CamelMimePart *mime_part);
void e_html_editor_remove_cid_part (EHTMLEditor *editor,
const gchar *cid_uri);
+void e_html_editor_remove_unused_cid_parts
+ (EHTMLEditor *editor,
+ GSList *used_mime_parts, /* CamelMimePart * */
+ GSList **out_removed_mime_parts); /* CamelMimePart * */
void e_html_editor_remove_all_cid_parts
(EHTMLEditor *editor);
CamelMimePart * e_html_editor_ref_cid_part (EHTMLEditor *editor,
diff --git a/src/mail/em-composer-utils.c b/src/mail/em-composer-utils.c
index 1f9a7ee41a..a54d72dee9 100644
--- a/src/mail/em-composer-utils.c
+++ b/src/mail/em-composer-utils.c
@@ -2573,6 +2573,7 @@ forward_non_attached (EMsgComposer *composer,
emu_set_source_headers (composer, folder, uid, CAMEL_MESSAGE_FORWARDED);
emu_update_composers_security (composer, validity_found);
+ e_msg_composer_check_inline_attachments (composer);
composer_set_no_change (composer);
gtk_widget_show (GTK_WIDGET (composer));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]