diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-08-11 15:06:20 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-08-11 15:06:20 +0100 |
commit | 5ed1a8aec4040116f1bc823b671ffdac0ecc3ae5 (patch) | |
tree | 65d7fdf66249030aad3bda8d4045f453104bddc1 /src/libutil | |
parent | 84eb4e2058760559f739af68690d4ff452401e22 (diff) | |
download | rspamd-5ed1a8aec4040116f1bc823b671ffdac0ecc3ae5.tar.gz rspamd-5ed1a8aec4040116f1bc823b671ffdac0ecc3ae5.zip |
Move and refactor url decoding routine.
Diffstat (limited to 'src/libutil')
-rw-r--r-- | src/libutil/str_util.c | 88 | ||||
-rw-r--r-- | src/libutil/str_util.h | 9 |
2 files changed, 97 insertions, 0 deletions
diff --git a/src/libutil/str_util.c b/src/libutil/str_util.c index 58105be36..780339e37 100644 --- a/src/libutil/str_util.c +++ b/src/libutil/str_util.c @@ -707,3 +707,91 @@ end: 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); +} diff --git a/src/libutil/str_util.h b/src/libutil/str_util.h index a9c920c31..986fc7f03 100644 --- a/src/libutil/str_util.h +++ b/src/libutil/str_util.h @@ -128,6 +128,15 @@ guchar* rspamd_decode_base32 (const gchar *in, gsize inlen, gsize *outlen); gchar * rspamd_encode_base64 (const guchar *in, gsize inlen, gint str_len, gsize *outlen); +/** + * Decode URL encoded string in-place and return new length of a string, src and dst are NULL terminated + * @param dst + * @param src + * @param size + * @return + */ +gsize rspamd_decode_url (gchar *dst, const gchar *src, gsize size); + #ifndef g_tolower # define g_tolower(x) (((x) >= 'A' && (x) <= 'Z') ? (x) - 'A' + 'a' : (x)) #endif |