evolution/evolution-3.10.4-large-message-render-hung.patch

178 lines
5.6 KiB
Diff

diff -up evolution-3.10.4/modules/text-highlight/e-mail-formatter-text-highlight.c.large-message-render-hung evolution-3.10.4/modules/text-highlight/e-mail-formatter-text-highlight.c
--- evolution-3.10.4/modules/text-highlight/e-mail-formatter-text-highlight.c.large-message-render-hung 2013-12-07 15:14:12.000000000 +0100
+++ evolution-3.10.4/modules/text-highlight/e-mail-formatter-text-highlight.c 2014-09-12 08:24:26.418217142 +0200
@@ -41,6 +41,15 @@ typedef EMailFormatterExtensionClass EMa
typedef EExtension EMailFormatterTextHighlightLoader;
typedef EExtensionClass EMailFormatterTextHighlightLoaderClass;
+typedef struct _TextHighlightClosure TextHighlightClosure;
+
+struct _TextHighlightClosure {
+ CamelStream *read_stream;
+ CamelStream *output_stream;
+ GCancellable *cancellable;
+ GError *error;
+};
+
GType e_mail_formatter_text_highlight_get_type (void);
G_DEFINE_DYNAMIC_TYPE (
@@ -110,6 +119,103 @@ get_syntax (EMailPart *part,
return syntax;
}
+static gpointer
+text_hightlight_read_data_thread (gpointer user_data)
+{
+ TextHighlightClosure *closure = user_data;
+ gchar buffer[10240];
+
+ g_return_val_if_fail (closure != NULL, NULL);
+
+ while (!camel_stream_eos (closure->read_stream) &&
+ !g_cancellable_set_error_if_cancelled (closure->cancellable, &closure->error)) {
+ gssize read;
+ gsize wrote = 0;
+
+ read = camel_stream_read (closure->read_stream, buffer, 10240, closure->cancellable, &closure->error);
+ if (read < 0 || closure->error)
+ break;
+
+ wrote = camel_stream_write (closure->output_stream, buffer, read, closure->cancellable, &closure->error);
+ if (wrote == -1 || (gssize) wrote != read || closure->error)
+ break;
+ }
+
+ return NULL;
+}
+
+static gboolean
+text_highlight_feed_data (CamelStream *output_stream,
+ CamelDataWrapper *data_wrapper,
+ gint pipe_stdin,
+ gint pipe_stdout,
+ GCancellable *cancellable,
+ GError **error)
+{
+ TextHighlightClosure closure;
+ CamelContentType *content_type;
+ CamelStream *write_stream;
+ gboolean success = TRUE;
+ GThread *thread;
+
+ closure.read_stream = camel_stream_fs_new_with_fd (pipe_stdout);
+ closure.output_stream = output_stream;
+ closure.cancellable = cancellable;
+ closure.error = NULL;
+
+ write_stream = camel_stream_fs_new_with_fd (pipe_stdin);
+
+ thread = g_thread_new (NULL, text_hightlight_read_data_thread, &closure);
+
+ content_type = camel_data_wrapper_get_mime_type_field (data_wrapper);
+ if (content_type) {
+ const gchar *charset = camel_content_type_param (content_type, "charset");
+
+ /* Convert to UTF-8 charset, if needed, which the 'highlight' expects;
+ it can cope with non-UTF-8 letters, thus no need for a content UTF-8-validation */
+ if (charset && g_ascii_strcasecmp (charset, "utf-8") != 0) {
+ CamelMimeFilter *filter;
+
+ filter = camel_mime_filter_charset_new (charset, "UTF-8");
+ if (filter != NULL) {
+ CamelStream *filtered = camel_stream_filter_new (write_stream);
+
+ if (filtered) {
+ camel_stream_filter_add (CAMEL_STREAM_FILTER (filtered), filter);
+ g_object_unref (write_stream);
+ write_stream = filtered;
+ }
+
+ g_object_unref (filter);
+ }
+ }
+ }
+
+ if (camel_data_wrapper_decode_to_stream_sync (data_wrapper, write_stream, cancellable, error) < 0) {
+ g_cancellable_cancel (cancellable);
+ success = FALSE;
+ } else {
+ /* Close the stream, thus the highlight knows no more data will come */
+ g_clear_object (&write_stream);
+ }
+
+ g_thread_join (thread);
+
+ g_clear_object (&closure.read_stream);
+ g_clear_object (&write_stream);
+
+ if (closure.error) {
+ if (error && !*error)
+ g_propagate_error (error, closure.error);
+ else
+ g_clear_error (&closure.error);
+
+ return FALSE;
+ }
+
+ return success;
+}
+
static gboolean
emfe_text_highlight_format (EMailFormatterExtension *extension,
EMailFormatter *formatter,
@@ -213,35 +319,27 @@ emfe_text_highlight_format (EMailFormatt
&pid, &pipe_stdin, &pipe_stdout, NULL, NULL);
if (success) {
- CamelStream *read;
- CamelStream *write;
- CamelStream *utf8;
- GByteArray *ba;
- gchar *tmp;
-
- write = camel_stream_fs_new_with_fd (pipe_stdin);
- read = camel_stream_fs_new_with_fd (pipe_stdout);
-
- /* Decode the content of mime part to the 'utf8' stream */
- utf8 = camel_stream_mem_new ();
- camel_data_wrapper_decode_to_stream_sync (
- dw, utf8, cancellable, NULL);
-
- /* Convert the binary data do someting displayable */
- ba = camel_stream_mem_get_byte_array (CAMEL_STREAM_MEM (utf8));
- tmp = e_util_utf8_data_make_valid ((gchar *) ba->data, ba->len);
-
- /* Send the sanitized data to the highlighter */
- camel_stream_write_string (write, tmp, cancellable, NULL);
- g_free (tmp);
- g_object_unref (utf8);
- g_object_unref (write);
+ GError *local_error = NULL;
- g_spawn_close_pid (pid);
+ success = text_highlight_feed_data (
+ stream, dw,
+ pipe_stdin, pipe_stdout,
+ cancellable, &local_error);
+
+ if (g_error_matches (
+ local_error, G_IO_ERROR,
+ G_IO_ERROR_CANCELLED)) {
+ /* Do nothing. */
+
+ } else if (local_error != NULL) {
+ g_warning (
+ "%s: %s", G_STRFUNC,
+ local_error->message);
+ }
+
+ g_clear_error (&local_error);
- g_seekable_seek (G_SEEKABLE (read), 0, G_SEEK_SET, cancellable, NULL);
- camel_stream_write_to_stream (read, stream, cancellable, NULL);
- g_object_unref (read);
+ g_spawn_close_pid (pid);
} else {
/* We can't call e_mail_formatter_format_as on text/plain,
* because text-highlight is registered as an handler for