[evolution] Bug #436914 - Reply to inline GPG quotes raw GPG message



commit a8bde44b69e42fdb5640930e28c5005b897053df
Author: Milan Crha <mcrha redhat com>
Date:   Mon Dec 13 16:30:21 2010 +0100

    Bug #436914 - Reply to inline GPG quotes raw GPG message

 em-format/Makefile.am                  |    2 +
 em-format/em-format-quote.c            |   60 ++++++++++++++++++++++++++++++++
 {mail => em-format}/em-inline-filter.c |   58 ++++++++++++++++++++++++++++++-
 {mail => em-format}/em-inline-filter.h |    3 ++
 mail/Makefile.am                       |    2 -
 mail/em-format-html.c                  |    2 +-
 6 files changed, 123 insertions(+), 4 deletions(-)
---
diff --git a/em-format/Makefile.am b/em-format/Makefile.am
index 212b45f..df052fe 100644
--- a/em-format/Makefile.am
+++ b/em-format/Makefile.am
@@ -5,6 +5,7 @@ privsolib_LTLIBRARIES = libemformat.la
 emformatinclude_HEADERS =				\
 	em-format.h					\
 	em-format-quote.h				\
+	em-inline-filter.h				\
 	em-stripsig-filter.h
 
 libemformat_la_CPPFLAGS =				\
@@ -18,6 +19,7 @@ libemformat_la_SOURCES =				\
 	$(emformatinclude_HEADERS)			\
 	em-format.c					\
 	em-format-quote.c				\
+	em-inline-filter.c				\
 	em-stripsig-filter.c
 
 libemformat_la_LDFLAGS = $(NO_UNDEFINED)
diff --git a/em-format/em-format-quote.c b/em-format/em-format-quote.c
index 6d6ed6a..bdb632b 100644
--- a/em-format/em-format-quote.c
+++ b/em-format/em-format-quote.c
@@ -30,6 +30,7 @@
 #include <glib/gi18n.h>
 #include <gconf/gconf-client.h>
 
+#include "em-inline-filter.h"
 #include "em-stripsig-filter.h"
 #include "em-format-quote.h"
 
@@ -529,6 +530,52 @@ emfq_format_message (EMFormat *emf,
 			cancellable, NULL);
 }
 
