178 lines
5.6 KiB
Diff
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
|