From 2bb32b1cf946817c983ac396691c88d16162e0fa Mon Sep 17 00:00:00 2001 From: Thomas Kolb Date: Thu, 17 Jan 2013 22:23:00 +0100 Subject: [PATCH] Safer directory listing HTML generation Also reallocate memory while generating the directory list. --- dirlisting.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/dirlisting.c b/dirlisting.c index 7c16a65..32c3ec0 100644 --- a/dirlisting.c +++ b/dirlisting.c @@ -60,7 +60,7 @@ char* gen_html(const char *url, struct Entry *entries, size_t numentries) { char fullpath[PATH_MAX]; // allocate a buffer for the result string - allocated = 64 * numentries + strlen(HEADER1 HEADER2 FOOTER) + 4096; + allocated = strlen(HEADER1 HEADER2 FOOTER) + 64 * numentries + 4096; LOG(LVL_DEBUG, "initially allocating result string - size: %lu bytes", allocated * sizeof(char)); result = malloc(allocated * sizeof(char)); result[0] = '\0'; @@ -119,6 +119,21 @@ char* gen_html(const char *url, struct Entry *entries, size_t numentries) { if(!(entries[i].flags & FLG_ISDIR)) continue; + size_t entrylen = 32 + 2 * strlen(entries[i].name); + size_t resultlen = strlen(result); + + if(allocated < resultlen + entrylen) { + allocated *= 2; + LOG(LVL_DEBUG, "reallocating result string (subdirs) - new size: %lu bytes", allocated * sizeof(char)); + char *tmpresult = realloc(result, allocated * sizeof(char)); + if(!tmpresult) { + LOG(LVL_ERR, "realloc failed for result string: %s", strerror(errno)); + break; + } + + result = tmpresult; + } + if(isrootdir) { sprintf(buf, "
  • %s/
  • \n", entries[i].name, entries[i].name); @@ -137,16 +152,16 @@ char* gen_html(const char *url, struct Entry *entries, size_t numentries) { // here the listing entries are generated for(i = 0; i < numentries; i++) { - size_t entrylen = 32 + 2 * strlen(entries[i].name); - size_t resultlen = strlen(result); - // skip all directories if(entries[i].flags & FLG_ISDIR) continue; + size_t entrylen = 64 + 2 * strlen(entries[i].name); + size_t resultlen = strlen(result); + if(allocated < resultlen + entrylen) { allocated *= 2; - LOG(LVL_DEBUG, "reallocating result string - new size: %lu bytes", allocated * sizeof(char)); + LOG(LVL_DEBUG, "reallocating result string (files) - new size: %lu bytes", allocated * sizeof(char)); char *tmpresult = realloc(result, allocated * sizeof(char)); if(!tmpresult) { LOG(LVL_ERR, "realloc failed for result string: %s", strerror(errno));