From 1604c0967129b4b348f3c6150f5a2c87f780e404 Mon Sep 17 00:00:00 2001 From: Fredrik Tolf Date: Sat, 28 Aug 2010 07:02:59 +0200 Subject: [PATCH] Unquote URL escapes in dirplex elements. --- lib/req.c | 34 ++++++++++++++++++++++++++++++++++ lib/req.h | 1 + src/dirplex.c | 6 ++++++ 3 files changed, 41 insertions(+) diff --git a/lib/req.c b/lib/req.c index 8ea2fbc..4cde483 100644 --- a/lib/req.c +++ b/lib/req.c @@ -268,3 +268,37 @@ fail: errno = EPROTO; return(-1); } + +char *unquoteurl(char *in) +{ + struct charbuf buf; + char *p; + int c; + + bufinit(buf); + p = in; + while(*p) { + if(*p == '%') { + if(!p[1] || !p[2]) + goto fail; + c = 0; + if((p[1] >= '0') && (p[1] <= '9')) c |= (p[1] - '0') << 4; + else if((p[1] >= 'a') && (p[1] <= 'f')) c |= (p[1] - 'a' + 10) << 4; + else if((p[1] >= 'A') && (p[1] <= 'F')) c |= (p[1] - 'A' + 10) << 4; + else goto fail; + if((p[2] >= '0') && (p[2] <= '9')) c |= (p[2] - '0'); + else if((p[2] >= 'a') && (p[2] <= 'f')) c |= (p[2] - 'a' + 10); + else if((p[2] >= 'A') && (p[2] <= 'F')) c |= (p[2] - 'A' + 10); + else goto fail; + bufadd(buf, c); + p += 3; + } else { + bufadd(buf, *(p++)); + } + } + bufadd(buf, 0); + return(buf.b); +fail: + buffree(buf); + return(NULL); +} diff --git a/lib/req.h b/lib/req.h index 9d77499..a5e50ba 100644 --- a/lib/req.h +++ b/lib/req.h @@ -22,5 +22,6 @@ int recvreq(int sock, struct hthead **reqp); void replrest(struct hthead *head, char *rest); int parseheaders(struct hthead *head, FILE *in); int writeresp(FILE *out, struct hthead *resp); +char *unquoteurl(char *in); #endif diff --git a/src/dirplex.c b/src/dirplex.c index 402d654..52313cc 100644 --- a/src/dirplex.c +++ b/src/dirplex.c @@ -494,6 +494,12 @@ static void serve(struct hthead *req, int fd) } else { *(p2++) = 0; } + if((tmp = unquoteurl(p)) == NULL) { + simpleerror(fd, 400, "Bad Request", "The requested URL contains an invalid escape sequence."); + goto fail; + } + strcpy(p, tmp); + free(tmp); if(!*p) { if(p2 == NULL) { -- 2.11.0