Refactored the code that joins the addresses in a single string
[modest] / src / modest-tny-msg.c
index 2da40e0..2399070 100644 (file)
@@ -334,8 +334,8 @@ add_attachments (TnyMimePart *part, GList *attachments_list, gboolean add_inline
 
                old_attachment = pos->data;
                if (!tny_mime_part_is_purged (old_attachment)) {
-                       const gchar *old_cid;
-                       old_cid = tny_mime_part_get_content_id (old_attachment);
+                       gchar *old_cid;
+                       old_cid = g_strdup (tny_mime_part_get_content_id (old_attachment));
                        attachment_part = copy_mime_part (old_attachment, err);
                        if (attachment_part != NULL) {
                                if (add_inline) {
@@ -343,12 +343,19 @@ add_attachments (TnyMimePart *part, GList *attachments_list, gboolean add_inline
                                                                       "inline");
                                } else {
                                        const gchar *filename;
+
                                        filename = tny_mime_part_get_filename (old_attachment);
-                                       if (filename)
-                                               tny_mime_part_set_filename (attachment_part, filename);
-                                       else
+                                       if (filename) {
+                                               /* If the mime part has a filename do not set it again
+                                                  because Camel won't replace the old one. Instead it
+                                                  will append the filename to the old one and that will
+                                                  mislead email clients */
+                                               if (!tny_mime_part_get_filename (attachment_part))
+                                                       tny_mime_part_set_filename (attachment_part, filename);
+                                       } else {
                                                tny_mime_part_set_header_pair (attachment_part, "Content-Disposition",
                                                                               "attachment");
+                                       }
                                }
                                if (!TNY_IS_MSG (old_attachment))  {
                                        tny_mime_part_set_transfer_encoding (TNY_MIME_PART (attachment_part), "base64");
@@ -359,6 +366,7 @@ add_attachments (TnyMimePart *part, GList *attachments_list, gboolean add_inline
                                        tny_mime_part_set_content_id (attachment_part, old_cid);
                                g_object_unref (attachment_part);
                        }
+                       g_free (old_cid);
                }
        }
        return attached;
@@ -382,7 +390,7 @@ add_images (TnyMsg *msg, GList *images_list, GError **err)
 
                while (!tny_iterator_is_done (iter)) {
                        TnyMimePart *part = TNY_MIME_PART (tny_iterator_get_current (iter));
-                       if (part && !g_strcasecmp (tny_mime_part_get_content_type (part), "multipart/related")) {
+                       if (part && !g_ascii_strcasecmp (tny_mime_part_get_content_type (part), "multipart/related")) {
                                related_part = part;
                                break;
                        }
@@ -920,6 +928,38 @@ count_addresses (const gchar* addresses)
        return count;
 }
 
+static void
+remove_undisclosed_recipients (gchar **recipients)
+{
+       GSList *addresses, *node;
+       gboolean is_first;
+       GString *result;
+
+       g_return_if_fail (recipients);
+       addresses = modest_text_utils_split_addresses_list (*recipients);
+
+       is_first = TRUE;
+       result = g_string_new ("");
+       for (node = addresses; node != NULL; node = g_slist_next (node)) {
+               const gchar *address = (const gchar *) node->data;
+
+               if (address && strstr (address, "undisclosed-recipients"))
+                       continue;
+
+               if (is_first)
+                       is_first = FALSE;
+               else
+                       result = g_string_append (result, ", ");
+
+               result = g_string_append (result, address);
+       }
+       g_slist_foreach (addresses, (GFunc)g_free, NULL);
+       g_slist_free (addresses);
+
+       g_free (*recipients);
+       *recipients = g_string_free (result, FALSE);
+}
+
 
 /* get the new To:, based on the old header,
  * result is newly allocated or NULL in case of error
@@ -928,6 +968,8 @@ static gchar*
 get_new_to (TnyMsg *msg, TnyHeader *header, const gchar* from,
            ModestTnyMsgReplyMode reply_mode)
 {
+       const gchar *reply_header = "Reply-To:";
+       const gchar *from_header = "From:";
        gchar* old_reply_to;
        gchar* old_from;
        gchar* new_to;
@@ -948,13 +990,25 @@ get_new_to (TnyMsg *msg, TnyHeader *header, const gchar* from,
        old_reply_to = modest_tny_mime_part_get_header_value (TNY_MIME_PART(msg), 
                                                              "Reply-To"); 
        old_from     = tny_header_dup_from (header);
-       
+
        if (!old_from && !old_reply_to) {
                g_debug ("%s: failed to get either Reply-To: or From: from header",
                           __FUNCTION__);
                return NULL;
        }
-       
+
+       /* Prevent DoS attacks caused by malformed emails */
+       if (old_from) {
+               gchar *tmp = old_from;
+               old_from = modest_text_utils_get_secure_header ((const gchar *) tmp, from_header);
+               g_free (tmp);
+       }
+       if (old_reply_to) {
+               gchar *tmp = old_reply_to;
+               old_reply_to = modest_text_utils_get_secure_header ((const gchar *) tmp, reply_header);
+               g_free (tmp);
+       }
+
        /* for mailing lists, use both Reply-To and From if we did a
         * 'Reply All:'
         * */
@@ -996,6 +1050,7 @@ get_new_to (TnyMsg *msg, TnyHeader *header, const gchar* from,
        }
 
        tmp = modest_text_utils_simplify_recipients (new_to);
+       remove_undisclosed_recipients  (&tmp);
        g_free (new_to);
        new_to = tmp;
 
@@ -1035,6 +1090,7 @@ get_new_cc (TnyHeader *header, const gchar* from, const gchar *new_to)
        g_free (dup);
        dup = result;
        result = modest_text_utils_simplify_recipients (dup);
+       remove_undisclosed_recipients  (&result);
        g_free (dup);
        g_free (old_cc);
        return result;
@@ -1065,13 +1121,13 @@ modest_tny_msg_get_references (TnyMsg *msg, gchar **message_id, gchar **referenc
 
                pair = TNY_PAIR (tny_iterator_get_current (iterator));
                name = tny_pair_get_name (pair);
-               if (!g_strcasecmp (name, "References")) {
+               if (!g_ascii_strcasecmp (name, "References")) {
                        if (l_references) g_free (l_references);
                        l_references = g_strdup (tny_pair_get_value (pair));
-               } else if (!g_strcasecmp (name, "In-Reply-To")) {
+               } else if (!g_ascii_strcasecmp (name, "In-Reply-To")) {
                        if (l_in_reply_to) g_free (l_in_reply_to);
                        l_in_reply_to = g_strdup (tny_pair_get_value (pair));
-               } else if (!g_strcasecmp (name, "Message-ID")) {
+               } else if (!g_ascii_strcasecmp (name, "Message-ID")) {
                        if (l_message_id) g_free (l_message_id);
                        l_message_id = g_strdup (tny_pair_get_value (pair));
                }
@@ -1274,56 +1330,32 @@ modest_tny_msg_header_get_all_recipients_list (TnyHeader *header)
 {
        GSList *recipients = NULL;
        gchar *from = NULL, *to = NULL, *cc = NULL, *bcc = NULL;
-       gchar *after_remove;
-       GString *buffer;
-       gboolean add_separator = TRUE;
+       gchar *after_remove, *joined;
 
        if (header == NULL)
                return NULL;
 
-       buffer = g_string_new ("");
-
        from = tny_header_dup_from (header);
        to = tny_header_dup_to (header);
        cc = tny_header_dup_cc (header);
        bcc = tny_header_dup_bcc (header);
 
-       recipients = NULL;
-       if (from) {
-               buffer = g_string_append (buffer, from);
-               add_separator = TRUE;
-       }
-       if (to) {
-               if (add_separator)
-                       buffer = g_string_append (buffer, "; ");
-               else
-                       add_separator = TRUE;
-
-               buffer = g_string_append (buffer, to);
-       }
-       if (cc) {
-               if (add_separator)
-                       buffer = g_string_append (buffer, "; ");
-               else
-                       add_separator = TRUE;
-
-               buffer = g_string_append (buffer, cc);
-       }
-       if (bcc) {
-               if (add_separator)
-                       buffer = g_string_append (buffer, "; ");
-               else
-                       add_separator = TRUE;
-
-               buffer = g_string_append (buffer, bcc);
-       }
-
-       after_remove = modest_text_utils_remove_duplicate_addresses (buffer->str);
-       g_string_free (buffer, TRUE);
+       joined = modest_text_utils_join_addresses (from, to, cc, bcc);
+       after_remove = modest_text_utils_remove_duplicate_addresses (joined);
+       g_free (joined);
 
        recipients = modest_text_utils_split_addresses_list (after_remove);
        g_free (after_remove);
 
+       if (from)
+               g_free (from);
+       if (to)
+               g_free (to);
+       if (cc)
+               g_free (cc);
+       if (bcc)
+               g_free (bcc);
+
        return recipients;
 }