Added the function that quotes emails
[modest] / src / modest-text-utils.c
index 5b7c0bd..ae7f8eb 100644 (file)
@@ -342,6 +342,39 @@ modest_text_utils_derived_subject (const gchar *subject, const gchar *prefix)
        return retval;
 }
 
        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)
 {
 gchar*
 modest_text_utils_remove_address (const gchar *address_list, const gchar *address)
 {
@@ -350,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);
        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);
        if (!address)
                return g_strdup (address_list);
 
        email_address = get_email_from_address (address);
-       
+
        /* search for substring */
        /* 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);
                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 */
        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
                        if (filtered_emails->len == 0)
                                g_string_append_printf (filtered_emails, "%s", g_strstrip (token));
                        else
@@ -454,7 +487,7 @@ modest_text_utils_convert_buffer_to_html_start (GString *html, const gchar *data
                guchar kar = data[i];
                
                if (space_seen && kar != ' ') {
                guchar kar = data[i];
                
                if (space_seen && kar != ' ') {
-                       g_string_append (html, "&nbsp;");
+                       g_string_append (html, " ");
                        space_seen = FALSE;
                }
                
                        space_seen = FALSE;
                }
                
@@ -491,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, "&nbsp; ");
                        break_dist = 0;
                        if (space_seen) { /* second space in a row */
                                g_string_append (html, "&nbsp; ");
-                               space_seen = FALSE;
                        } else
                                space_seen = TRUE;
                        break;
                        } else
                                space_seen = TRUE;
                        break;
@@ -941,6 +973,7 @@ modest_text_utils_quote_body (GString *output, const gchar *text,
                                g_string_prepend (l, remaining->str);
                        } else {
                                do {
                                g_string_prepend (l, remaining->str);
                        } else {
                                do {
+                                       gunichar remaining_first;
                                        breakpoint =
                                                get_breakpoint (remaining->str,
                                                                rem_indent,
                                        breakpoint =
                                                get_breakpoint (remaining->str,
                                                                rem_indent,
@@ -949,9 +982,11 @@ modest_text_utils_quote_body (GString *output, const gchar *text,
                                                       remaining, breakpoint);
                                        g_string_erase (remaining, 0,
                                                        breakpoint);
                                                       remaining, breakpoint);
                                        g_string_erase (remaining, 0,
                                                        breakpoint);
-                                       if (remaining->str[0] == ' ') {
-                                               g_string_erase (remaining, 0,
-                                                               1);
+                                       remaining_first = g_utf8_get_char_validated (remaining->str, remaining->len);
+                                       if (remaining_first != ((gunichar) -1)) {
+                                               if (g_unichar_isspace (remaining_first)) {
+                                                       g_string_erase (remaining, 0, g_utf8_next_char (remaining->str) - remaining->str);
+                                               }
                                        }
                                } while (remaining->len);
                        }
                                        }
                                } while (remaining->len);
                        }
