From 4b90b875c669cffd9e14751cd5c6c0502b419e8a Mon Sep 17 00:00:00 2001 From: Emil Mikulic Date: Wed, 13 Dec 2006 08:30:21 +0000 Subject: [PATCH] Adapt make_safe_uri() to work in-place. We're currently failing some tests. --- trunk/darkhttpd.c | 111 ++++++++++++++++++++++------------------------ 1 file changed, 52 insertions(+), 59 deletions(-) diff --git a/trunk/darkhttpd.c b/trunk/darkhttpd.c index 8913f7e..a97a73c 100644 --- a/trunk/darkhttpd.c +++ b/trunk/darkhttpd.c @@ -520,31 +520,38 @@ static void consolidate_slashes(char *s) /* --------------------------------------------------------------------------- - * Resolve /./ and /../ in a URI, returning a new, safe URI, or NULL if the - * URI is invalid/unsafe. Returned buffer needs to be deallocated. + * Resolve /./ and /../ in a URI, in-place. Returns NULL if the URI is + * invalid/unsafe, or the original buffer if successful. */ static char *make_safe_uri(char *uri) { - char **elem, *out; - unsigned int slashes = 0, elements = 0; + struct { + char *start; + size_t len; + } *chunks; + unsigned int num_slashes, num_chunks; size_t urilen, i, j, pos; + int ends_in_slash; assert(uri != NULL); if (uri[0] != '/') return NULL; consolidate_slashes(uri); urilen = strlen(uri); + if (urilen > 0) + ends_in_slash = (uri[urilen-1] == '/'); + else + ends_in_slash = 1; /* count the slashes */ - for (i=0, slashes=0; iuri); /* make sure it's safe */ - safe_url = make_safe_uri(decoded_url); - free(decoded_url); - if (safe_url == NULL) - { + if (make_safe_uri(decoded_url) == NULL) { default_reply(conn, 400, "Bad Request", "You requested an invalid URI: %s", conn->uri); return; } /* does it end in a slash? serve up url/index_name */ - if (safe_url[strlen(safe_url)-1] == '/') + if (decoded_url[strlen(decoded_url)-1] == '/') { - xasprintf(&target, "%s%s%s", wwwroot, safe_url, index_name); + xasprintf(&target, "%s%s%s", wwwroot, decoded_url, index_name); if (!file_exists(target)) { free(target); - xasprintf(&target, "%s%s", wwwroot, safe_url); + xasprintf(&target, "%s%s", wwwroot, decoded_url); generate_dir_listing(conn, target); free(target); - free(safe_url); + free(decoded_url); return; } mimetype = uri_content_type(index_name); } else /* points to a file */ { - xasprintf(&target, "%s%s", wwwroot, safe_url); - mimetype = uri_content_type(safe_url); + xasprintf(&target, "%s%s", wwwroot, decoded_url); + mimetype = uri_content_type(decoded_url); } - free(safe_url); + free(decoded_url); if (debug) printf("uri=%s, target=%s, content-type=%s\n", conn->uri, target, mimetype); @@ -2076,7 +2069,7 @@ static void poll_send_header(struct connection *conn) /* --------------------------------------------------------------------------- * Send chunk on socket from FILE *fp, starting at and of size - * . Use sendfile() is possible since it's zero-copy on some platforms. + * . Use sendfile() if possible since it's zero-copy on some platforms. * Returns the number of bytes sent, 0 on closure, -1 if send() failed, -2 if * read error. */