+/* Decodes inline encoded parts of 'part'. The returned pointer, if not NULL, should
+   be unreffed with g_object_unref().
+*/
+static CamelMimePart *
+decode_inline_parts (CamelMimePart *part, GCancellable *cancellable)
+{
+	CamelMultipart *mp;
+	CamelStream *null;
+	CamelStream *filtered_stream;
+	EMInlineFilter *inline_filter;
+
+	g_return_val_if_fail (part != NULL, NULL);
+
+	null = camel_stream_null_new ();
+	filtered_stream = camel_stream_filter_new (null);
+	g_object_unref (null);
+
+	inline_filter = em_inline_filter_new (camel_mime_part_get_encoding (part), camel_mime_part_get_content_type (part));
+	camel_stream_filter_add (
+		CAMEL_STREAM_FILTER (filtered_stream),
+		CAMEL_MIME_FILTER (inline_filter));
+	camel_data_wrapper_decode_to_stream_sync (
+		camel_medium_get_content (CAMEL_MEDIUM (part)), (CamelStream *)filtered_stream, cancellable, NULL);
+	camel_stream_close ((CamelStream *)filtered_stream, cancellable, NULL);
+	g_object_unref (filtered_stream);
+
+	if (!em_inline_filter_found_any (inline_filter)) {
+		g_object_unref (inline_filter);
+		return NULL;
+	}
+
+	mp = em_inline_filter_get_multipart (inline_filter);
+
+	g_object_unref (inline_filter);
+
+	if (mp) {
+		part = camel_mime_part_new ();
+		camel_medium_set_content (CAMEL_MEDIUM (part), CAMEL_DATA_WRAPPER (mp));
+		g_object_unref (mp);
+	} else {
+		g_object_ref (part);
+	}
+
+	return part;
+}
+
 static void
 emfq_text_plain (EMFormat *emf,
                  CamelStream *stream,
@@ -541,6 +588,7 @@ emfq_text_plain (EMFormat *emf,
 	CamelStream *filtered_stream;
 	CamelMimeFilter *html_filter;
 	CamelMimeFilter *sig_strip;
+	CamelMimePart *mp;
 	CamelContentType *type;
 	const gchar *format;
 	guint32 rgb = 0x737373, flags;
@@ -548,6 +596,18 @@ emfq_text_plain (EMFormat *emf,
 	if (!part)
 		return;
 
+	mp = decode_inline_parts (part, cancellable);
+	if (mp) {
+		if (CAMEL_IS_MULTIPART (camel_medium_get_content (CAMEL_MEDIUM (mp)))) {
+			em_format_part (emf, stream, mp, cancellable);
+			g_object_unref (mp);
+
+			return;
+		}
+
+		g_object_unref (mp);
+	}
+
 	flags = emfq->text_html_flags;
 
 	/* Check for RFC 2646 flowed text. */
diff --git a/mail/em-inline-filter.c b/em-format/em-inline-filter.c
similarity index 88%
rename from mail/em-inline-filter.c
rename to em-format/em-inline-filter.c
index 7222c03..23e5a6f 100644
--- a/mail/em-inline-filter.c
+++ b/em-format/em-inline-filter.c
@@ -28,7 +28,6 @@
 
 #include "em-inline-filter.h"
 
-#include "em-utils.h"
 #include "em-format/em-format.h"
 
 #define d(x)
@@ -56,6 +55,35 @@ static const struct {
 	{ "application", "x-inlinepgp-encrypted", CAMEL_TRANSFER_ENCODING_DEFAULT,  0, },
 };
 
+static CamelMimePart *
+construct_part_from_stream (CamelStream *mem, const GByteArray *data)
+{
+	CamelMimePart *part = NULL;
+	CamelMimeParser *parser;
+
+	g_return_val_if_fail (mem != NULL, NULL);
+	g_return_val_if_fail (data != NULL, NULL);
+
+	if (data->len <= 13 || g_ascii_strncasecmp ((const gchar *) data->data, "Content-Type:", 13) != 0)
+		return NULL;
+
+	parser = camel_mime_parser_new ();
+	camel_mime_parser_scan_from (parser, FALSE);
+	camel_mime_parser_scan_pre_from (parser, FALSE);
+
+	if (camel_mime_parser_init_with_stream (parser, mem, NULL) != -1) {
+		part = camel_mime_part_new ();
+		if (!camel_mime_part_construct_from_parser_sync (part, parser, NULL, NULL)) {
+			g_object_unref (part);
+			part = NULL;
+		}
+	}
+
+	g_object_unref (parser);
+
+	return part;
+}
+
 static void
 inline_filter_add_part (EMInlineFilter *emif, const gchar *data, gint len)
 {
@@ -79,7 +107,21 @@ inline_filter_add_part (EMInlineFilter *emif, const gchar *data, gint len)
 	}
 
 	mem = camel_stream_mem_new_with_byte_array (emif->data);
+	part = construct_part_from_stream (mem, emif->data);
+	if (part) {
+		g_object_unref (mem);
+		emif->data = g_byte_array_new ();
+		g_free (emif->filename);
+		emif->filename = NULL;
+
+		emif->parts = g_slist_append (emif->parts, part);
+		emif->found_any = TRUE;
+
+		return;
+	}
+
 	emif->data = g_byte_array_new ();
+	camel_stream_reset (mem, NULL);
 
 	dw = camel_data_wrapper_new ();
 	if (encoding == emif->base_encoding && (encoding == CAMEL_TRANSFER_ENCODING_BASE64 || encoding == CAMEL_TRANSFER_ENCODING_QUOTEDPRINTABLE)) {
@@ -207,6 +249,7 @@ inline_filter_scan (CamelMimeFilter *f, gchar *in, gsize len, gint final)
 				inline_filter_add_part (emif, data_start, inptr-data_start);
 				data_start = inptr;
 				emif->state = EMIF_PLAIN;
+				emif->found_any = TRUE;
 			}
 			break;
 		case EMIF_POSTSCRIPT:
@@ -215,6 +258,7 @@ inline_filter_scan (CamelMimeFilter *f, gchar *in, gsize len, gint final)
 				inline_filter_add_part (emif, data_start, inptr-data_start);
 				data_start = inptr;
 				emif->state = EMIF_PLAIN;
+				emif->found_any = TRUE;
 			}
 			break;
 		case EMIF_PGPSIGNED:
@@ -223,6 +267,7 @@ inline_filter_scan (CamelMimeFilter *f, gchar *in, gsize len, gint final)
 				inline_filter_add_part (emif, data_start, inptr-data_start);
 				data_start = inptr;
 				emif->state = EMIF_PLAIN;
+				emif->found_any = TRUE;
 			}
 			break;
 		case EMIF_PGPENCRYPTED:
@@ -231,6 +276,7 @@ inline_filter_scan (CamelMimeFilter *f, gchar *in, gsize len, gint final)
 				inline_filter_add_part (emif, data_start, inptr-data_start);
 				data_start = inptr;
 				emif->state = EMIF_PLAIN;
+				emif->found_any = TRUE;
 			}
 			break;
 		}
