aboutsummaryrefslogtreecommitdiffstats
path: root/src/libmime/email_addr.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2019-01-17 14:57:40 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2019-01-17 14:57:40 +0000
commit5b577d4da98d9790ae6b055e1368e63c68a62349 (patch)
tree9c00ba60d86510f88ce6bb2b52d8c9082873037c /src/libmime/email_addr.c
parent9cd6c30cd0fb6c8c1189d1cddeb1d52d4e687251 (diff)
downloadrspamd-5b577d4da98d9790ae6b055e1368e63c68a62349.tar.gz
rspamd-5b577d4da98d9790ae6b055e1368e63c68a62349.zip
[Fix] Core: Fix emails comments parsing and other issues
Diffstat (limited to 'src/libmime/email_addr.c')
-rw-r--r--src/libmime/email_addr.c143
1 files changed, 77 insertions, 66 deletions
diff --git a/src/libmime/email_addr.c b/src/libmime/email_addr.c
index 9aa2d0618..b8d4b04f9 100644
--- a/src/libmime/email_addr.c
+++ b/src/libmime/email_addr.c
@@ -137,6 +137,7 @@ rspamd_email_address_add (rspamd_mempool_t *pool,
}
if (name->len > 0) {
+ rspamd_gstring_strip (name, " \t\v");
elt->name = rspamd_mime_header_decode (pool, name->str, name->len, NULL);
}
@@ -233,13 +234,12 @@ rspamd_email_address_from_mime (rspamd_mempool_t *pool,
gboolean seen_at = FALSE;
const gchar *p = hdr, *end = hdr + len, *c = hdr, *t;
- GString *ns;
+ GString *ns, *cpy;
gint obraces, ebraces;
enum {
parse_name = 0,
parse_quoted,
parse_addr,
- skip_comment,
skip_spaces
} state = parse_name, next_state = parse_name;
@@ -249,7 +249,70 @@ rspamd_email_address_from_mime (rspamd_mempool_t *pool,
res);
}
- ns = g_string_sized_new (127);
+ ns = g_string_sized_new (len);
+ cpy = g_string_sized_new (len);
+
+ rspamd_mempool_add_destructor (pool, rspamd_gstring_free_hard, cpy);
+
+ /* First, we need to remove all comments as they are terrible */
+ obraces = 0;
+ ebraces = 0;
+
+ while (p < end) {
+ if (state == parse_name) {
+ if (*p == '\\') {
+ if (obraces == 0) {
+ g_string_append_c (cpy, *p);
+ }
+
+ p++;
+ }
+ else {
+ if (*p == '"') {
+ state = parse_quoted;
+ }
+ else if (*p == '(') {
+ obraces ++;
+ }
+ else if (*p == ')') {
+ ebraces ++;
+ }
+
+ if (obraces == ebraces) {
+ obraces = 0;
+ ebraces = 0;
+ }
+ }
+
+ if (p < end && obraces == 0) {
+ g_string_append_c (cpy, *p);
+ }
+ }
+ else {
+ /* Quoted elt */
+ if (*p == '\\') {
+ g_string_append_c (cpy, *p);
+ p++;
+ }
+ else {
+ if (*p == '"') {
+ state = parse_name;
+ }
+ }
+
+ if (p < end) {
+ g_string_append_c (cpy, *p);
+ }
+ }
+
+ p++;
+ }
+
+ state = parse_name;
+
+ p = cpy->str;
+ c = p;
+ end = p + cpy->len;
while (p < end) {
switch (state) {
@@ -257,13 +320,20 @@ rspamd_email_address_from_mime (rspamd_mempool_t *pool,
if (*p == '"') {
/* We need to strip last spaces and update `ns` */
if (p > c) {
+ guint nspaces = 0;
+
t = p - 1;
while (t > c && g_ascii_isspace (*t)) {
t --;
+ nspaces ++;
}
g_string_append_len (ns, c, t - c + 1);
+
+ if (nspaces > 0) {
+ g_string_append_c (ns, ' ');
+ }
}
state = parse_quoted;
@@ -311,33 +381,7 @@ rspamd_email_address_from_mime (rspamd_mempool_t *pool,
else if (*p == '@') {
seen_at = TRUE;
}
- else if (*p == '(') {
- if (p > c) {
- t = p - 1;
-
- while (t > c && g_ascii_isspace (*t)) {
- t --;
- }
- g_string_append_len (ns, c, t - c + 1);
-
- if (seen_at) {
- if (!rspamd_email_address_check_and_add (c, t - c + 1,
- res, pool, ns)) {
- rspamd_email_address_add (pool, res, NULL, ns);
- }
-
- g_string_set_size (ns, 0);
- seen_at = FALSE;
- }
- }
-
- c = p;
- obraces = 1;
- ebraces = 0;
- state = skip_comment;
- next_state = parse_name;
- }
p ++;
break;
case parse_quoted:
@@ -346,6 +390,10 @@ rspamd_email_address_from_mime (rspamd_mempool_t *pool,
g_string_append_len (ns, c, p - c);
}
+ if (p + 1 < end && g_ascii_isspace (p[1])) {
+ g_string_append_c (ns, ' ');
+ }
+
state = skip_spaces;
next_state = parse_name;
}
@@ -367,12 +415,6 @@ rspamd_email_address_from_mime (rspamd_mempool_t *pool,
else if (*p == '@') {
seen_at = TRUE;
}
- else if (*p == '(') {
- obraces = 1;
- ebraces = 0;
- state = skip_comment;
- next_state = parse_addr;
- }
p ++;
break;
case skip_spaces:
@@ -384,36 +426,6 @@ rspamd_email_address_from_mime (rspamd_mempool_t *pool,
p ++;
}
break;
- case skip_comment:
- if (*p == '(') {
- obraces ++;
- }
- else if (*p == ')') {
- ebraces ++;
- }
-
- if (obraces == ebraces) {
- if (next_state == parse_name) {
- if (ns->len > 0) {
- /* Include comment in name if it has been seen */
- if (p > c) {
- t = p - 1;
-
- while (t > c && g_ascii_isspace (*t)) {
- t --;
- }
-
- g_string_append_len (ns, c, t - c + 1);
- }
- }
-
- c = p + 1;
- }
-
- state = next_state;
- }
- p ++;
- break;
}
}
@@ -460,7 +472,6 @@ rspamd_email_address_from_mime (rspamd_mempool_t *pool,
}
break;
case parse_quoted:
- case skip_comment:
/* Unfinished quoted string or a comment */
break;
default: