diff --git a/include/util.h b/include/util.h
index 13838bd..bc6ee3a 100644
--- a/include/util.h
+++ b/include/util.h
@@ -17,5 +17,6 @@
void remove_trailing_slash(char *str);
void urlencode(const char *str, char *result);
+char* safe_append(char *target, size_t *targetsize, const char *src);
#endif // UTIL_H
diff --git a/src/dirlisting.c b/src/dirlisting.c
index 62df779..82ed552 100644
--- a/src/dirlisting.c
+++ b/src/dirlisting.c
@@ -79,21 +79,20 @@ char* gen_html(const char *url, struct Entry *entries, size_t numentries, int up
result = malloc(allocated * sizeof(char));
result[0] = '\0';
- // this is still safe
- strcat(result, HEADER1);
+ result = safe_append(result, &allocated, HEADER1);
snprintf(buf, BUFSIZE, "
Directory listing for %s", url);
- strcat(result, buf);
+ result = safe_append(result, &allocated, buf);
- strcat(result, HEADER2);
+ result = safe_append(result, &allocated, HEADER2);
snprintf(buf, BUFSIZE, "Directory listing for %s
", url);
- strcat(result, buf);
+ result = safe_append(result, &allocated, buf);
int isrootdir = strcmp(url, "/") == 0;
// Begin Navigation
- strcat(result, "Navigation: ");
+ result = safe_append(result, &allocated, "
Navigation: ");
// tokenize the URL: init
char *token, *urlclone;
@@ -103,30 +102,31 @@ char* gen_html(const char *url, struct Entry *entries, size_t numentries, int up
strcpy(fullpath, "/");
if(isrootdir) {
- strcat(result, "/");
+ result = safe_append(result, &allocated, "/");
} else {
- strcat(result, "/");
+ result = safe_append(result, &allocated, "/");
// create a link for each token in URL
do {
LOG(LVL_DUMP, "Found token of %s: %s", url, token);
+ // TODO: check if this is safe
strcat(fullpath, token);
strcat(fullpath, "/");
snprintf(buf, BUFSIZE, " %s /", fullpath, token);
- strcat(result, buf);
+ result = safe_append(result, &allocated, buf);
}
while((token = strtok(NULL, "/")) != NULL);
}
free(urlclone);
- strcat(result, "
");
+ result = safe_append(result, &allocated, "");
// begin listing subdirs
- strcat(result, "Sub-directories
");
- strcat(result, "");
+ result = safe_append(result, &allocated, "Sub-directories
");
+ result = safe_append(result, &allocated, "");
for(i = 0; i < numentries; i++) {
// skip all non-directories
@@ -135,21 +135,6 @@ char* gen_html(const char *url, struct Entry *entries, size_t numentries, int up
urlencode(entries[i].name, encName);
- size_t entrylen = 64 + strlen(url) + strlen(entries[i].name) + strlen(encName);
- size_t resultlen = strlen(result);
-
- if(allocated < resultlen + entrylen) {
- allocated = 2*allocated + entrylen; // be on the safe side
- 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) {
snprintf(buf, BUFSIZE, "- %s/
\n",
encName, entries[i].name);
@@ -157,14 +142,14 @@ char* gen_html(const char *url, struct Entry *entries, size_t numentries, int up
snprintf(buf, BUFSIZE, "- %s/
\n",
url, encName, entries[i].name);
}
- strcat(result, buf);
+ result = safe_append(result, &allocated, buf);
}
- strcat(result, "
");
+ result = safe_append(result, &allocated, "
");
// begin listing files
- strcat(result, "Files
");
- strcat(result, "");
+ result = safe_append(result, &allocated, "Files
");
+ result = safe_append(result, &allocated, "");
// here the listing entries are generated
for(i = 0; i < numentries; i++) {
@@ -174,21 +159,6 @@ char* gen_html(const char *url, struct Entry *entries, size_t numentries, int up
urlencode(entries[i].name, encName);
- size_t entrylen = 64 + strlen(url) + strlen(entries[i].name) + strlen(encName);
- size_t resultlen = strlen(result);
-
- if(allocated < resultlen + entrylen) {
- allocated = 2*allocated + entrylen; // be on the safe side
- 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));
- break;
- }
-
- result = tmpresult;
- }
-
if(isrootdir) {
snprintf(buf, BUFSIZE, "- %s [%s]
\n",
encName, entries[i].name, format_size(entries[i].size));
@@ -196,15 +166,15 @@ char* gen_html(const char *url, struct Entry *entries, size_t numentries, int up
snprintf(buf, BUFSIZE, "- %s [%s]
\n",
url, encName, entries[i].name, format_size(entries[i].size));
}
- strcat(result, buf);
+ result = safe_append(result, &allocated, buf);
}
- strcat(result, "
");
+ result = safe_append(result, &allocated, "
");
if(uploadEnabled) {
- strcat(result, "Upload
");
- strcat(result, "Upload a file to this directory:
");
- strcat(result,
+ result = safe_append(result, &allocated, "Upload
");
+ result = safe_append(result, &allocated, "Upload a file to this directory:
");
+ result = safe_append(result, &allocated,
""
"