Browse Source

Allow url parser seting the end of url.

tags/0.9.0
Vsevolod Stakhov 9 years ago
parent
commit
a87a4f475c
1 changed files with 42 additions and 33 deletions
  1. 42
    33
      src/libserver/url.c

+ 42
- 33
src/libserver/url.c View File

} }


static gint static gint
rspamd_mailto_parse (struct http_parser_url *u, const gchar *str)
rspamd_mailto_parse (struct http_parser_url *u, const gchar *str,
gchar const **end)
{ {
const gchar *p = str, *c = str; const gchar *p = str, *c = str;
gchar t; gchar t;
gint ret = 1;
enum { enum {
parse_mailto, parse_mailto,
parse_slash, parse_slash,
st = parse_slash_slash; st = parse_slash_slash;
} }
else { else {
return 1;
goto out;
} }
p ++; p ++;
break; break;
st = parse_destination; st = parse_destination;
} }
else { else {
return 1;
goto out;
} }
break; break;
case parse_destination: case parse_destination:
case parse_user: case parse_user:
if (t == '@') { if (t == '@') {
if (p - c == 0) { if (p - c == 0) {
return 1;
goto out;
} }
u->field_set |= 1 << UF_USERINFO; u->field_set |= 1 << UF_USERINFO;
u->field_data[UF_USERINFO].len = p - c; u->field_data[UF_USERINFO].len = p - c;
st = parse_at; st = parse_at;
} }
else if (!is_atom (t)) { else if (!is_atom (t)) {
return 1;
goto out;
} }
p ++; p ++;
break; break;
st = parse_suffix_question; st = parse_suffix_question;
} }
else if (!is_domain (t) && t != '.' && t != '_') { else if (!is_domain (t) && t != '.' && t != '_') {
return 1;
goto out;
} }
p ++; p ++;
break; break;
break; break;
case parse_query: case parse_query:
if (!is_atom (t)) { if (!is_atom (t)) {
return 1;
goto out;
} }
p ++; p ++;
break; break;
} }


if (st == parse_domain) { if (st == parse_domain) {
if (p - c == 0) {
return 1;
}

u->field_set |= 1 << UF_HOST;
u->field_data[UF_HOST].len = p - c;
u->field_data[UF_HOST].off = c - str;
if (p - c != 0) {
u->field_set |= 1 << UF_HOST;
u->field_data[UF_HOST].len = p - c;
u->field_data[UF_HOST].off = c - str;


return 0;
ret = 0;
}
} }
else if (st == parse_query) { else if (st == parse_query) {
if (p - c > 0) { if (p - c > 0) {
u->field_data[UF_QUERY].off = c - str; u->field_data[UF_QUERY].off = c - str;
} }


return 0;
ret = 0;
}

out:
if (end != NULL) {
*end = p;
} }


return 1;
return ret;
} }


static gint static gint
rspamd_web_parse (struct http_parser_url *u, const gchar *str)
rspamd_web_parse (struct http_parser_url *u, const gchar *str, gchar const **end)
{ {
const gchar *p = str, *c = str; const gchar *p = str, *c = str;
gchar t; gchar t;
st = parse_slash_slash; st = parse_slash_slash;
} }
else { else {
return 1;
goto out;
} }
p ++; p ++;
break; break;
case parse_user: case parse_user:
if (t == ':') { if (t == ':') {
if (p - c == 0) { if (p - c == 0) {
return 1;
goto out;
} }
u->field_set |= 1 << UF_USERINFO; u->field_set |= 1 << UF_USERINFO;
u->field_data[UF_USERINFO].len = p - c; u->field_data[UF_USERINFO].len = p - c;
else if (t == '@') { else if (t == '@') {
/* No password */ /* No password */
if (p - c == 0) { if (p - c == 0) {
return 1;
goto out;
} }
u->field_set |= 1 << UF_USERINFO; u->field_set |= 1 << UF_USERINFO;
u->field_data[UF_USERINFO].len = p - c; u->field_data[UF_USERINFO].len = p - c;
st = parse_at; st = parse_at;
} }
else if (!is_atom (t)) { else if (!is_atom (t)) {
return 1;
goto out;
} }
p ++; p ++;
break; break;
st = parse_at; st = parse_at;
} }
else if (!is_atom (t)) { else if (!is_atom (t)) {
return 1;
goto out;
} }
p ++; p ++;
break; break;
case parse_domain: case parse_domain:
if (t == '/' || t == ':') { if (t == '/' || t == ':') {
if (p - c == 0) { if (p - c == 0) {
return 1;
goto out;
} }
u->field_set |= 1 << UF_HOST; u->field_set |= 1 << UF_HOST;
u->field_data[UF_HOST].len = p - c; u->field_data[UF_HOST].len = p - c;


if (uc == (gunichar)-1) { if (uc == (gunichar)-1) {
/* Bad utf8 */ /* Bad utf8 */
return 1;
goto out;
} }


if (!g_unichar_isalnum (uc)) { if (!g_unichar_isalnum (uc)) {
/* Bad symbol */ /* Bad symbol */
return 1;
goto out;
} }


p = g_utf8_next_char (p); p = g_utf8_next_char (p);
if (t == '/') { if (t == '/') {
pt = strtoul (c, NULL, 10); pt = strtoul (c, NULL, 10);
if (pt == 0 || pt > 65535) { if (pt == 0 || pt > 65535) {
return 1;
goto out;
} }
u->port = pt; u->port = pt;
st = parse_suffix_slash; st = parse_suffix_slash;
} }
else if (!g_ascii_isdigit (t)) { else if (!g_ascii_isdigit (t)) {
return 1;
goto out;
} }
p ++; p ++;
break; break;
switch (st) { switch (st) {
case parse_domain: case parse_domain:
if (p - c == 0) { if (p - c == 0) {
return 1;
goto out;
} }
u->field_set |= 1 << UF_HOST; u->field_set |= 1 << UF_HOST;
u->field_data[UF_HOST].len = p - c; u->field_data[UF_HOST].len = p - c;
case parse_port: case parse_port:
pt = strtoul (c, NULL, 10); pt = strtoul (c, NULL, 10);
if (pt == 0 || pt > 65535) { if (pt == 0 || pt > 65535) {
return 1;
goto out;
} }
u->port = pt; u->port = pt;
ret = 0; ret = 0;
ret = 1; ret = 1;
break; break;
} }
out:
if (end != NULL) {
*end = p;
}


return ret; return ret;
} }
if (len > sizeof ("mailto:") - 1) { if (len > sizeof ("mailto:") - 1) {
/* For mailto: urls we also need to add slashes to make it a valid URL */ /* For mailto: urls we also need to add slashes to make it a valid URL */
if (g_ascii_strncasecmp (p, "mailto:", sizeof ("mailto:") - 1) == 0) { if (g_ascii_strncasecmp (p, "mailto:", sizeof ("mailto:") - 1) == 0) {
ret = rspamd_mailto_parse (&u, p);
ret = rspamd_mailto_parse (&u, p, NULL);
} }
else { else {
ret = rspamd_web_parse (&u, p);
ret = rspamd_web_parse (&u, p, NULL);
} }
} }
else { else {
ret = rspamd_web_parse (&u, p);
ret = rspamd_web_parse (&u, p, NULL);
} }


if (ret != 0) { if (ret != 0) {

Loading…
Cancel
Save