X-Git-Url: http://git.maemo.org/git/?p=modest;a=blobdiff_plain;f=src%2Fmodest-text-utils.c;h=020b160e0a13e0cc22f1ccdcf28b442eb40010b6;hp=7a89d08657dccaa1090aeb935a1c2061e5e8ea2b;hb=a97791ec68e7d15593080049399bda9366517b1e;hpb=cfd46b1d74a13b1b8066bc64dfdabf43d49d2f2d diff --git a/src/modest-text-utils.c b/src/modest-text-utils.c index 7a89d08..020b160 100644 --- a/src/modest-text-utils.c +++ b/src/modest-text-utils.c @@ -63,8 +63,6 @@ * will hang modest */ #define HYPERLINKIFY_MAX_LENGTH (1024*50) -#define SIGNATURE_MARKER "--" - /* * we need these regexps to find URLs in plain text e-mails @@ -216,7 +214,7 @@ modest_text_utils_cite (const gchar *text, if (!signature) { tmp_sig = g_strdup (text); } else { - tmp_sig = g_strconcat (text, "\n", SIGNATURE_MARKER, "\n", signature, NULL); + tmp_sig = g_strconcat (text, "\n", MODEST_TEXT_UTILS_SIGNATURE_MARKER, "\n", signature, NULL); } if (strcmp (content_type, "text/html") == 0) { @@ -318,7 +316,23 @@ modest_text_utils_derived_subject (const gchar *subject, const gchar *prefix) tmp += prefix_len; tmp = g_strchug (tmp); } else { - break; + gchar *prefix_down, *tmp_down; + + /* We need this to properly check the cases of + some clients adding FW: instead of Fw: for + example */ + prefix_down = g_utf8_strdown (prefix, -1); + tmp_down = g_utf8_strdown (tmp, -1); + if (g_str_has_prefix (tmp_down, prefix_down)) { + tmp += prefix_len; + tmp = g_strchug (tmp); + g_free (prefix_down); + g_free (tmp_down); + } else { + g_free (prefix_down); + g_free (tmp_down); + break; + } } } while (tmp); @@ -328,6 +342,39 @@ modest_text_utils_derived_subject (const gchar *subject, const gchar *prefix) return retval; } + +/* Performs a case-insensitive strstr for ASCII strings */ +static const gchar * +ascii_stristr(const gchar *haystack, const gchar *needle) +{ + int needle_len; + int haystack_len; + const gchar *pos; + const gchar *max_pos; + + if (haystack == NULL || needle == NULL) { + return haystack; /* as in strstr */ + } + + needle_len = strlen(needle); + + if (needle_len == 0) { + return haystack; /* as in strstr */ + } + + haystack_len = strlen(haystack); + max_pos = haystack + haystack_len - needle_len; + + for (pos = haystack; pos <= max_pos; pos++) { + if (g_ascii_strncasecmp (pos, needle, needle_len) == 0) { + return pos; + } + } + + return NULL; +} + + gchar* modest_text_utils_remove_address (const gchar *address_list, const gchar *address) { @@ -336,26 +383,26 @@ modest_text_utils_remove_address (const gchar *address_list, const gchar *addres gchar *email_address; g_return_val_if_fail (address_list, NULL); - + if (!address) return g_strdup (address_list); email_address = get_email_from_address (address); - + /* search for substring */ - if (!strstr ((const char *) address_list, (const char *) email_address)) { + if (!ascii_stristr ((const char *) address_list, (const char *) email_address)) { g_free (email_address); return g_strdup (address_list); } dup = g_strdup (address_list); filtered_emails = g_string_new (NULL); - + token = strtok_r (dup, ",", &ptr); while (token != NULL) { /* Add to list if not found */ - if (!strstr ((const char *) token, (const char *) email_address)) { + if (!ascii_stristr ((const char *) token, (const char *) email_address)) { if (filtered_emails->len == 0) g_string_append_printf (filtered_emails, "%s", g_strstrip (token)); else @@ -418,6 +465,9 @@ modest_text_utils_remove_duplicate_addresses (const gchar *address_list) g_slist_foreach (addresses, (GFunc)g_free, NULL); g_slist_free (addresses); + if (new_list == NULL) + new_list = g_strdup (""); + return new_list; } @@ -437,7 +487,7 @@ modest_text_utils_convert_buffer_to_html_start (GString *html, const gchar *data guchar kar = data[i]; if (space_seen && kar != ' ') { - g_string_append_c (html, ' '); + g_string_append (html, " "); space_seen = FALSE; } @@ -474,7 +524,6 @@ modest_text_utils_convert_buffer_to_html_start (GString *html, const gchar *data break_dist = 0; if (space_seen) { /* second space in a row */ g_string_append (html, "  "); - space_seen = FALSE; } else space_seen = TRUE; break; @@ -768,7 +817,7 @@ get_indent_level (const char *l) /* if we hit the signature marker "-- ", we return -(indent + 1). This * stops reformatting. */ - if (strcmp (l, "-- ") == 0) { + if (strcmp (l, MODEST_TEXT_UTILS_SIGNATURE_MARKER) == 0) { return -1 - indent; } else { return indent; @@ -966,7 +1015,7 @@ modest_text_utils_quote_plain_text (const gchar *text, q = g_string_new (""); if (signature != NULL) { - q = g_string_append (q, "\n--\n"); + g_string_append_printf (q, "\n%s\n", MODEST_TEXT_UTILS_SIGNATURE_MARKER); q = g_string_append (q, signature); } @@ -1013,7 +1062,7 @@ modest_text_utils_quote_html (const gchar *text, GString *quoted_text; g_string_append (result_string, "
\n");
 		if (signature) {
-			quote_html_add_to_gstring (result_string, SIGNATURE_MARKER);
+			quote_html_add_to_gstring (result_string, MODEST_TEXT_UTILS_SIGNATURE_MARKER);
 			quote_html_add_to_gstring (result_string, signature);
 		}
 		quote_html_add_to_gstring (result_string, cite);
