commit 3075162855d6428533550e29406942795dd704a0
parent ff613f4665eda3a498a23493e75d2cacad02f5c6
Author: Joris Vink <joris@coders.se>
Date:   Tue, 13 Aug 2013 14:18:47 +0200
Add http_argument_urldecode() which takes a string and decodes any url encoding done to it.
Change kore_strtonum() to pass 0 to strtoll by default so we can use it to convert hex numbers (prepended with 0x) as well.
Diffstat:
5 files changed, 62 insertions(+), 6 deletions(-)
diff --git a/includes/http.h b/includes/http.h
@@ -75,8 +75,9 @@ void		http_response_header_add(struct http_request *, char *, char *);
 int		http_request_new(struct connection *, struct spdy_stream *,
 		    char *, char *, char *, struct http_request **);
 
-int		http_generic_404(struct http_request *);
+int		http_argument_urldecode(char *);
 int		http_header_recv(struct netbuf *);
+int		http_generic_404(struct http_request *);
 char		*http_post_data_text(struct http_request *);
 int		http_populate_arguments(struct http_request *);
 void		http_argument_multiple_free(struct http_arg *);
diff --git a/includes/kore.h b/includes/kore.h
@@ -48,6 +48,8 @@
 #define KORE_PIDFILE_DEFAULT		"/var/run/kore.pid"
 #define KORE_DEFAULT_CIPHER_LIST	"HIGH:!aNULL:!MD5;"
 
+#define KORE_DEBUG		1
+
 #if defined(KORE_DEBUG)
 #define kore_debug(fmt, ...)	\
 	if (kore_debug)		\
diff --git a/src/buf.c b/src/buf.c
@@ -121,7 +121,8 @@ kore_buf_replace_string(struct kore_buf *b, const char *src,
 
 		tmp = kore_malloc(nlen);
 		memcpy(tmp, p, off);
-		memcpy((tmp + off), dst, len);
+		if (dst != NULL)
+			memcpy((tmp + off), dst, len);
 		memcpy((tmp + off + len), end, off2);
 
 		kore_mem_free(b->data);
diff --git a/src/http.c b/src/http.c
@@ -16,6 +16,8 @@
 
 #include <sys/param.h>
 
+#include <ctype.h>
+
 #include "spdy.h"
 #include "kore.h"
 #include "http.h"
@@ -486,19 +488,69 @@ http_argument_lookup(struct http_request *req, const char *name, char **out)
 }
 
 int
+http_argument_urldecode(char *arg)
+{
+	u_int8_t	v;
+	int		err;
+	size_t		len;
+	char		*p, *in, h[5];
+
+	p = arg;
+	in = arg;
+	len = strlen(arg);
+
+	while (*p != '\0' && p < (arg + len)) {
+		if (*p == '+')
+			*p = ' ';
+		if (*p != '%') {
+			*in++ = *p++;
+			continue;
+		}
+
+		if ((p + 2) >= (arg + len)) {
+			kore_debug("overflow in '%s'", arg);
+			return (KORE_RESULT_ERROR);
+		}
+
+		if (!isxdigit(*(p + 1)) || !isxdigit(*(p + 2))) {
+			*in++ = *p++;
+			continue;
+		}
+
+		h[0] = '0';
+		h[1] = 'x';
+		h[2] = *(p + 1);
+		h[3] = *(p + 2);
+		h[4] = '\0';
+
+		v = kore_strtonum(h, 32, 127, &err);
+		if (err != KORE_RESULT_OK)
+			return (err);
+
+		*in++ = (char)v;
+		p += 3;
+	}
+
+	*in = '\0';
+	return (KORE_RESULT_OK);
+}
+
+int
 http_argument_multiple_lookup(struct http_request *req, struct http_arg *args)
 {
-	int		i;
+	int		i, c;
 
+	c = 0;
 	for (i = 0; args[i].name != NULL; i++) {
 		if (!http_argument_lookup(req,
 		    args[i].name, &(args[i].value))) {
 			args[i].value = NULL;
-			return (i);
+		} else {
+			c++;
 		}
 	}
 
-	return (i);
+	return (c);
 }
 
 void
diff --git a/src/utils.c b/src/utils.c
@@ -99,7 +99,7 @@ kore_strtonum(const char *str, long long min, long long max, int *err)
 
 	l = 0;
 	errno = 0;
-	l = strtoll(str, &ep, 10);
+	l = strtoll(str, &ep, 0);
 	if (errno != 0 || str == ep || *ep != '\0') {
 		*err = KORE_RESULT_ERROR;
 		return (0);