diff options
author | Milan Crha <mcrha@redhat.com> | 2013-03-07 02:37:37 +0800 |
---|---|---|
committer | Milan Crha <mcrha@redhat.com> | 2013-03-07 02:38:19 +0800 |
commit | 0d96f08f9f0400ab9202f1dcdbaca1d891a41ac8 (patch) | |
tree | 16a25ce6707e5a61b86bedc3386e8412be764227 | |
parent | 989886007f3f69ca64e383ad6d64ef8c352f6df8 (diff) | |
download | gsoc2013-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.c | 27 | ||||
-rw-r--r-- | em-format/e-mail-formatter-print-headers.c | 8 | ||||
-rw-r--r-- | em-format/e-mail-formatter-quote-headers.c | 20 | ||||
-rw-r--r-- | em-format/e-mail-formatter-utils.c | 8 | ||||
-rw-r--r-- | em-format/e-mail-formatter.c | 114 | ||||
-rw-r--r-- | em-format/e-mail-formatter.h | 4 | ||||
-rw-r--r-- | mail/e-mail-printer.c | 8 |
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); } |