[evolution] Bug 606344 - Clicking "Reply to All" button causes Evo to dump core



commit 7636c4705148cd31f842de134448918381dc2045
Author: Matthew Barnes <mbarnes redhat com>
Date:   Fri Jan 8 15:52:05 2010 -0500

    Bug 606344 - Clicking "Reply to All" button causes Evo to dump core
    
    Adding a GtkhtmlEditor::uri-requested repeater signal was a mistake.
    It unnecessarily complicates URI handling and so the composer no longer
    uses it -- instead it connects to GtkHTML::url-requested directly.
    
    This also requires commit 203ce61e6ea19323914b9c459b2e79bde5db15be from
    GtkHTML to work right.  That commit changes GtkHTML::url-requested to a
    G_SIGNAL_RUN_LAST so the composer's signal handler runs first.  If the
    composer can handle the URI request, it stops the signal emission so
    that nothing else tries to use the freed GtkHTMLStream.
    
    Henceforth consider GtkhtmlEditor::uri-requested to be deprecated.

 composer/e-composer-private.c |   58 +++++++++++++++++++++++++++++++++
 composer/e-composer-private.h |   17 ++++++++++
 composer/e-msg-composer.c     |   72 -----------------------------------------
 3 files changed, 75 insertions(+), 72 deletions(-)
---
diff --git a/composer/e-composer-private.c b/composer/e-composer-private.c
index 8dfdeeb..b0bc0c9 100644
--- a/composer/e-composer-private.c
+++ b/composer/e-composer-private.c
@@ -82,6 +82,47 @@ composer_setup_recent_menu (EMsgComposer *composer)
 	gtk_ui_manager_ensure_update (ui_manager);
 }
 
+static void
+msg_composer_url_requested_cb (GtkHTML *html,
+                               const gchar *uri,
+                               GtkHTMLStream *stream,
+                               EMsgComposer *composer)
+{
+	GByteArray *array;
+	GHashTable *hash_table;
+	CamelDataWrapper *wrapper;
+	CamelStream *camel_stream;
+	CamelMimePart *mime_part;
+
+	hash_table = composer->priv->inline_images_by_url;
+	mime_part = g_hash_table_lookup (hash_table, uri);
+
+	if (mime_part == NULL) {
+		hash_table = composer->priv->inline_images;
+		mime_part = g_hash_table_lookup (hash_table, uri);
+	}
+
+	/* If this is not an inline image request,
+	 * allow the signal emission to continue. */
+	if (mime_part == NULL)
+		return;
+
+	array = g_byte_array_new ();
+	camel_stream = camel_stream_mem_new_with_byte_array (array);
+	wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part));
+	camel_data_wrapper_decode_to_stream (wrapper, camel_stream);
+
+	gtk_html_write (html, stream, (gchar *) array->data, array->len);
+
+	gtk_html_end (html, stream, GTK_HTML_STREAM_OK);
+
+	camel_object_unref (camel_stream);
+
+	/* gtk_html_end() destroys the GtkHTMLStream, so we need to
+	 * stop the signal emission so nothing else tries to use it. */
+	g_signal_stop_emission_by_name (html, "url-requested");
+}
+
 void
 e_composer_private_constructed (EMsgComposer *composer)
 {
@@ -94,12 +135,14 @@ e_composer_private_constructed (EMsgComposer *composer)
 	GtkWidget *widget;
 	GtkWidget *send_widget;
 	GtkWindow *window;
+	GtkHTML *html;
 	const gchar *path;
 	gchar *filename;
 	gint ii;
 	GError *error = NULL;
 
 	editor = GTKHTML_EDITOR (composer);
+	html = gtkhtml_editor_get_html (editor);
 	ui_manager = gtkhtml_editor_get_ui_manager (editor);
 
 	if (composer->lite) {
@@ -304,6 +347,21 @@ e_composer_private_constructed (EMsgComposer *composer)
 			action, "active");
 	}
 
+	/* Install a handler for inline images. */
+
+	/* XXX We no longer use GtkhtmlEditor::uri-requested because it
+	 *     conflicts with EWebView's url_requested() method, which
+	 *     unconditionally launches an async operation.  I changed
+	 *     GtkHTML::url-requested to be a G_SIGNAL_RUN_LAST so that
+	 *     our handler runs first.  If we can handle the request
+	 *     we'll stop the signal emission to prevent EWebView from
+	 *     launching an async operation.  Messy, but works until we
+	 *     switch to WebKit.  --mbarnes */
+
+	g_signal_connect (
+		html, "url-requested",
+		G_CALLBACK (msg_composer_url_requested_cb), composer);
+
 	priv->mail_sent = FALSE;
 }
 
