aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2013-03-07 02:37:37 +0800
committerMilan Crha <mcrha@redhat.com>2013-03-07 02:38:19 +0800
commit0d96f08f9f0400ab9202f1dcdbaca1d891a41ac8 (patch)
tree16a25ce6707e5a61b86bedc3386e8412be764227
parent989886007f3f69ca64e383ad6d64ef8c352f6df8 (diff)
downloadgsoc2013-evolution-0d96f08f9f0400ab9202f1dcdbaca1d891a41ac8.tar
gsoc2013-evolution-0d96f08f9f0400ab9202f1dcdbaca1d891a41ac8.tar.gz
gsoc2013-evolution-0d96f08f9f0400ab9202f1dcdbaca1d891a41ac8.tar.bz2
gsoc2013-evolution-0d96f08f9f0400ab9202f1dcdbaca1d891a41ac8.tar.lz
gsoc2013-evolution-0d96f08f9f0400ab9202f1dcdbaca1d891a41ac8.tar.xz
gsoc2013-evolution-0d96f08f9f0400ab9202f1dcdbaca1d891a41ac8.tar.zst
gsoc2013-evolution-0d96f08f9f0400ab9202f1dcdbaca1d891a41ac8.zip
Bug #690092 - Crash under format_full_headers()
-rw-r--r--em-format/e-mail-formatter-headers.c27
-rw-r--r--em-format/e-mail-formatter-print-headers.c8
-rw-r--r--em-format/e-mail-formatter-quote-headers.c20
-rw-r--r--em-format/e-mail-formatter-utils.c8
-rw-r--r--em-format/e-mail-formatter.c114
-rw-r--r--em-format/e-mail-formatter.h4
-rw-r--r--mail/e-mail-printer.c8
7 files changed, 153 insertions, 36 deletions
diff --git a/em-format/e-mail-formatter-headers.c b/em-format/e-mail-formatter-headers.c
index 7a3a7232fe..ef86c21fc5 100644
--- a/em-format/e-mail-formatter-headers.c
+++ b/em-format/e-mail-formatter-headers.c
@@ -56,7 +56,7 @@ format_short_headers (EMailFormatter *formatter,
{
const gchar *charset;
CamelContentType *ct;
- const gchar *hdr_charset;
+ gchar *hdr_charset;
gchar *evolution_imagesdir;
gchar *subject = NULL;
struct _camel_header_address *addrs = NULL;
@@ -70,9 +70,9 @@ format_short_headers (EMailFormatter *formatter,
ct = camel_mime_part_get_content_type ((CamelMimePart *) part);
charset = camel_content_type_param (ct, "charset");
charset = camel_iconv_charset_name (charset);
- hdr_charset = e_mail_formatter_get_charset (formatter) ?
- e_mail_formatter_get_charset (formatter) :
- e_mail_formatter_get_default_charset (formatter);
+ hdr_charset = e_mail_formatter_dup_charset (formatter);
+ if (!hdr_charset)
+ hdr_charset = e_mail_formatter_dup_default_charset (formatter);
evolution_imagesdir = g_filename_to_uri (EVOLUTION_IMAGESDIR, NULL, NULL);
from = g_string_new ("");
@@ -112,6 +112,8 @@ format_short_headers (EMailFormatter *formatter,
header = header->next;
}
+ g_free (hdr_charset);
+
is_rtl = gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL;
if (is_rtl) {
g_string_append_printf (
@@ -241,7 +243,7 @@ format_full_headers (EMailFormatter *formatter,
gsize face_header_len = 0;
gchar *header_sender = NULL, *header_from = NULL, *name;
gboolean mail_from_delegate = FALSE;
- const gchar *hdr_charset;
+ gchar *hdr_charset;
gchar *evolution_imagesdir;
if (g_cancellable_is_cancelled (cancellable))
@@ -250,9 +252,9 @@ format_full_headers (EMailFormatter *formatter,
ct = camel_mime_part_get_content_type ((CamelMimePart *) part);
charset = camel_content_type_param (ct, "charset");
charset = camel_iconv_charset_name (charset);
- hdr_charset = e_mail_formatter_get_charset (formatter) ?
- e_mail_formatter_get_charset (formatter) :
- e_mail_formatter_get_default_charset (formatter);
+ hdr_charset = e_mail_formatter_dup_charset (formatter);
+ if (!hdr_charset)
+ hdr_charset = e_mail_formatter_dup_default_charset (formatter);
evolution_imagesdir = g_filename_to_uri (EVOLUTION_IMAGESDIR, NULL, NULL);
@@ -305,6 +307,8 @@ format_full_headers (EMailFormatter *formatter,
header = header->next;
}
+ g_free (hdr_charset);
+
if (header_sender && header_from && mail_from_delegate) {
gchar *bold_sender, *bold_from;
@@ -352,11 +356,12 @@ format_full_headers (EMailFormatter *formatter,
header = header->next;
}
} else {
+ GQueue *headers_queue;
GList *link;
gint mailer_shown = FALSE;
- link = g_queue_peek_head_link (
- (GQueue *) e_mail_formatter_get_headers (formatter));
+ headers_queue = e_mail_formatter_dup_headers (formatter);
+ link = g_queue_peek_head_link (headers_queue);
while (link != NULL) {
EMailFormatterHeader *h = link->data;
@@ -427,6 +432,8 @@ format_full_headers (EMailFormatter *formatter,
link = g_list_next (link);
}
+
+ g_queue_free_full (headers_queue, (GDestroyNotify) e_mail_formatter_header_free);
}
g_string_append (buffer, "</table></td>");
diff --git a/em-format/e-mail-formatter-print-headers.c b/em-format/e-mail-formatter-print-headers.c
index fb19559e49..a79dfa1f70 100644
--- a/em-format/e-mail-formatter-print-headers.c
+++ b/em-format/e-mail-formatter-print-headers.c
@@ -61,7 +61,7 @@ emfpe_headers_format (EMailFormatterExtension *extension,
const gchar *buf;
gint attachments_count;
gchar *part_id_prefix;
- const GQueue *headers;
+ GQueue *headers_queue;
GQueue queue = G_QUEUE_INIT;
GList *head, *link;
@@ -76,8 +76,8 @@ emfpe_headers_format (EMailFormatterExtension *extension,
"<table border=\"0\" cellspacing=\"5\" "
"cellpadding=\"0\" class=\"printing-header\">\n");
- headers = e_mail_formatter_get_headers (formatter);
- for (link = headers->head; link != NULL; link = g_list_next (link)) {
+ headers_queue = e_mail_formatter_dup_headers (formatter);
+ for (link = headers_queue->head; link != NULL; link = g_list_next (link)) {
EMailFormatterHeader *header = link->data;
raw_header.name = header->name;
@@ -113,6 +113,8 @@ emfpe_headers_format (EMailFormatterExtension *extension,
}
}
+ g_queue_free_full (headers_queue, (GDestroyNotify) e_mail_formatter_header_free);
+
/* Get prefix of this PURI */
part_id_prefix = g_strndup (part->id, g_strrstr (part->id, ".") - part->id);
diff --git a/em-format/e-mail-formatter-quote-headers.c b/em-format/e-mail-formatter-quote-headers.c
index 20e97fdc69..4a29d849c5 100644
--- a/em-format/e-mail-formatter-quote-headers.c
+++ b/em-format/e-mail-formatter-quote-headers.c
@@ -121,15 +121,19 @@ emfqe_format_header (EMailFormatter *formatter,
if (addrspec) {
struct _camel_header_address *addrs;
GString *html;
+ gchar *charset;
if (!(txt = camel_medium_get_header (part, name)))
return;
+ charset = e_mail_formatter_dup_charset (formatter);
+ if (!charset)
+ charset = e_mail_formatter_dup_default_charset (formatter);
+
buf = camel_header_unfold (txt);
- addrs = camel_header_address_decode (
- txt, e_mail_formatter_get_charset (formatter) ?
- e_mail_formatter_get_charset (formatter) :
- e_mail_formatter_get_default_charset (formatter));
+ addrs = camel_header_address_decode (txt, charset);
+ g_free (charset);
+
if (addrs == NULL) {
g_free (buf);
return;
@@ -189,7 +193,7 @@ emqfe_headers_format (EMailFormatterExtension *extension,
const gchar *charset;
GList *iter;
GString *buffer;
- const GQueue *default_headers;
+ GQueue *headers_queue;
if (!part)
return FALSE;
@@ -201,8 +205,8 @@ emqfe_headers_format (EMailFormatterExtension *extension,
buffer = g_string_new ("");
/* dump selected headers */
- default_headers = e_mail_formatter_get_headers (formatter);
- for (iter = default_headers->head; iter; iter = iter->next) {
+ headers_queue = e_mail_formatter_dup_headers (formatter);
+ for (iter = headers_queue->head; iter; iter = iter->next) {
struct _camel_header_raw *raw_header;
EMailFormatterHeader *h = iter->data;
guint32 flags;
@@ -222,6 +226,8 @@ emqfe_headers_format (EMailFormatterExtension *extension,
}
}
+ g_queue_free_full (headers_queue, (GDestroyNotify) e_mail_formatter_header_free);
+
g_string_append (buffer, "<br>\n");
camel_stream_write_string (stream, buffer->str, cancellable, NULL);
diff --git a/em-format/e-mail-formatter-utils.c b/em-format/e-mail-formatter-utils.c
index 5fdb885e9a..a2e0d43ff1 100644
--- a/em-format/e-mail-formatter-utils.c
+++ b/em-format/e-mail-formatter-utils.c
@@ -299,19 +299,21 @@ e_mail_formatter_format_header (EMailFormatter *formatter,
struct _camel_header_address *addrs;
GString *html;
gchar *img;
- const gchar *charset;
+ gchar *charset;
- charset = e_mail_formatter_get_charset (formatter);
+ charset = e_mail_formatter_dup_charset (formatter);
if (charset == NULL)
- charset = e_mail_formatter_get_default_charset (formatter);
+ charset = e_mail_formatter_dup_default_charset (formatter);
buf = camel_header_unfold (header->value);
addrs = camel_header_address_decode (buf, charset);
if (addrs == NULL) {
+ g_free (charset);
g_free (buf);
return;
}
+ g_free (charset);
g_free (buf);
html = g_string_new ("");
diff --git a/em-format/e-mail-formatter.c b/em-format/e-mail-formatter.c
index dc3cb89694..2e89f698d5 100644
--- a/em-format/e-mail-formatter.c
+++ b/em-format/e-mail-formatter.c
@@ -51,6 +51,8 @@ struct _EMailFormatterPrivate {
guint show_real_date : 1;
guint animate_images : 1;
+ GMutex property_lock;
+
gchar *charset;
gchar *default_charset;
@@ -304,16 +306,16 @@ e_mail_formatter_get_property (GObject *object,
return;
case PROP_CHARSET:
- g_value_set_string (
+ g_value_take_string (
value,
- e_mail_formatter_get_charset (
+ e_mail_formatter_dup_charset (
E_MAIL_FORMATTER (object)));
return;
case PROP_DEFAULT_CHARSET:
- g_value_set_string (
+ g_value_take_string (
value,
- e_mail_formatter_get_default_charset (
+ e_mail_formatter_dup_default_charset (
E_MAIL_FORMATTER (object)));
return;
}
@@ -344,6 +346,8 @@ e_mail_formatter_finalize (GObject *object)
priv->header_list = NULL;
}
+ g_mutex_clear (&priv->property_lock);
+
/* Chain up to parent's finalize() */
G_OBJECT_CLASS (e_mail_formatter_parent_class)->finalize (object);
}
@@ -717,6 +721,7 @@ e_mail_formatter_init (EMailFormatter *formatter)
{
formatter->priv = E_MAIL_FORMATTER_GET_PRIVATE (formatter);
+ g_mutex_init (&formatter->priv->property_lock);
formatter->priv->header_list = g_queue_new ();
e_mail_formatter_set_default_headers (formatter);
}
@@ -1289,14 +1294,31 @@ e_mail_formatter_get_charset (EMailFormatter *formatter)
return formatter->priv->charset;
}
+gchar *
+e_mail_formatter_dup_charset (EMailFormatter *formatter)
+{
+ gchar *charset;
+
+ g_return_val_if_fail (E_IS_MAIL_FORMATTER (formatter), NULL);
+
+ g_mutex_lock (&formatter->priv->property_lock);
+ charset = g_strdup (e_mail_formatter_get_charset (formatter));
+ g_mutex_unlock (&formatter->priv->property_lock);
+
+ return charset;
+}
+
void
e_mail_formatter_set_charset (EMailFormatter *formatter,
const gchar *charset)
{
g_return_if_fail (E_IS_MAIL_FORMATTER (formatter));
- if (g_strcmp0 (formatter->priv->charset, charset) == 0)
+ g_mutex_lock (&formatter->priv->property_lock);
+ if (g_strcmp0 (formatter->priv->charset, charset) == 0) {
+ g_mutex_unlock (&formatter->priv->property_lock);
return;
+ }
g_free (formatter->priv->charset);
@@ -1306,6 +1328,8 @@ e_mail_formatter_set_charset (EMailFormatter *formatter,
formatter->priv->charset = g_strdup (charset);
}
+ g_mutex_unlock (&formatter->priv->property_lock);
+
g_object_notify (G_OBJECT (formatter), "charset");
}
@@ -1317,6 +1341,20 @@ e_mail_formatter_get_default_charset (EMailFormatter *formatter)
return formatter->priv->default_charset;
}
+gchar *
+e_mail_formatter_dup_default_charset (EMailFormatter *formatter)
+{
+ gchar *default_charset;
+
+ g_return_val_if_fail (E_IS_MAIL_FORMATTER (formatter), NULL);
+
+ g_mutex_lock (&formatter->priv->property_lock);
+ default_charset = g_strdup (e_mail_formatter_get_default_charset (formatter));
+ g_mutex_unlock (&formatter->priv->property_lock);
+
+ return default_charset;
+}
+
void
e_mail_formatter_set_default_charset (EMailFormatter *formatter,
const gchar *default_charset)
@@ -1324,12 +1362,18 @@ e_mail_formatter_set_default_charset (EMailFormatter *formatter,
g_return_if_fail (E_IS_MAIL_FORMATTER (formatter));
g_return_if_fail (default_charset && *default_charset);
- if (g_strcmp0 (formatter->priv->default_charset, default_charset) == 0)
+ g_mutex_lock (&formatter->priv->property_lock);
+
+ if (g_strcmp0 (formatter->priv->default_charset, default_charset) == 0) {
+ g_mutex_unlock (&formatter->priv->property_lock);
return;
+ }
g_free (formatter->priv->default_charset);
formatter->priv->default_charset = g_strdup (default_charset);
+ g_mutex_unlock (&formatter->priv->property_lock);
+
g_object_notify (G_OBJECT (formatter), "default-charset");
}
@@ -1366,6 +1410,46 @@ e_mail_formatter_get_headers (EMailFormatter *formatter)
}
/**
+ * e_mail_formatter_dup_headers:
+ * @formatter: an #EMailFormatter
+ *
+ * Returns copy of a list of currently set headers.
+ *
+ * Returns: (transfer-full): A new #GQueue of currently set headers; the pointer should
+ * be freed when no longer needed with command:
+ * g_queue_free_full (queue, (GDestroyNotify) e_mail_formatter_header_free);
+ */
+GQueue *
+e_mail_formatter_dup_headers (EMailFormatter *formatter)
+{
+ GQueue *header_list;
+ GList *link;
+
+ g_return_val_if_fail (E_IS_MAIL_FORMATTER (formatter), NULL);
+
+ g_mutex_lock (&formatter->priv->property_lock);
+
+ header_list = g_queue_new ();
+ for (link = g_queue_peek_head_link ((GQueue *) e_mail_formatter_get_headers (formatter));
+ link;
+ link = g_list_next (link)) {
+ EMailFormatterHeader *h = link->data, *copy;
+
+ if (!h)
+ continue;
+
+ copy = e_mail_formatter_header_new (h->name, h->value);
+ copy->flags = h->flags;
+
+ g_queue_push_tail (header_list, copy);
+ }
+
+ g_mutex_unlock (&formatter->priv->property_lock);
+
+ return header_list;
+}
+
+/**
* e_mail_formatter_clear_headers:
* @formatter: an #EMailFormatter
*
@@ -1379,9 +1463,13 @@ e_mail_formatter_clear_headers (EMailFormatter *formatter)
g_return_if_fail (E_IS_MAIL_FORMATTER (formatter));
+ g_mutex_lock (&formatter->priv->property_lock);
+
while ((header = g_queue_pop_head (formatter->priv->header_list)) != NULL) {
e_mail_formatter_header_free (header);
}
+
+ g_mutex_unlock (&formatter->priv->property_lock);
}
/**
@@ -1432,7 +1520,10 @@ e_mail_formatter_add_header (EMailFormatter *formatter,
h = e_mail_formatter_header_new (name, value);
h->flags = flags;
+
+ g_mutex_lock (&formatter->priv->property_lock);
g_queue_push_tail (formatter->priv->header_list, h);
+ g_mutex_unlock (&formatter->priv->property_lock);
g_signal_emit (formatter, signals[NEED_REDRAW], 0, NULL);
}
@@ -1447,15 +1538,18 @@ e_mail_formatter_add_header_struct (EMailFormatter *formatter,
e_mail_formatter_add_header (formatter, header->name, header->value, header->flags);
}
-void e_mail_formatter_remove_header (EMailFormatter *formatter,
- const gchar *name,
- const gchar *value)
+void
+e_mail_formatter_remove_header (EMailFormatter *formatter,
+ const gchar *name,
+ const gchar *value)
{
GList *iter = NULL;
g_return_if_fail (E_IS_MAIL_FORMATTER (formatter));
g_return_if_fail (name && *name);
+ g_mutex_lock (&formatter->priv->property_lock);
+
iter = g_queue_peek_head_link (formatter->priv->header_list);
while (iter) {
EMailFormatterHeader *header = iter->data;
@@ -1485,6 +1579,8 @@ void e_mail_formatter_remove_header (EMailFormatter *formatter,
e_mail_formatter_header_free (iter->data);
g_queue_delete_link (formatter->priv->header_list, iter);
}
+
+ g_mutex_unlock (&formatter->priv->property_lock);
}
void
diff --git a/em-format/e-mail-formatter.h b/em-format/e-mail-formatter.h
index c85096912e..93e5268950 100644
--- a/em-format/e-mail-formatter.h
+++ b/em-format/e-mail-formatter.h
@@ -217,16 +217,20 @@ void e_mail_formatter_set_show_real_date
gboolean show_real_date);
const gchar * e_mail_formatter_get_charset (EMailFormatter *formatter);
+gchar * e_mail_formatter_dup_charset (EMailFormatter *formatter);
void e_mail_formatter_set_charset (EMailFormatter *formatter,
const gchar *charset);
const gchar * e_mail_formatter_get_default_charset
(EMailFormatter *formatter);
+gchar * e_mail_formatter_dup_default_charset
+ (EMailFormatter *formatter);
void e_mail_formatter_set_default_charset
(EMailFormatter *formatter,
const gchar *charset);
const GQueue * e_mail_formatter_get_headers (EMailFormatter *formatter);
+GQueue * e_mail_formatter_dup_headers (EMailFormatter *formatter);
void e_mail_formatter_clear_headers (EMailFormatter *formatter);
diff --git a/mail/e-mail-printer.c b/mail/e-mail-printer.c
index 4df136ebb8..475f49af8a 100644
--- a/mail/e-mail-printer.c
+++ b/mail/e-mail-printer.c
@@ -649,6 +649,7 @@ emp_set_parts_list (EMailPrinter *emp,
CamelMediumHeader *header;
CamelMimeMessage *message;
GArray *headers;
+ GQueue *headers_queue;
gint i;
GtkTreeIter last_known = { 0 };
@@ -667,6 +668,7 @@ emp_set_parts_list (EMailPrinter *emp,
if (!headers)
return;
+ headers_queue = e_mail_formatter_dup_headers (E_MAIL_FORMATTER (emp->priv->formatter));
for (i = 0; i < headers->len; i++) {
GtkTreeIter iter;
GList *found_header;
@@ -675,10 +677,7 @@ emp_set_parts_list (EMailPrinter *emp,
header = &g_array_index (headers, CamelMediumHeader, i);
emfh = e_mail_formatter_header_new (header->name, header->value);
- found_header = g_queue_find_custom (
- (GQueue *) e_mail_formatter_get_headers (
- E_MAIL_FORMATTER (emp->priv->formatter)),
- emfh, (GCompareFunc) emp_header_name_equal);
+ found_header = g_queue_find_custom (headers_queue, emfh, (GCompareFunc) emp_header_name_equal);
if (!found_header) {
emfh->flags |= E_MAIL_FORMATTER_HEADER_FLAG_HIDDEN;
@@ -702,6 +701,7 @@ emp_set_parts_list (EMailPrinter *emp,
COLUMN_HEADER_STRUCT, emfh, -1);
}
+ g_queue_free_full (headers_queue, (GDestroyNotify) e_mail_formatter_header_free);
camel_medium_free_headers (CAMEL_MEDIUM (message), headers);
}