aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2010-12-13 23:30:21 +0800
committerMilan Crha <mcrha@redhat.com>2010-12-13 23:30:21 +0800
commita8bde44b69e42fdb5640930e28c5005b897053df (patch)
treefea363167793260e40ae0ddff89dce6aef9f1a93
parentda223fce69fe73305c0ab03abd4f092a72686556 (diff)
downloadgsoc2013-evolution-a8bde44b69e42fdb5640930e28c5005b897053df.tar
gsoc2013-evolution-a8bde44b69e42fdb5640930e28c5005b897053df.tar.gz
gsoc2013-evolution-a8bde44b69e42fdb5640930e28c5005b897053df.tar.bz2
gsoc2013-evolution-a8bde44b69e42fdb5640930e28c5005b897053df.tar.lz
gsoc2013-evolution-a8bde44b69e42fdb5640930e28c5005b897053df.tar.xz
gsoc2013-evolution-a8bde44b69e42fdb5640930e28c5005b897053df.tar.zst
gsoc2013-evolution-a8bde44b69e42fdb5640930e28c5005b897053df.zip
Bug #436914 - Reply to inline GPG quotes raw GPG message
-rw-r--r--em-format/Makefile.am2
-rw-r--r--em-format/em-format-quote.c60
-rw-r--r--em-format/em-inline-filter.c (renamed from mail/em-inline-filter.c)58
-rw-r--r--em-format/em-inline-filter.h (renamed from mail/em-inline-filter.h)3
-rw-r--r--mail/Makefile.am2
-rw-r--r--mail/em-format-html.c2
6 files changed, 123 insertions, 4 deletions
diff --git a/em-format/Makefile.am b/em-format/Makefile.am
index 212b45f074..df052fe915 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 6d6ed6a4ab..bdb632b252 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
index 7222c03489..23e5a6f6ed 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
index 8ee90a6640..503ec7c66c 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 a88a7c889a..520e6876cd 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 de8c0b5961..6b74da70b5 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 {