diff --git a/darkhttpd.c b/darkhttpd.c index f49df02..62670c3 100644 --- a/darkhttpd.c +++ b/darkhttpd.c @@ -1861,7 +1861,35 @@ static void urlencode(const char *src, char *dest) { dest[j] = '\0'; } -static void generate_dir_listing(struct connection *conn, const char *path) { +/* Escape < > & ' " into HTML entities. */ +static void append_escaped(struct apbuf *dst, const char *src) { + int pos = 0; + while (src[pos] != '\0') { + switch (src[pos]) { + case '<': + append(dst, "<"); + break; + case '>': + append(dst, ">"); + break; + case '&': + append(dst, "&"); + break; + case '\'': + append(dst, "'"); + break; + case '"': + append(dst, """); + break; + default: + appendl(dst, src+pos, 1); + } + pos++; + } +} + +static void generate_dir_listing(struct connection *conn, const char *path, + const char *decoded_url) { char date[DATE_LEN], *spaces; struct dlent **list; ssize_t listsize; @@ -1883,13 +1911,13 @@ static void generate_dir_listing(struct connection *conn, const char *path) { } listing = make_apbuf(); - append(listing, "\n
\n\n"); spaces = xmalloc(maxlen); @@ -1906,7 +1934,7 @@ static void generate_dir_listing(struct connection *conn, const char *path) { append(listing, ""); - append(listing, list[i]->name); + append_escaped(listing, list[i]->name); append(listing, ""); if (list[i]->is_dir) @@ -2012,7 +2040,7 @@ static void process_get(struct connection *conn) { return; } xasprintf(&target, "%s%s", wwwroot, decoded_url); - generate_dir_listing(conn, target); + generate_dir_listing(conn, target, decoded_url); free(target); free(decoded_url); return;