summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2018-11-16 13:33:38 +0100
committerMilan Crha <mcrha@redhat.com>2018-11-16 13:34:33 +0100
commitc4ffe29820b39c83a4a53e97fc7b3545346ed53c (patch)
tree1a9a637f146c04dbfed484303750f2a2076a3d63
parent991f62cc2624b1e137fa3dbe5fb551c4daa60d88 (diff)
downloadevolution-data-server-c4ffe29820b39c83a4a53e97fc7b3545346ed53c.tar.gz
I#56 - [Camel] Can stop parsing mail address header too early
Closes https://gitlab.gnome.org/GNOME/evolution-data-server/issues/56
-rw-r--r--src/camel/camel-internet-address.c6
-rw-r--r--src/camel/camel-mime-utils.c76
2 files changed, 74 insertions, 8 deletions
diff --git a/src/camel/camel-internet-address.c b/src/camel/camel-internet-address.c
index 0dadb4d04..f3b8e0eb0 100644
--- a/src/camel/camel-internet-address.c
+++ b/src/camel/camel-internet-address.c
@@ -608,10 +608,10 @@ camel_internet_address_encode_address (gint *inlen,
len -= out->len;
if (name && name[0])
- g_string_append_printf (out, " <");
+ g_string_append (out, " <");
cia_encode_addrspec (out, addr);
if (name && name[0])
- g_string_append_printf (out, ">");
+ g_string_append (out, ">");
len += out->len;
@@ -648,7 +648,7 @@ camel_internet_address_format_address (const gchar *name,
gchar *o, c;
while ((c = *p++)) {
- if (c == '\"' || c == ',') {
+ if (c == ',' || c == ';' || c == '\"' || c == '<' || c == '>') {
o = ret = g_malloc (strlen (name) + 3 + strlen (addr) + 3 + 1);
p = name;
*o++ = '\"';
diff --git a/src/camel/camel-mime-utils.c b/src/camel/camel-mime-utils.c
index ff515430a..cd5513bcd 100644
--- a/src/camel/camel-mime-utils.c
+++ b/src/camel/camel-mime-utils.c
@@ -2686,12 +2686,14 @@ header_decode_mailbox (const gchar **in,
addr = g_string_new ("");
+ start:
/* for each address */
pre = header_decode_word (&inptr);
header_decode_lwsp (&inptr);
if (!(*inptr == '.' || *inptr == '@' || *inptr == ',' || *inptr == '\0')) {
/* ',' and '\0' required incase it is a simple address, no @ domain part (buggy writer) */
- name = g_string_new ("");
+ if (!name)
+ name = g_string_new ("");
while (pre) {
gchar *text, *last;
@@ -2886,8 +2888,36 @@ header_decode_mailbox (const gchar **in,
}
}
+ header_decode_lwsp (&inptr);
+
+ if (*inptr && *inptr != ',') {
+ if (addr->len > 0) {
+ if (!name) {
+ name = g_string_sized_new (addr->len + 5);
+ } else {
+ g_string_append_c (name, ' ');
+ }
+
+ g_string_append_c (name, '<');
+ g_string_append (name, addr->str);
+ g_string_append_c (name, '>');
+ g_string_append_c (name, ' ');
+
+ g_string_truncate (addr, 0);
+ }
+
+ goto start;
+ }
+
*in = inptr;
+ if (name) {
+ /* Trim any trailing spaces */
+ while (name->len > 0 && name->str[name->len - 1] == ' ') {
+ g_string_truncate (name, name->len - 1);
+ }
+ }
+
if (addr->len > 0) {
if (!g_utf8_validate (addr->str, addr->len, NULL)) {
/* workaround for invalid addr-specs containing 8bit chars (see bug #42170 for details) */
@@ -3202,11 +3232,11 @@ camel_header_address_decode (const gchar *in,
} while (inptr != last);
if (*inptr) {
- w (g_warning ("Invalid input detected at %c (%d): %s\n or at: %s", *inptr, inptr - in, in, inptr));
+ w (g_warning ("Invalid input detected at %c (%d): '%s'\n or at: '%s'", *inptr, (gint) (inptr - in), in, inptr));
}
if (inptr == last) {
- w (g_warning ("detected invalid input loop at : %s", last));
+ w (g_warning ("detected invalid input loop at : '%s' for '%s'", last, in));
}
return list;
@@ -4983,6 +5013,36 @@ camel_header_address_list_clear (CamelHeaderAddress **addrlistp)
*addrlistp = NULL;
}
+static gchar *
+maybe_quote_name (const gchar *name,
+ gboolean *out_free_result)
+{
+ if (out_free_result)
+ *out_free_result = FALSE;
+
+ if (name && *name && (strchr (name, ',') || strchr (name, ';') || strchr (name, '\"') || strchr (name, '<') || strchr (name, '>'))) {
+ GString *quoted;
+
+ if (out_free_result)
+ *out_free_result = TRUE;
+
+ quoted = g_string_sized_new (strlen (name) + 2);
+ g_string_append_c (quoted, '\"');
+
+ while (*name) {
+ if (*name != '\"')
+ g_string_append_c (quoted, *name);
+ name++;
+ }
+
+ g_string_append_c (quoted, '\"');
+
+ return g_string_free (quoted, FALSE);
+ }
+
+ return (gchar *) name;
+}
+
/* if encode is true, then the result is suitable for mailing, otherwise
* the result is suitable for display only (and may not even be re-parsable) */
static void
@@ -4993,12 +5053,14 @@ header_address_list_encode_append (GString *out,
gchar *text;
while (a) {
+ gboolean free_text = FALSE;
+
switch (a->type) {
case CAMEL_HEADER_ADDRESS_NAME:
if (encode)
text = camel_header_encode_phrase ((guchar *) a->name);
else
- text = a->name;
+ text = maybe_quote_name (a->name, &free_text);
if (text && *text)
g_string_append_printf (out, "%s <%s>", text, a->v.addr);
else
@@ -5010,7 +5072,7 @@ header_address_list_encode_append (GString *out,
if (encode)
text = camel_header_encode_phrase ((guchar *) a->name);
else
- text = a->name;
+ text = maybe_quote_name (a->name, &free_text);
g_string_append_printf (out, "%s: ", text);
header_address_list_encode_append (out, encode, a->v.members);
g_string_append_printf (out, ";");
@@ -5021,9 +5083,13 @@ header_address_list_encode_append (GString *out,
g_warning ("Invalid address type");
break;
}
+
a = a->next;
if (a)
g_string_append (out, ", ");
+
+ if (free_text)
+ g_free (text);
}
}