From b02c1bba0861e9a9222290d28c52619c07e382ab Mon Sep 17 00:00:00 2001 From: Emil Mikulic Date: Sun, 26 Oct 2008 12:45:57 +0000 Subject: [PATCH] urlencode file names when generating directory listing. Noticed by, patched by: nf --- trunk/darkhttpd.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/trunk/darkhttpd.c b/trunk/darkhttpd.c index dc9ebed..b576592 100644 --- a/trunk/darkhttpd.c +++ b/trunk/darkhttpd.c @@ -1690,7 +1690,49 @@ static void cleanup_sorted_dirlist(struct dlent **list, const ssize_t size) } } +/* --------------------------------------------------------------------------- + * Should this character be urlencoded (according to rfc1738) + */ +static int is_bad_char(unsigned char c) +{ + int i; + const static char bad[] = "<>\"%{}|^~[]`\\;:/?@#=&"; + for (i=0; i= 0x80) || (c == 0x7F)) + return 1; + + return 0; +} + +/* --------------------------------------------------------------------------- + * Encode filename to be an rfc1738-compliant URL part + */ +static void urlencode_filename(unsigned char *name, unsigned char *safe_url) +{ + const static char hex[] = "0123456789ABCDEF"; + int i, j, len; + + len = strlen(name); + + for (i=j=0; i> 4) & 0xF]; + safe_url[j++] = hex[ name[i] & 0xF]; + } + else + safe_url[j++] = name[i]; + } + + safe_url[j] = '\0'; +} /* --------------------------------------------------------------------------- * Generate directory listing. @@ -1704,6 +1746,10 @@ static void generate_dir_listing(struct connection *conn, const char *path) int i; struct apbuf *listing = make_apbuf(); + /* If a filename is made up of entirely unsafe chars, + the url would be three times its original length. */ + char safe_url[MAXNAMLEN*3]; + listsize = make_sorted_dirlist(path, &list); if (listsize == -1) { @@ -1729,8 +1775,10 @@ static void generate_dir_listing(struct connection *conn, const char *path) for (i=0; iname, safe_url); + append(listing, "name); + append(listing, safe_url); append(listing, "\">"); append(listing, list[i]->name); append(listing, "");