aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2015-02-18 10:28:24 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2015-02-18 10:28:24 +0000
commit8e04a2a8db85cab3738128fd0c7ba39df5ca24b9 (patch)
treeb0aab360250dd0a7c604fd327b9391fdf5e8a066
parent7c7b34864cb4c530385c0e7c9e4505b96a44456e (diff)
downloadrspamd-8e04a2a8db85cab3738128fd0c7ba39df5ca24b9.tar.gz
rspamd-8e04a2a8db85cab3738128fd0c7ba39df5ca24b9.zip
Improve emails parsing (mentioned at #181).
-rw-r--r--src/libserver/url.c63
1 files changed, 58 insertions, 5 deletions
diff --git a/src/libserver/url.c b/src/libserver/url.c
index 7748f8a46..d3a255a07 100644
--- a/src/libserver/url.c
+++ b/src/libserver/url.c
@@ -812,9 +812,14 @@ rspamd_mailto_parse (struct http_parser_url *u, const gchar *str)
parse_slash,
parse_slash_slash,
parse_semicolon,
+ parse_prefix_question,
+ parse_destination,
+ parse_equal,
parse_user,
parse_at,
- parse_domain
+ parse_domain,
+ parse_suffix_question,
+ parse_query
} st = parse_mailto;
while (*p) {
@@ -833,12 +838,11 @@ rspamd_mailto_parse (struct http_parser_url *u, const gchar *str)
case parse_semicolon:
if (t == '/') {
st = parse_slash;
+ p ++;
}
else {
- st = parse_user;
- c = p;
+ st = parse_slash_slash;
}
- p ++;
break;
case parse_slash:
if (t == '/') {
@@ -850,6 +854,31 @@ rspamd_mailto_parse (struct http_parser_url *u, const gchar *str)
p ++;
break;
case parse_slash_slash:
+ if (t == '?') {
+ st = parse_prefix_question;
+ p ++;
+ }
+ else {
+ c = p;
+ st = parse_user;
+ }
+ break;
+ case parse_prefix_question:
+ if (t == 't') {
+ /* XXX: accept only to= */
+ st = parse_destination;
+ }
+ else {
+ return 1;
+ }
+ break;
+ case parse_destination:
+ if (t == '=') {
+ st = parse_equal;
+ }
+ p ++;
+ break;
+ case parse_equal:
c = p;
st = parse_user;
break;
@@ -873,7 +902,24 @@ rspamd_mailto_parse (struct http_parser_url *u, const gchar *str)
st = parse_domain;
break;
case parse_domain:
- if (!is_domain (t) && t != '.' && t != '_') {
+ if (t == '?') {
+ u->field_set |= 1 << UF_HOST;
+ u->field_data[UF_HOST].len = p - c;
+ u->field_data[UF_HOST].off = c - str;
+
+ st = parse_suffix_question;
+ }
+ else if (!is_domain (t) && t != '.' && t != '_') {
+ return 1;
+ }
+ p ++;
+ break;
+ case parse_suffix_question:
+ c = p;
+ st = parse_query;
+ break;
+ case parse_query:
+ if (!is_atom (t)) {
return 1;
}
p ++;
@@ -888,6 +934,13 @@ rspamd_mailto_parse (struct http_parser_url *u, const gchar *str)
return 0;
}
+ else if (st == parse_query) {
+ u->field_set |= 1 << UF_QUERY;
+ u->field_data[UF_QUERY].len = p - c;
+ u->field_data[UF_QUERY].off = c - str;
+
+ return 0;
+ }
return 1;
}