* fix for NB#67837, NB#63633
[modest] / src / modest-text-utils.c
index f01e706..8a83e60 100644 (file)
  */
 
 
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif /*_GNU_SOURCE*/
+#include <string.h> /* for strcasestr */
+
+
 #include <glib.h>
-#include <string.h>
 #include <stdlib.h>
 #include <glib/gi18n.h>
 #include <regex.h>
 #endif /*HAVE_CONFIG_H */
 
 /* defines */
-#define FORWARD_STRING _("-----Forwarded Message-----")
-#define FROM_STRING _("From:")
-#define SENT_STRING _("Sent:")
-#define TO_STRING _("To:")
-#define        SUBJECT_STRING _("Subject:")
+#define FORWARD_STRING _("mcen_ia_editor_original_message")
+#define FROM_STRING _("mail_va_from")
+#define SENT_STRING _("mcen_fi_message_properties_sent")
+#define TO_STRING _("mail_va_to")
+#define        SUBJECT_STRING _("mail_va_subject")
 #define EMPTY_STRING ""
 
 /*
@@ -90,6 +96,19 @@ struct _url_match_t {
          NULL, "mailto:"}\
        }
 
+const gchar account_title_forbidden_chars[] = {
+       '\\', '/', ':', '*', '?', '\'', '<', '>', '|', '^'
+};
+const gchar folder_name_forbidden_chars[] = {
+       '<', '>', ':', '\'', '/', '\\', '|', '?', '*', '^', '%', '$'
+};
+const gchar user_name_forbidden_chars[] = {
+       '<', '>'
+};
+const guint ACCOUNT_TITLE_FORBIDDEN_CHARS_LENGTH = G_N_ELEMENTS (account_title_forbidden_chars);
+const guint FOLDER_NAME_FORBIDDEN_CHARS_LENGTH = G_N_ELEMENTS (folder_name_forbidden_chars);
+const guint USER_NAME_FORBIDDEN_CHARS_LENGTH = G_N_ELEMENTS (user_name_forbidden_chars);
+
 /* private */
 static gchar*   cite                    (const time_t sent_date, const gchar *from);
 static void     hyperlinkify_plain_text (GString *txt);
@@ -161,18 +180,18 @@ modest_text_utils_cite (const gchar *text,
 {
        gchar *retval;
        gchar *tmp_sig;
-
+       
        g_return_val_if_fail (text, NULL);
        g_return_val_if_fail (content_type, NULL);
-
+       
        if (!signature)
                retval = g_strdup ("");
-       else if (!strcmp(content_type, "text/html")) {
+       else if (strcmp(content_type, "text/html") == 0) {
                tmp_sig = g_strconcat ("\n", signature, NULL);
                retval = modest_text_utils_convert_to_html_body(tmp_sig);
                g_free (tmp_sig);
        } else {
-               retval = g_strconcat ("\n", signature, NULL);
+               retval = g_strconcat (text, "\n", signature, NULL);
        }
 
        return retval;
@@ -180,9 +199,9 @@ modest_text_utils_cite (const gchar *text,
 
 static gchar *
 forward_cite (const gchar *from,
-                   const gchar *sent,
-                   const gchar *to,
-                   const gchar *subject)
+             const gchar *sent,
+             const gchar *to,
+             const gchar *subject)
 {
        return g_strdup_printf ("%s\n%s %s\n%s %s\n%s %s\n%s %s\n", 
                                FORWARD_STRING, 
@@ -242,9 +261,9 @@ modest_text_utils_derived_subject (const gchar *subject, const gchar *prefix)
        gchar *tmp;
 
        g_return_val_if_fail (prefix, NULL);
-       
-       if (!subject)
-               return g_strdup (prefix);
+
+       if (!subject || subject[0] == '\0')
+               subject = _("mail_va_no_subject");
 
        tmp = g_strchug (g_strdup (subject));
 
@@ -335,7 +354,9 @@ modest_text_utils_convert_buffer_to_html (GString *html, const gchar *data)
                case '>'  : g_string_append (html, "&gt;");   break;
                case '&'  : g_string_append (html, "&amp;");  break;
                case '"'  : g_string_append (html, "&quot;");  break;
-               case '\'' : g_string_append (html, "&apos;"); break;
+
+               /* don't convert &apos; --> wpeditor will try to re-convert it... */    
+               //case '\'' : g_string_append (html, "&apos;"); break;
                case '\n' : g_string_append (html, "<br>\n");              break_dist= 0; break;
                case '\t' : g_string_append (html, "&nbsp;&nbsp;&nbsp; "); break_dist=0; break; /* note the space at the end*/
                case ' ':
@@ -814,6 +835,7 @@ modest_text_utils_quote_html (const gchar *text,
        g_free (attachments_string);
        g_free (q_attachments_string);
        g_free (signature_result);
+       
        return result;
 }
 
@@ -875,7 +897,6 @@ get_url_matches (GString *txt)
                                match->offset = offset + rm.rm_so;
                                match->len    = rm.rm_eo - rm.rm_so;
                                match->prefix = patterns[i].prefix;
-                               g_warning ("<%d, %d, %s>",  match->offset, match->len, match->prefix);
                                match_list = g_slist_prepend (match_list, match);
                        }
                                
@@ -1071,6 +1092,51 @@ modest_text_utils_get_display_date (time_t date)
 
 
 gboolean
+modest_text_utils_validate_folder_name (const gchar *folder_name)
+{
+       /* based on http://msdn2.microsoft.com/en-us/library/aa365247.aspx,
+        * with some extras */
+       
+       guint len;
+       gint i;
+       const gchar **cursor = NULL;
+       const gchar *forbidden_names[] = { /* windows does not like these */
+               "CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6",
+               "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9",
+               ".", "..", NULL
+       };
+       
+       /* cannot be NULL */
+       if (!folder_name) 
+               return FALSE;
+
+       /* cannot be empty */
+       len = strlen(folder_name);
+       if (len == 0)
+               return FALSE;
+       
+       /* cannot start or end with a space */
+       if (g_ascii_isspace(folder_name[0]) || g_ascii_isspace(folder_name[len - 1]))
+               return FALSE; 
+
+       /* cannot contain a forbidden char */   
+       for (i = 0; i < len; i++)
+               if (modest_text_utils_is_forbidden_char (folder_name[i], FOLDER_NAME_FORBIDDEN_CHARS))
+                       return FALSE;
+       
+       /* cannot contain a forbidden word */
+       if (len <= 4) {
+               for (cursor = forbidden_names; cursor && *cursor; ++cursor) {
+                       if (g_ascii_strcasecmp (folder_name, *cursor) == 0)
+                               return FALSE;
+               }
+       }
+       return TRUE; /* it's valid! */
+}
+
+
+
+gboolean
 modest_text_utils_validate_domain_name (const gchar *domain)
 {
        gboolean valid = FALSE;
@@ -1104,7 +1170,14 @@ modest_text_utils_validate_email_address (const gchar *email_address, const gcha
 
        if (invalid_char_position != NULL)
                *invalid_char_position = NULL;
-
+       
+       /* check that the email adress contains exactly one @ */
+       if (!strstr(email_address, "@") || 
+                       (strstr(email_address, "@") != g_strrstr(email_address, "@")))
+       {
+               return FALSE;
+       }
+       
        /* first we validate the name portion (name@domain) */
        for (c = email_address;  *c;  c++) {
                if (*c == '\"' && 
@@ -1145,7 +1218,7 @@ modest_text_utils_validate_email_address (const gchar *email_address, const gcha
                return FALSE;
        do {
                if (*c == '.') {
-                       if (c == domain || *(c - 1) == '.') 
+                       if (c == domain || *(c - 1) == '.' || *(c + 1) == '\0') 
                                return FALSE;
                        count++;
                }
@@ -1319,3 +1392,36 @@ modest_text_utils_text_buffer_get_text (GtkTextBuffer *buffer)
        return g_string_free (result, FALSE);
        
 }
+
+gboolean
+modest_text_utils_is_forbidden_char (const gchar character,
+                                    ModestTextUtilsForbiddenCharType type)
+{
+       gint i, len;
+       const gchar *forbidden_chars = NULL;
+       
+       /* We need to get the length in the switch because the
+          compiler needs to know the size at compile time */
+       switch (type) {
+       case ACCOUNT_TITLE_FORBIDDEN_CHARS:
+               forbidden_chars = account_title_forbidden_chars;
+               len = G_N_ELEMENTS (account_title_forbidden_chars);
+               break;
+       case FOLDER_NAME_FORBIDDEN_CHARS:
+               forbidden_chars = folder_name_forbidden_chars;
+               len = G_N_ELEMENTS (folder_name_forbidden_chars);
+               break;
+       case USER_NAME_FORBIDDEN_NAMES:
+               forbidden_chars = user_name_forbidden_chars;
+               len = G_N_ELEMENTS (user_name_forbidden_chars);
+               break;
+       default:
+               g_return_val_if_reached (TRUE);
+       }
+
+       for (i = 0; i < len ; i++)
+               if (forbidden_chars[i] == character)
+                       return TRUE;
+
+       return FALSE; /* it's valid! */
+}