r = rspamd_strlcpy (filepath, task->msg.start,
MIN (sizeof (filepath), task->msg.len + 1));
- rspamd_unescape_uri (filepath, filepath, r + 1);
+ rspamd_decode_url (filepath, filepath, r + 1);
flen = strlen (filepath);
if (filepath[0] == '"' && flen > 2) {
#define is_urlsafe(x) ((url_scanner_table[(guchar)(x)] & (IS_ALPHA | IS_DIGIT | \
IS_URLSAFE)) != 0)
-void
-rspamd_unescape_uri (gchar *dst, const gchar *src, gsize size)
-{
- gchar *d, ch, c, decoded;
- const gchar *s;
- enum {
- sw_usual = 0,
- sw_quoted,
- sw_quoted_second
- } state;
-
- d = dst;
- s = src;
-
- state = 0;
- decoded = 0;
-
- while (size--) {
-
- ch = *s++;
-
- switch (state) {
- case sw_usual:
-
- if (ch == '%') {
- state = sw_quoted;
- break;
- }
- else if (ch == '+') {
- *d++ = ' ';
- }
- else {
- *d++ = ch;
- }
- break;
-
- case sw_quoted:
-
- if (ch >= '0' && ch <= '9') {
- decoded = (ch - '0');
- state = sw_quoted_second;
- break;
- }
-
- c = (ch | 0x20);
- if (c >= 'a' && c <= 'f') {
- decoded = (c - 'a' + 10);
- state = sw_quoted_second;
- break;
- }
-
- /* the invalid quoted character */
-
- state = sw_usual;
-
- *d++ = ch;
-
- break;
-
- case sw_quoted_second:
-
- state = sw_usual;
-
- if (ch >= '0' && ch <= '9') {
- ch = ((decoded << 4) + ch - '0');
- *d++ = ch;
-
- break;
- }
-
- c = (u_char) (ch | 0x20);
- if (c >= 'a' && c <= 'f') {
- ch = ((decoded << 4) + c - 'a' + 10);
-
- *d++ = ch;
- break;
- }
-
- /* the invalid quoted character */
- break;
- }
- }
-
- *d = '\0';
-}
-
const gchar *
rspamd_url_strerror (enum uri_errno err)
{
uri->urllen = len;
if (uri->userlen == 0) {
- rspamd_unescape_uri (uri->string, uri->string, len);
+ rspamd_decode_url (uri->string, uri->string, len);
}
else {
- rspamd_unescape_uri (uri->string, uri->string, uri->protocollen);
- rspamd_unescape_uri (uri->host, uri->host, uri->hostlen);
+ rspamd_decode_url (uri->string, uri->string, uri->protocollen);
+ rspamd_decode_url (uri->host, uri->host, uri->hostlen);
if (uri->datalen) {
- rspamd_unescape_uri (uri->data, uri->data, uri->datalen);
+ rspamd_decode_url (uri->data, uri->data, uri->datalen);
}
if (uri->querylen) {
- rspamd_unescape_uri (uri->query, uri->query, uri->querylen);
+ rspamd_decode_url (uri->query, uri->query, uri->querylen);
}
if (uri->fragmentlen) {
- rspamd_unescape_uri (uri->fragment, uri->fragment, uri->fragmentlen);
+ rspamd_decode_url (uri->fragment, uri->fragment, uri->fragmentlen);
}
}
return out;
}
+
+gsize
+rspamd_decode_url (gchar *dst, const gchar *src, gsize size)
+{
+ gchar *d, ch, c, decoded;
+ const gchar *s;
+ enum {
+ sw_usual = 0,
+ sw_quoted,
+ sw_quoted_second
+ } state;
+
+ d = dst;
+ s = src;
+
+ state = 0;
+ decoded = 0;
+
+ while (size--) {
+
+ ch = *s++;
+
+ switch (state) {
+ case sw_usual:
+
+ if (ch == '%') {
+ state = sw_quoted;
+ break;
+ }
+ else if (ch == '+') {
+ *d++ = ' ';
+ }
+ else {
+ *d++ = ch;
+ }
+ break;
+
+ case sw_quoted:
+
+ if (ch >= '0' && ch <= '9') {
+ decoded = (ch - '0');
+ state = sw_quoted_second;
+ break;
+ }
+
+ c = (ch | 0x20);
+ if (c >= 'a' && c <= 'f') {
+ decoded = (c - 'a' + 10);
+ state = sw_quoted_second;
+ break;
+ }
+
+ /* the invalid quoted character */
+
+ state = sw_usual;
+
+ *d++ = ch;
+
+ break;
+
+ case sw_quoted_second:
+
+ state = sw_usual;
+
+ if (ch >= '0' && ch <= '9') {
+ ch = ((decoded << 4) + ch - '0');
+ *d++ = ch;
+
+ break;
+ }
+
+ c = (u_char) (ch | 0x20);
+ if (c >= 'a' && c <= 'f') {
+ ch = ((decoded << 4) + c - 'a' + 10);
+
+ *d++ = ch;
+ break;
+ }
+
+ /* the invalid quoted character */
+ break;
+ }
+ }
+
+ *d = '\0';
+
+ return (d - dst);
+}