[evolution] Bug 789648 - Problem viewing .eml attachment
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution] Bug 789648 - Problem viewing .eml attachment
- Date: Thu, 2 Nov 2017 11:07:24 +0000 (UTC)
commit a41a550eab83ccd5922b08823e95e8959cee1859
Author: Milan Crha <mcrha redhat com>
Date: Thu Nov 2 12:04:07 2017 +0100
Bug 789648 - Problem viewing .eml attachment
src/em-format/e-mail-parser-application-mbox.c | 94 +++++++++++++++---------
src/em-format/e-mail-parser-multipart-mixed.c | 64 +++++++++++++++-
src/em-format/e-mail-parser.c | 76 +++++++++++++++-----
src/em-format/e-mail-parser.h | 5 +
4 files changed, 182 insertions(+), 57 deletions(-)
---
diff --git a/src/em-format/e-mail-parser-application-mbox.c b/src/em-format/e-mail-parser-application-mbox.c
index c4e9ecd..38dc1ee 100644
--- a/src/em-format/e-mail-parser-application-mbox.c
+++ b/src/em-format/e-mail-parser-application-mbox.c
@@ -40,6 +40,47 @@ static const gchar *parser_mime_types[] = {
NULL
};
+static void
+empe_app_mbox_add_message (EMailParser *parser,
+ CamelMimeMessage *message,
+ gint nth_message,
+ GString *part_id,
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
+{
+ GQueue work_queue = G_QUEUE_INIT;
+ CamelMimePart *opart;
+ gint old_len;
+
+ old_len = part_id->len;
+
+ g_string_append_printf (part_id, ".mbox.%d", nth_message);
+
+ opart = camel_mime_part_new ();
+ camel_medium_set_content (CAMEL_MEDIUM (opart), CAMEL_DATA_WRAPPER (message));
+ camel_data_wrapper_set_mime_type (CAMEL_DATA_WRAPPER (opart), "message/rfc822");
+
+ e_mail_parser_parse_part_as (
+ parser, opart, part_id, "message/rfc822",
+ cancellable, &work_queue);
+
+ /* Wrap every message as attachment */
+ e_mail_parser_wrap_as_attachment (parser, opart, part_id, &work_queue);
+
+ /* Inline all messages in mbox */
+ if (!g_queue_is_empty (&work_queue)) {
+ EMailPart *pp = g_queue_peek_head (&work_queue);
+
+ pp->force_inline = TRUE;
+ }
+
+ e_queue_transfer (&work_queue, out_mail_parts);
+
+ g_string_truncate (part_id, old_len);
+
+ g_object_unref (opart);
+}
+
static gboolean
empe_app_mbox_parse (EMailParserExtension *extension,
EMailParser *parser,
@@ -51,7 +92,6 @@ empe_app_mbox_parse (EMailParserExtension *extension,
CamelMimeParser *mime_parser;
CamelStream *mem_stream;
CamelMimeParserState state;
- gint old_len;
gint messages;
GError *error = NULL;
@@ -90,67 +130,51 @@ empe_app_mbox_parse (EMailParserExtension *extension,
return TRUE;
}
- g_object_unref (mem_stream);
-
- old_len = part_id->len;
-
/* Extract messages from the mbox. */
messages = 0;
state = camel_mime_parser_step (mime_parser, NULL, NULL);
while (state == CAMEL_MIME_PARSER_STATE_FROM) {
- GQueue work_queue = G_QUEUE_INIT;
CamelMimeMessage *message;
- CamelMimePart *opart;
message = camel_mime_message_new ();
- opart = CAMEL_MIME_PART (message);
if (!camel_mime_part_construct_from_parser_sync (
- opart, mime_parser, NULL, NULL)) {
+ CAMEL_MIME_PART (message), mime_parser, NULL, NULL)) {
g_object_unref (message);
break;
}
- g_string_append_printf (part_id, ".mbox.%d", messages);
+ empe_app_mbox_add_message (parser, message, messages, part_id, cancellable, out_mail_parts);
+ messages++;
- opart = camel_mime_part_new ();
- camel_medium_set_content (CAMEL_MEDIUM (opart), CAMEL_DATA_WRAPPER (message));
- camel_data_wrapper_set_mime_type (CAMEL_DATA_WRAPPER (opart), "message/rfc822");
+ g_object_unref (message);
- e_mail_parser_parse_part_as (
- parser, opart, part_id, "message/rfc822",
- cancellable, &work_queue);
+ /* Skip past CAMEL_MIME_PARSER_STATE_FROM_END. */
+ camel_mime_parser_step (mime_parser, NULL, NULL);
- /* Wrap every message as attachment */
- e_mail_parser_wrap_as_attachment (
- parser, opart, part_id, &work_queue);
+ state = camel_mime_parser_step (mime_parser, NULL, NULL);
+ }
- /* Inline all messages in mbox */
- if (!g_queue_is_empty (&work_queue)) {
- EMailPart *p = g_queue_peek_head (&work_queue);
+ if (!messages) {
+ CamelMimeMessage *message;
- p->force_inline = TRUE;
- }
+ g_seekable_seek (G_SEEKABLE (mem_stream), 0, G_SEEK_SET, cancellable, NULL);
- e_queue_transfer (&work_queue, out_mail_parts);
+ message = camel_mime_message_new ();
- g_string_truncate (part_id, old_len);
+ if (camel_data_wrapper_construct_from_stream_sync (CAMEL_DATA_WRAPPER (message), mem_stream,
NULL, NULL)) {
+ empe_app_mbox_add_message (parser, message, messages, part_id, cancellable,
out_mail_parts);
+ messages++;
+ }
g_object_unref (message);
- g_object_unref (opart);
-
- /* Skip past CAMEL_MIME_PARSER_STATE_FROM_END. */
- camel_mime_parser_step (mime_parser, NULL, NULL);
-
- state = camel_mime_parser_step (mime_parser, NULL, NULL);
-
- messages++;
}
g_object_unref (mime_parser);
+ g_object_unref (mem_stream);
- return TRUE;
+ return messages > 0;
}
static void
diff --git a/src/em-format/e-mail-parser-multipart-mixed.c b/src/em-format/e-mail-parser-multipart-mixed.c
index cc6a023..6d3aefe 100644
--- a/src/em-format/e-mail-parser-multipart-mixed.c
+++ b/src/em-format/e-mail-parser-multipart-mixed.c
@@ -140,12 +140,65 @@ empe_mp_mixed_parse (EMailParserExtension *extension,
g_string_append_printf (part_id, ".mixed.%d", i);
- handled = e_mail_parser_parse_part (
- parser, subpart, part_id, cancellable, &work_queue);
+ handled = FALSE;
+ ct = camel_mime_part_get_content_type (subpart);
+ if (ct)
+ ct = camel_content_type_ref (ct);
+
+ if (!e_mail_parser_get_parsers_for_part (parser, subpart)) {
+ const gchar *snoop_type;
+ CamelContentType *snoop_ct = NULL;
+
+ snoop_type = e_mail_part_snoop_type (subpart);
+ if (snoop_type)
+ snoop_ct = camel_content_type_decode (snoop_type);
+
+ if (snoop_ct && snoop_ct->type && snoop_ct->subtype && (
+ !ct || g_ascii_strcasecmp (snoop_ct->type, ct->type) != 0 ||
+ g_ascii_strcasecmp (snoop_ct->subtype, ct->subtype) != 0)) {
+ CamelStream *mem_stream;
+
+ mem_stream = camel_stream_mem_new ();
+ if (camel_data_wrapper_decode_to_stream_sync (
+ camel_medium_get_content (CAMEL_MEDIUM (subpart)),
+ mem_stream, cancellable, NULL)) {
+ CamelMimePart *opart;
+ CamelDataWrapper *dw;
+
+ g_seekable_seek (G_SEEKABLE (mem_stream), 0, G_SEEK_SET, cancellable,
NULL);
+
+ opart = camel_mime_part_new ();
+
+ dw = camel_data_wrapper_new ();
+ camel_data_wrapper_set_mime_type (dw, snoop_type);
+ if (camel_data_wrapper_construct_from_stream_sync (dw, mem_stream,
cancellable, NULL)) {
+ camel_medium_set_content (CAMEL_MEDIUM (opart), dw);
+ camel_data_wrapper_set_mime_type (CAMEL_DATA_WRAPPER (opart),
snoop_type);
+
+ handled = e_mail_parser_parse_part (parser, opart, part_id,
cancellable, &work_queue);
+ if (handled) {
+ camel_content_type_unref (ct);
+ ct = camel_content_type_ref (snoop_ct);
+ }
+ }
- mail_part = g_queue_peek_head (&work_queue);
+ g_object_unref (opart);
+ g_object_unref (dw);
+ }
- ct = camel_mime_part_get_content_type (subpart);
+ g_object_unref (mem_stream);
+ }
+
+ if (snoop_ct)
+ camel_content_type_unref (snoop_ct);
+ }
+
+ if (!handled) {
+ handled = e_mail_parser_parse_part (
+ parser, subpart, part_id, cancellable, &work_queue);
+ }
+
+ mail_part = g_queue_peek_head (&work_queue);
/* Display parts with CID as attachments
* (unless they already are attachments).
@@ -178,6 +231,9 @@ empe_mp_mixed_parse (EMailParserExtension *extension,
e_queue_transfer (&work_queue, out_mail_parts);
g_string_truncate (part_id, len);
+
+ if (ct)
+ camel_content_type_unref (ct);
}
return TRUE;
diff --git a/src/em-format/e-mail-parser.c b/src/em-format/e-mail-parser.c
index 1cbbe32..a9a0849 100644
--- a/src/em-format/e-mail-parser.c
+++ b/src/em-format/e-mail-parser.c
@@ -494,6 +494,63 @@ e_mail_parser_parse_finish (EMailParser *parser,
return g_object_ref (part_list);
}
+GQueue *
+e_mail_parser_get_parsers_for_part (EMailParser *parser,
+ CamelMimePart *part)
+{
+ CamelContentType *ct;
+ gchar *mime_type;
+ GQueue *parsers;
+
+ g_return_val_if_fail (E_IS_MAIL_PARSER (parser), NULL);
+ g_return_val_if_fail (CAMEL_IS_MIME_PART (part), NULL);
+
+ ct = camel_mime_part_get_content_type (part);
+ if (!ct) {
+ mime_type = (gchar *) "application/vnd.evolution.error";
+ } else {
+ gchar *tmp;
+ tmp = camel_content_type_simple (ct);
+ mime_type = g_ascii_strdown (tmp, -1);
+ g_free (tmp);
+ }
+
+ parsers = e_mail_parser_get_parsers (parser, mime_type);
+
+ if (ct)
+ g_free (mime_type);
+
+ return parsers;
+}
+
+GQueue *
+e_mail_parser_get_parsers (EMailParser *parser,
+ const gchar *mime_type)
+{
+ EMailExtensionRegistry *reg;
+ EMailParserClass *parser_class;
+ gchar *as_mime_type;
+ GQueue *parsers;
+
+ g_return_val_if_fail (E_IS_MAIL_PARSER (parser), NULL);
+
+ if (mime_type)
+ as_mime_type = g_ascii_strdown (mime_type, -1);
+ else
+ as_mime_type = NULL;
+
+ parser_class = E_MAIL_PARSER_GET_CLASS (parser);
+ reg = E_MAIL_EXTENSION_REGISTRY (parser_class->extension_registry);
+
+ parsers = e_mail_extension_registry_get_for_mime_type (reg, as_mime_type);
+ if (!parsers)
+ parsers = e_mail_extension_registry_get_fallback (reg, as_mime_type);
+
+ g_free (as_mime_type);
+
+ return parsers;
+}
+
gboolean
e_mail_parser_parse_part (EMailParser *parser,
CamelMimePart *part,
@@ -536,26 +593,9 @@ e_mail_parser_parse_part_as (EMailParser *parser,
{
GQueue *parsers;
GList *iter;
- EMailExtensionRegistry *reg;
- EMailParserClass *parser_class;
- gchar *as_mime_type;
gboolean mime_part_handled = FALSE;
- if (mime_type)
- as_mime_type = g_ascii_strdown (mime_type, -1);
- else
- as_mime_type = NULL;
-
- parser_class = E_MAIL_PARSER_GET_CLASS (parser);
- reg = E_MAIL_EXTENSION_REGISTRY (parser_class->extension_registry);
-
- parsers = e_mail_extension_registry_get_for_mime_type (reg, as_mime_type);
- if (!parsers) {
- parsers = e_mail_extension_registry_get_fallback (reg, as_mime_type);
- }
-
- if (as_mime_type)
- g_free (as_mime_type);
+ parsers = e_mail_parser_get_parsers (parser, mime_type);
if (parsers == NULL) {
e_mail_parser_wrap_as_attachment (
diff --git a/src/em-format/e-mail-parser.h b/src/em-format/e-mail-parser.h
index 1d0c447..9a6ccd3 100644
--- a/src/em-format/e-mail-parser.h
+++ b/src/em-format/e-mail-parser.h
@@ -79,6 +79,11 @@ EMailPartList * e_mail_parser_parse_finish (EMailParser *parser,
GAsyncResult *result,
GError **error);
+GQueue * e_mail_parser_get_parsers_for_part
+ (EMailParser *parser,
+ CamelMimePart *part);
+GQueue * e_mail_parser_get_parsers (EMailParser *parser,
+ const gchar *mime_type);
gboolean e_mail_parser_parse_part (EMailParser *parser,
CamelMimePart *part,
GString *part_id,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]