@@ -1664,6 +1699,7 @@ modest_text_utils_validate_recipient (const gchar *recipient, const gchar **inva
 
        /* quoted string */
        if (*current == '\"') {
 
        /* quoted string */
        if (*current == '\"') {
+               gchar *last_quote = NULL;
                current = g_utf8_next_char (current);
                has_error = TRUE;
                for (; *current != '\0'; current = g_utf8_next_char (current)) {
                current = g_utf8_next_char (current);
                has_error = TRUE;
                for (; *current != '\0'; current = g_utf8_next_char (current)) {
@@ -1679,9 +1715,11 @@ modest_text_utils_validate_recipient (const gchar *recipient, const gchar **inva
                        } else if (*current == '\"') {
                                has_error = FALSE;
                                current = g_utf8_next_char (current);
                        } else if (*current == '\"') {
                                has_error = FALSE;
                                current = g_utf8_next_char (current);
-                               break;
+                               last_quote = current;
                        }
                }
                        }
                }
+               if (last_quote)
+                       current = last_quote;
        } else {
                has_error = TRUE;
                for (current = stripped ; *current != '\0'; current = g_utf8_next_char (current)) {
        } else {
                has_error = TRUE;
                for (current = stripped ; *current != '\0'; current = g_utf8_next_char (current)) {
@@ -1701,6 +1739,9 @@ modest_text_utils_validate_recipient (const gchar *recipient, const gchar **inva
        g_free (stripped);
        right_part = g_strstrip (right_part);
 
        g_free (stripped);
        right_part = g_strstrip (right_part);
 
+       if (g_str_has_suffix (right_part, ",") || g_str_has_suffix (right_part, ";"))
+               right_part [(strlen (right_part) - 1)] = '\0';
+
        if (g_str_has_prefix (right_part, "<") &&
            g_str_has_suffix (right_part, ">")) {
                gchar *address;
        if (g_str_has_prefix (right_part, "<") &&
            g_str_has_suffix (right_part, ">")) {
                gchar *address;
@@ -2043,3 +2084,84 @@ modest_text_utils_get_secure_header (const gchar *value,
 
        return new_value;
 }
 
        return new_value;
 }
+
+static gboolean
+is_quoted (const char *start, const gchar *end)
+{
+       gchar *c;
+
+       c = (gchar *) start;
+       while (*c == ' ')
+               c = g_utf8_next_char (c);
+
+       if (*c == '\0' || *c != '\"')
+               return FALSE;
+
+       c = (gchar *) end;
+       while (*c == ' ' && c != start)
+               c = g_utf8_prev_char (c);
+
+       if (c == start || *c != '\"')
+               return FALSE;
+
+       return TRUE;
+}
+
+
+static void
+quote_name_part (GString **str, gchar **cur, gchar **start)
+{
+       gchar *blank;
+       gint str_len = g_utf8_pointer_to_offset (*start, *cur) -
+               g_utf8_pointer_to_offset (*start, *start) + 1;
+
+       while (**start == ' ')
+               *start = g_utf8_next_char (*start);
+
+       blank = g_utf8_strrchr (*start, str_len, g_utf8_get_char (" "));
+       if (blank && (blank != *start)) {
+               if (is_quoted (*start, blank - 1)) {
+                       *str = g_string_append_len (*str, *start, str_len - 1);
+                       *str = g_string_append (*str, ";\n ");
+                       *start = g_utf8_next_char (*cur);
+               } else {
+                       *str = g_string_append_c (*str, '"');
+                       *str = g_string_append_len (*str, *start,
+                                                   (g_utf8_pointer_to_offset (*start, blank) -
+                                                    g_utf8_pointer_to_offset (*start, *start)));
+                       *str = g_string_append_c (*str, '"');
+                       *str = g_string_append_len (*str, blank,
+                                                   (g_utf8_pointer_to_offset (*start, *cur) -
+                                                    g_utf8_pointer_to_offset (*start, blank)));
+                       *str = g_string_append (*str, ";\n");
+                       *start = g_utf8_next_char (*cur);
+               }
+       } else {
+               *str = g_string_append_len (*str, *start, (str_len - 1));
+               *str = g_string_append (*str, ";\n");
+               *start = g_utf8_next_char (*cur);
+       }
+}
+
+gchar *
+modest_text_utils_quote_names (const gchar *recipients)
+{
+       GString *str;
+       gchar *start, *cur;
+
+       str = g_string_new ("");
+       start = (gchar*) recipients;
+       cur = (gchar*) recipients;
+
+       for (cur = start; *cur != '\0'; cur = g_utf8_next_char (cur)) {
+               if (*cur == ',' || *cur == ';') {
+                       if (!g_utf8_strchr (start, (cur - start + 1), g_utf8_get_char ("@")))
+                               continue;
+                       quote_name_part (&str, &cur, &start);
+               }
+       }
+
+       quote_name_part (&str, &cur, &start);
+
+       return g_string_free (str, FALSE);
+}