@@ -1274,7 +1323,37 @@ modest_text_utils_get_display_address (gchar *address)
 }
 
 
+gchar *
+modest_text_utils_get_display_addresses (const gchar *recipients)
+{
+	gchar *addresses;
+	GSList *recipient_list;
+
+	addresses = NULL;
+	recipient_list = modest_text_utils_split_addresses_list (recipients);
+	if (recipient_list) {
+		GString *add_string = g_string_sized_new (strlen (recipients));
+		GSList *iter = recipient_list;
+		gboolean first = TRUE;
+
+		while (iter) {
+			/* Strings are changed in place */
+			modest_text_utils_get_display_address ((gchar *) iter->data);
+			if (G_UNLIKELY (first)) {
+				g_string_append_printf (add_string, "%s", (gchar *) iter->data);
+				first = FALSE;
+			} else {
+				g_string_append_printf (add_string, ", %s", (gchar *) iter->data);
+			}
+			iter = g_slist_next (iter);
+		}
+		g_slist_foreach (recipient_list, (GFunc) g_free, NULL);
+		g_slist_free (recipient_list);
+		addresses = g_string_free (add_string, FALSE);
+	}
 
+	return addresses;
+}
 
 
 gchar *
@@ -1685,11 +1764,11 @@ modest_text_utils_get_display_size (guint64 size)
 	else if (KB <= size && size < 100 * KB)
 		return g_strdup_printf (_FM("sfil_li_size_1kb_99kb"), (int) size / KB);
 	else if (100*KB <= size && size < MB)
-		return g_strdup_printf (_FM("sfil_li_size_100kb_1mb"), (float) size / MB);
+		return g_strdup_printf (_FM("sfil_li_size_100kb_1mb"), (int) size / KB);
 	else if (MB <= size && size < 10*MB)
 		return g_strdup_printf (_FM("sfil_li_size_1mb_10mb"), (float) size / MB);
 	else if (10*MB <= size && size < GB)
-		return g_strdup_printf (_FM("sfil_li_size_10mb_1gb"), (int) size / MB);
+		return g_strdup_printf (_FM("sfil_li_size_10mb_1gb"), (float) size / MB);
 	else
 		return g_strdup_printf (_FM("sfil_li_size_1gb_or_greater"), (float) size / GB);
 }
@@ -1891,6 +1970,7 @@ modest_text_utils_simplify_recipients (const gchar *recipients)
 	for (node = addresses; node != NULL; node = g_slist_next (node)) {
 		const gchar *address = (const gchar *) node->data;
 		gchar *left_limit, *right_limit;
+
 		left_limit = strstr (address, "<");
 		right_limit = g_strrstr (address, ">");
 
@@ -1924,3 +2004,74 @@ modest_text_utils_simplify_recipients (const gchar *recipients)
 	return g_string_free (result, FALSE);
 
 }
+
+GSList *
+modest_text_utils_remove_duplicate_addresses_list (GSList *address_list)
+{
+	GSList *new_list, *iter;
+	GHashTable *table;
+
+	g_return_val_if_fail (address_list, NULL);
+
+	table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+	new_list = address_list;
+	iter = address_list;
+	while (iter) {
+		const gchar* address = (const gchar*)iter->data;
+
+		/* We need only the email to just compare it and not
+		   the full address which would make "a "
+		   different from "a@a.com" */
+		const gchar *email = get_email_from_address (address);
+
+		/* ignore the address if already seen */
+		if (g_hash_table_lookup (table, email) == 0) {
+			g_hash_table_insert (table, (gchar*)email, GINT_TO_POINTER(1));
+			iter = g_slist_next (iter);
+		} else {
+			GSList *tmp = g_slist_next (iter);
+			new_list = g_slist_delete_link (new_list, iter);
+			iter = tmp;
+		}
+	}
+
+	g_hash_table_unref (table);
+
+	return new_list;
+}
+
+gchar *
+modest_text_utils_get_secure_header (const gchar *value,
+				     const gchar *header)
+{
+	const gint max_len = 128;
+	gchar *new_value = NULL;
+	gchar *needle = g_strrstr (value, header);
+
+	if (needle && value != needle)
+		new_value = g_strdup (needle + strlen (header));
+
+	if (!new_value)
+		new_value = g_strdup (value);
+
+	/* Do a max length check to prevent DoS attacks caused by huge
+	   malformed headers */
+	if (g_utf8_validate (new_value, -1, NULL)) {
+		if (g_utf8_strlen (new_value, -1) > max_len) {
+			gchar *tmp = g_malloc0 (max_len * 4);
+			g_utf8_strncpy (tmp, (const gchar *) new_value, max_len);
+			g_free (new_value);
+			new_value = tmp;
+		}
+	} else {
+		if (strlen (new_value) > max_len) {
+			gchar *tmp = g_malloc0 (max_len);
+			strncpy (new_value, tmp, max_len);
+			g_free (new_value);
+			new_value = tmp;
+		}
+	}
+
+	return new_value;
+}