diff --git a/composer/e-composer-private.h b/composer/e-composer-private.h
index bab8dd1..1711e0c 100644
--- a/composer/e-composer-private.h
+++ b/composer/e-composer-private.h
@@ -27,7 +27,24 @@
 #include <glib/gi18n-lib.h>
 #include <glib/gstdio.h>
 
+#include <camel/camel-charset-map.h>
+#include <camel/camel-cipher-context.h>
+#include <camel/camel-folder.h>
+#include <camel/camel-gpg-context.h>
 #include <camel/camel-iconv.h>
+#include <camel/camel-mime-filter-basic.h>
+#include <camel/camel-mime-filter-canon.h>
+#include <camel/camel-mime-filter-charset.h>
+#include <camel/camel-mime-filter-tohtml.h>
+#include <camel/camel-multipart-encrypted.h>
+#include <camel/camel-multipart-signed.h>
+#include <camel/camel-stream-filter.h>
+#include <camel/camel-stream-fs.h>
+#include <camel/camel-stream-mem.h>
+#include <camel/camel-string-utils.h>
+#if defined (HAVE_NSS)
+#include <camel/camel-smime-context.h>
+#endif
 
 #include "e-composer-actions.h"
 #include "e-composer-autosave.h"
diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c
index eed3893..e9b388b 100644
--- a/composer/e-msg-composer.c
+++ b/composer/e-msg-composer.c
@@ -57,25 +57,6 @@
 #include "em-format/em-format-quote.h"
 #include "misc/e-web-view.h"
 
-#include <camel/camel-charset-map.h>
-#include <camel/camel-cipher-context.h>
-#include <camel/camel-folder.h>
-#include <camel/camel-gpg-context.h>
-#include <camel/camel-iconv.h>
-#include <camel/camel-mime-filter-basic.h>
-#include <camel/camel-mime-filter-canon.h>
-#include <camel/camel-mime-filter-charset.h>
-#include <camel/camel-mime-filter-tohtml.h>
-#include <camel/camel-multipart-encrypted.h>
-#include <camel/camel-multipart-signed.h>
-#include <camel/camel-stream-filter.h>
-#include <camel/camel-stream-fs.h>
-#include <camel/camel-stream-mem.h>
-#include <camel/camel-string-utils.h>
-#if defined (HAVE_NSS)
-#include <camel/camel-smime-context.h>
-#endif
-
 #include "e-msg-composer.h"
 #include "e-attachment.h"
 #include "e-composer-autosave.h"
@@ -2099,58 +2080,6 @@ msg_composer_object_deleted (GtkhtmlEditor *editor)
 }
 
 static void
-msg_composer_uri_requested (GtkhtmlEditor *editor,
-                            const gchar *uri,
-                            GtkHTMLStream *stream)
-{
-	GtkhtmlEditorClass *editor_class;
-	EMsgComposer *composer;
-	GHashTable *hash_table;
-	GByteArray *array;
-	CamelDataWrapper *wrapper;
-	CamelStream *camel_stream;
-	CamelMimePart *part;
-	GtkHTML *html;
-
-	/* XXX It's unfortunate we have to expose GtkHTML structs here.
-	 *     Maybe we could rework this to use a GOutputStream. */
-
-	composer = E_MSG_COMPOSER (editor);
-	html = gtkhtml_editor_get_html (editor);
-
-	hash_table = composer->priv->inline_images_by_url;
-	part = g_hash_table_lookup (hash_table, uri);
-
-	if (part == NULL) {
-		hash_table = composer->priv->inline_images;
-		part = g_hash_table_lookup (hash_table, uri);
-	}
-
-	if (part == NULL)
-		goto chainup;
-
-	array = g_byte_array_new ();
-	camel_stream = camel_stream_mem_new_with_byte_array (array);
-	wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (part));
-	camel_data_wrapper_decode_to_stream (wrapper, camel_stream);
-
-	gtk_html_write (
-		gtkhtml_editor_get_html (editor), stream,
-		(gchar *) array->data, array->len);
-
-	camel_object_unref (camel_stream);
-
-	gtk_html_end (html, stream, GTK_HTML_STREAM_OK);
-
-	return;
-
-chainup:
-	/* Chain up to parent's uri_requested() method. */
-	editor_class = GTKHTML_EDITOR_CLASS (parent_class);
-	editor_class->uri_requested (editor, uri, stream);
-}
-
-static void
 msg_composer_class_init (EMsgComposerClass *class)
 {
 	GObjectClass *object_class;
@@ -2187,7 +2116,6 @@ msg_composer_class_init (EMsgComposerClass *class)
 	editor_class->image_uri = msg_composer_image_uri;
 	editor_class->link_clicked = msg_composer_link_clicked;
 	editor_class->object_deleted = msg_composer_object_deleted;
-	editor_class->uri_requested = msg_composer_uri_requested;
 
 	g_object_class_install_property (
 		object_class,



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