]> source.dussan.org Git - rspamd.git/commitdiff
Start to fix url decoding shifting
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 28 Nov 2015 13:46:42 +0000 (13:46 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 28 Nov 2015 13:46:42 +0000 (13:46 +0000)
src/libserver/url.c
src/libserver/url.h
src/libutil/str_util.c

index 7d9b7a9eb8cfe9706dc6b6b3f01b845371098895..b612bb1938a32de9e2e685ba2d5af623769c2324 100644 (file)
@@ -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);
index 90b6d5c61d66fba429dbbc831f5ee0ea3d680e22..26e994e448c652eff508e4c4bb35bce401363fd3 100644 (file)
@@ -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;
index c4b0ea1738257cdf398f96364f974d1ea4b180b0..64e02955e24045fa9d03da4ed5b481f789f6adf5 100644 (file)
@@ -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)))