@@ -321,6 +367,7 @@ inline_filter_reset (CamelMimeFilter *filter)
 	}
 	emif->parts = NULL;
 	g_byte_array_set_size (emif->data, 0);
+	emif->found_any = FALSE;
 }
 
 static void
@@ -342,6 +389,7 @@ static void
 em_inline_filter_init (EMInlineFilter *emif)
 {
 	emif->data = g_byte_array_new ();
+	emif->found_any = FALSE;
 }
 
 /**
@@ -386,3 +434,11 @@ em_inline_filter_get_multipart (EMInlineFilter *emif)
 
 	return mp;
 }
+
+gboolean
+em_inline_filter_found_any (EMInlineFilter *emif)
+{
+	g_return_val_if_fail (emif != NULL, FALSE);
+
+	return emif->found_any;
+}
diff --git a/mail/em-inline-filter.h b/em-format/em-inline-filter.h
similarity index 96%
rename from mail/em-inline-filter.h
rename to em-format/em-inline-filter.h
index 8ee90a6..503ec7c 100644
--- a/mail/em-inline-filter.h
+++ b/em-format/em-inline-filter.h
@@ -61,6 +61,8 @@ struct _EMInlineFilter {
 	GByteArray *data;
 	gchar *filename;
 	GSList *parts;
+
+	gboolean found_any;
 };
 
 struct _EMInlineFilterClass {
@@ -71,6 +73,7 @@ GType		em_inline_filter_get_type	(void);
 EMInlineFilter *em_inline_filter_new		(CamelTransferEncoding base_encoding,
 						 CamelContentType *type);
 CamelMultipart *em_inline_filter_get_multipart	(EMInlineFilter *emif);
+gboolean	em_inline_filter_found_any	(EMInlineFilter *emif);
 
 G_END_DECLS
 
diff --git a/mail/Makefile.am b/mail/Makefile.am
index a88a7c8..520e687 100644
--- a/mail/Makefile.am
+++ b/mail/Makefile.am
@@ -91,7 +91,6 @@ mailinclude_HEADERS =					\
 	em-format-html-display.h			\
 	em-format-html-print.h				\
 	em-html-stream.h				\
-	em-inline-filter.h				\
 	em-junk.h					\
 	em-search-context.h				\
 	em-subscription-editor.h			\
@@ -164,7 +163,6 @@ libevolution_mail_la_SOURCES =				\
 	em-format-html-display.c			\
 	em-format-html-print.c				\
 	em-html-stream.c				\
-	em-inline-filter.c				\
 	em-junk.c					\
 	em-search-context.c				\
 	em-subscription-editor.c			\
diff --git a/mail/em-format-html.c b/mail/em-format-html.c
index de8c0b5..6b74da7 100644
--- a/mail/em-format-html.c
+++ b/mail/em-format-html.c
@@ -1595,7 +1595,7 @@ efh_object_requested (GtkHTML *html, GtkHTMLEmbedded *eb, EMFormatHTML *efh)
 }
 
 /* ********************************************************************** */
-#include "em-inline-filter.h"
+#include "em-format/em-inline-filter.h"
 
 /* FIXME: This is duplicated in em-format-html-display, should be exported or in security module */
 static const struct {



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