Commit 0d96f08f authored by Milan Crha's avatar Milan Crha
Browse files

Bug #690092 - Crash under format_full_headers()

parent 98988600
......@@ -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>");
......
......@@ -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);
......
......@@ -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);
......
......@@ -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 ("");
......
......@@ -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");
}
......@@ -1365,6 +1409,46 @@ e_mail_formatter_get_headers (EMailFormatter *formatter)
return formatter->priv->header_list;
}
/**
* 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
......
......@@ -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);
......
......@@ -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);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment