aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libserver/url.c150
-rw-r--r--src/libserver/url.h2
-rw-r--r--src/libutil/str_util.c2
3 files changed, 134 insertions, 20 deletions
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)))