From: Vsevolod Stakhov Date: Sat, 28 Nov 2015 13:46:42 +0000 (+0000) Subject: Start to fix url decoding shifting X-Git-Tag: 1.1.0~452 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=de9a56dfb1ebd0fa05216e5ef566393c4bc40b9c;p=rspamd.git Start to fix url decoding shifting --- diff --git a/src/libserver/url.c b/src/libserver/url.c index 7d9b7a9eb..b612bb193 100644 --- a/src/libserver/url.c +++ b/src/libserver/url.c @@ -1195,6 +1195,117 @@ rspamd_url_is_ip (struct rspamd_url *uri, rspamd_mempool_t *pool) return ret; } +static void +rspamd_url_shift (struct rspamd_url *uri, gsize nlen, + enum http_parser_url_fields field) +{ + guint old_shift, shift = 0; + + /* Shift remaining data */ + switch (field) { + case UF_SCHEMA: + if (nlen >= uri->protocollen) { + return; + } + else { + shift = uri->protocollen - nlen; + } + + old_shift = uri->protocollen; + uri->protocollen -= shift; + memmove (uri->string + uri->protocollen, uri->string + old_shift, + uri->urllen - uri->protocollen); + break; + case UF_HOST: + if (nlen >= uri->hostlen) { + return; + } + else { + shift = uri->hostlen - nlen; + } + + old_shift = uri->hostlen; + uri->hostlen -= shift; + memmove (uri->host + uri->hostlen, uri->host + old_shift, + uri->datalen + uri->querylen + uri->fragmentlen); + break; + case UF_PATH: + if (nlen >= uri->datalen) { + return; + } + else { + shift = uri->datalen - nlen; + } + + old_shift = uri->datalen; + uri->datalen -= shift; + memmove (uri->data + uri->datalen, uri->data + old_shift, + uri->querylen + uri->fragmentlen); + break; + case UF_QUERY: + if (nlen >= uri->querylen) { + return; + } + else { + shift = uri->querylen - nlen; + } + + old_shift = uri->querylen; + uri->querylen -= shift; + memmove (uri->query + uri->querylen, uri->query + old_shift, + uri->fragmentlen); + break; + case UF_FRAGMENT: + if (nlen >= uri->fragmentlen) { + return; + } + else { + shift = uri->fragmentlen - nlen; + } + + uri->fragmentlen -= shift; + break; + default: + break; + } + + /* Now adjust lengths and offsets */ + switch (field) { + case UF_SCHEMA: + if (uri->userlen > 0) { + uri->user -= shift; + uri->userlen -= shift; + } + if (uri->hostlen > 0) { + uri->host -= shift; + uri->hostlen -= shift; + } + /* Go forward */ + case UF_HOST: + if (uri->datalen > 0) { + uri->data -= shift; + uri->datalen -= shift; + } + /* Go forward */ + case UF_PATH: + if (uri->querylen > 0) { + uri->query -= shift; + uri->querylen -= shift; + } + /* Go forward */ + case UF_QUERY: + if (uri->fragmentlen > 0) { + uri->fragment -= shift; + uri->fragmentlen -= shift; + } + /* Go forward */ + case UF_FRAGMENT: + default: + uri->urllen -= shift; + break; + } +} + enum uri_errno rspamd_url_parse (struct rspamd_url *uri, gchar *uristring, gsize len, rspamd_mempool_t *pool) @@ -1203,6 +1314,7 @@ rspamd_url_parse (struct rspamd_url *uri, gchar *uristring, gsize len, gchar *p, *comp; const gchar *end; guint i, complen, ret; + gsize unquoted_len = 0; gint state = 0; const struct { @@ -1319,22 +1431,28 @@ rspamd_url_parse (struct rspamd_url *uri, gchar *uristring, gsize len, uri->string = p; uri->urllen = len; - if (uri->userlen == 0) { - rspamd_decode_url (uri->string, uri->string, len); - } - else { - rspamd_decode_url (uri->string, uri->string, uri->protocollen); - rspamd_decode_url (uri->host, uri->host, uri->hostlen); - - if (uri->datalen) { - rspamd_decode_url (uri->data, uri->data, uri->datalen); - } - if (uri->querylen) { - rspamd_decode_url (uri->query, uri->query, uri->querylen); - } - if (uri->fragmentlen) { - rspamd_decode_url (uri->fragment, uri->fragment, uri->fragmentlen); - } + unquoted_len = rspamd_decode_url (uri->string, + uri->string, + uri->protocollen); + rspamd_url_shift (uri, unquoted_len, UF_SCHEMA); + unquoted_len = rspamd_decode_url (uri->host, uri->host, uri->hostlen); + rspamd_url_shift (uri, unquoted_len, UF_HOST); + + if (uri->datalen) { + unquoted_len = rspamd_decode_url (uri->data, uri->data, uri->datalen); + rspamd_url_shift (uri, unquoted_len, UF_PATH); + } + if (uri->querylen) { + unquoted_len = rspamd_decode_url (uri->query, + uri->query, + uri->querylen); + rspamd_url_shift (uri, unquoted_len, UF_QUERY); + } + if (uri->fragmentlen) { + unquoted_len = rspamd_decode_url (uri->fragment, + uri->fragment, + uri->fragmentlen); + rspamd_url_shift (uri, unquoted_len, UF_FRAGMENT); } rspamd_str_lc (uri->string, uri->protocollen); diff --git a/src/libserver/url.h b/src/libserver/url.h index 90b6d5c61..26e994e44 100644 --- a/src/libserver/url.h +++ b/src/libserver/url.h @@ -20,7 +20,6 @@ struct rspamd_url { guint port; gchar *user; - gchar *password; gchar *host; gchar *data; gchar *query; @@ -32,7 +31,6 @@ struct rspamd_url { guint protocollen; guint userlen; - guint passwordlen; guint hostlen; guint datalen; guint querylen; diff --git a/src/libutil/str_util.c b/src/libutil/str_util.c index c4b0ea173..64e02955e 100644 --- a/src/libutil/str_util.c +++ b/src/libutil/str_util.c @@ -856,8 +856,6 @@ rspamd_decode_url (gchar *dst, const gchar *src, gsize size) } } - *d = '\0'; - return (d - dst); } #define MIN3(a, b, c) ((a) < (b) ? ((a) < (c) ? (a) : (c)) : ((b) < (c) ? (b) : (c)))