From dc6ba44ea66c471305908a8053d7de56d705e499 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Sat, 28 Oct 2017 00:03:18 +0200 Subject: [SERVER] Add function to parse x-www-form-urlencoded strings Use it to properly parse RPC queries. Will also come in handy when parsing POST body for calls that actually trigger any actions in the server (reload, alt-servers, ...) --- src/server/urldecode.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 src/server/urldecode.c (limited to 'src/server/urldecode.c') diff --git a/src/server/urldecode.c b/src/server/urldecode.c new file mode 100644 index 0000000..4553097 --- /dev/null +++ b/src/server/urldecode.c @@ -0,0 +1,61 @@ +#include "urldecode.h" +#include +#include + +#define hex2int(a) do { \ + if ( a >= 'a' ) { \ + a = (char)(a - ( 'a' - 'A' - 10 )); \ + } else if ( a > 'F' ) { \ + goto normie; \ + } else if ( a >= 'A' ) { \ + a = (char)(a - ( 'A' - 10 )); \ + } else if ( a < '0' || a > '9' ) { \ + goto normie; \ + } else { \ + a = (char)(a - '0'); \ + } \ +} while (0) + +void urldecode(struct string* str, struct field *out, size_t *out_num) +{ + char *src = (char*)str->s; + char *dst = src; + const char * const end = str->s + str->l; + char a, b; + size_t max_out = *out_num; + *out_num = 0; + do { + if ( *out_num == max_out ) return; + out->name.s = dst; + while ( src < end && *src != '=' ) { + *dst++ = *src++; + } + if ( src == end ) return; + out->name.l = (size_t)( dst - out->name.s ); + ++src; + out->value.s = ++dst; + while ( src < end && *src != '&' ) { + if ( *src == '%' && src + 2 < end ) { + if ( src[1] > 'f' || src[2] > 'f' ) goto normie; + a = src[1]; + hex2int(a); + b = src[2]; + hex2int(b); + *dst++ = (char)( (16 * a) + b ); + src += 3; + } else if (*src == '+') { + *dst++ = (char)' '; + ++src; + } else { + normie:; + *dst++ = *src++; + } + } + out->value.l = (size_t)( dst - out->value.s ); + out++; + (*out_num)++; + if ( src++ >= end ) return; + ++dst; + } while ( 1 ); +} + -- cgit v1.2.3-55-g7522