From 53a30785852eaf7ecd9d8c2ff997f09f42628e3c Mon Sep 17 00:00:00 2001 From: cel Date: Sun, 31 May 2020 13:25:19 -0400 Subject: [PATCH] Unescape query --- sundown/houdini_uri_u.c | 58 +++++++++++++++++++++++++++++++++++++++++ zet.dpi.c | 15 ++++++++++- 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 sundown/houdini_uri_u.c diff --git a/sundown/houdini_uri_u.c b/sundown/houdini_uri_u.c new file mode 100644 index 0000000..bae2aa1 --- /dev/null +++ b/sundown/houdini_uri_u.c @@ -0,0 +1,58 @@ +#include +#include +#include + +#include "houdini.h" + +#define UNESCAPE_GROW_FACTOR(x) (x) +#define hex2c(c) ((c | 32) % 39 - 9) + +static void +unescape(struct buf *ob, const uint8_t *src, size_t size, int is_url) +{ + size_t i = 0, org; + + bufgrow(ob, UNESCAPE_GROW_FACTOR(size)); + + while (i < size) { + org = i; + while (i < size && src[i] != '%') + i++; + + if (i > org) + bufput(ob, src + org, i - org); + + /* escaping */ + if (i >= size) + break; + + i++; + + if (i + 1 < size && _isxdigit(src[i]) && _isxdigit(src[i + 1])) { + unsigned char new_char = (hex2c(src[i]) << 4) + hex2c(src[i + 1]); + bufputc(ob, new_char); + i += 2; + } else { + bufputc(ob, '%'); + } + } + + if (is_url) { + char *find = (char *)bufcstr(ob); + while ((find = strchr(find, '+')) != NULL) + *find = ' '; + } +} + +void +houdini_unescape_uri(struct buf *ob, const uint8_t *src, size_t size) +{ + return unescape(ob, src, size, 0); +} + +void +houdini_unescape_url(struct buf *ob, const uint8_t *src, size_t size) +{ + return unescape(ob, src, size, 1); +} + diff --git a/zet.dpi.c b/zet.dpi.c index c548941..5ac25dd 100644 --- a/zet.dpi.c +++ b/zet.dpi.c @@ -358,11 +358,20 @@ static int dpi_serve_zet_index(int fd) { return 0; } +static void unescape(char *buf, size_t len, const char *str) { + struct buf *ob = bufnew(1024); + houdini_unescape_url(ob, str, strlen(str)); + if (ob->size < len) len = ob->size; + strncpy(buf, ob->data, len); + buf[len] = '\0'; + bufrelease(ob); +} + static int dpi_serve_zet_search(int fd, char *qs) { int rc; struct zet_search zs; - char *query = NULL; + char *query = NULL, query_unescaped[1024]; char *name = qs, *next_name; while (name != NULL) { char *value = strchr(name, '='); @@ -374,6 +383,10 @@ static int dpi_serve_zet_search(int fd, char *qs) { name = next_name; } + if (query != NULL) { + unescape(query_unescaped, sizeof(query_unescaped), query); + query = query_unescaped; + } rc = zet_search_start(&zs, NULL, query); if (rc < 0) return dpi_respond_err(fd, "Unable to list");