|
@@ -9001,8 +9001,8 @@ mg_url_encode(const char *src, char *dst, size_t dst_len)
|
|
|
static int
|
|
|
print_dir_entry(struct de *de)
|
|
|
{
|
|
|
- size_t hrefsize;
|
|
|
- char *href;
|
|
|
+ size_t namesize, escsize, i;
|
|
|
+ char *href, *esc, *p;
|
|
|
char size[64], mod[64];
|
|
|
#if defined(REENTRANT_TIME)
|
|
|
struct tm _tm;
|
|
@@ -9011,11 +9011,30 @@ print_dir_entry(struct de *de)
|
|
|
struct tm *tm;
|
|
|
#endif
|
|
|
|
|
|
- hrefsize = PATH_MAX * 3; /* worst case */
|
|
|
- href = (char *)mg_malloc(hrefsize);
|
|
|
+ /* Estimate worst case size for encoding and escaping */
|
|
|
+ namesize = strlen(de->file_name) + 1;
|
|
|
+ escsize = de->file_name[strcspn(de->file_name, "&<>")] ? namesize * 5 : 0;
|
|
|
+ href = (char *)mg_malloc(namesize * 3 + escsize);
|
|
|
if (href == NULL) {
|
|
|
return -1;
|
|
|
}
|
|
|
+ mg_url_encode(de->file_name, href, namesize * 3);
|
|
|
+ esc = NULL;
|
|
|
+ if (escsize > 0) {
|
|
|
+ /* HTML escaping needed */
|
|
|
+ esc = href + namesize * 3;
|
|
|
+ for (i = 0, p = esc; de->file_name[i]; i++, p += strlen(p)) {
|
|
|
+ mg_strlcpy(p, de->file_name + i, 2);
|
|
|
+ if (*p == '&') {
|
|
|
+ strcpy(p, "&");
|
|
|
+ } else if (*p == '<') {
|
|
|
+ strcpy(p, "<");
|
|
|
+ } else if (*p == '>') {
|
|
|
+ strcpy(p, ">");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if (de->file.is_directory) {
|
|
|
mg_snprintf(de->conn,
|
|
|
NULL, /* Buffer is big enough */
|
|
@@ -9071,13 +9090,12 @@ print_dir_entry(struct de *de)
|
|
|
mg_strlcpy(mod, "01-Jan-1970 00:00", sizeof(mod));
|
|
|
mod[sizeof(mod) - 1] = '\0';
|
|
|
}
|
|
|
- mg_url_encode(de->file_name, href, hrefsize);
|
|
|
mg_printf(de->conn,
|
|
|
"<tr><td><a href=\"%s%s\">%s%s</a></td>"
|
|
|
"<td> %s</td><td> %s</td></tr>\n",
|
|
|
href,
|
|
|
de->file.is_directory ? "/" : "",
|
|
|
- de->file_name,
|
|
|
+ esc ? esc : de->file_name,
|
|
|
de->file.is_directory ? "/" : "",
|
|
|
mod,
|
|
|
size);
|
|
@@ -9314,7 +9332,8 @@ handle_directory_request(struct mg_connection *conn, const char *dir)
|
|
|
unsigned int i;
|
|
|
int sort_direction;
|
|
|
struct dir_scan_data data = {NULL, 0, 128};
|
|
|
- char date[64];
|
|
|
+ char date[64], *esc, *p;
|
|
|
+ const char *title;
|
|
|
time_t curtime = time(NULL);
|
|
|
|
|
|
if (!scan_directory(conn, dir, &data, dir_scan_callback)) {
|
|
@@ -9332,6 +9351,27 @@ handle_directory_request(struct mg_connection *conn, const char *dir)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ esc = NULL;
|
|
|
+ title = conn->request_info.local_uri;
|
|
|
+ if (title[strcspn(title, "&<>")]) {
|
|
|
+ /* HTML escaping needed */
|
|
|
+ esc = (char *)mg_malloc(strlen(title) * 5 + 1);
|
|
|
+ if (esc) {
|
|
|
+ for (i = 0, p = esc; title[i]; i++, p += strlen(p)) {
|
|
|
+ mg_strlcpy(p, title + i, 2);
|
|
|
+ if (*p == '&') {
|
|
|
+ strcpy(p, "&");
|
|
|
+ } else if (*p == '<') {
|
|
|
+ strcpy(p, "<");
|
|
|
+ } else if (*p == '>') {
|
|
|
+ strcpy(p, ">");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ title = "";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
sort_direction = ((conn->request_info.query_string != NULL)
|
|
|
&& (conn->request_info.query_string[0] != '\0')
|
|
|
&& (conn->request_info.query_string[1] == 'd'))
|
|
@@ -9355,11 +9395,12 @@ handle_directory_request(struct mg_connection *conn, const char *dir)
|
|
|
"<th><a href=\"?d%c\">Modified</a></th>"
|
|
|
"<th><a href=\"?s%c\">Size</a></th></tr>"
|
|
|
"<tr><td colspan=\"3\"><hr></td></tr>",
|
|
|
- conn->request_info.local_uri,
|
|
|
- conn->request_info.local_uri,
|
|
|
+ esc ? esc : title,
|
|
|
+ esc ? esc : title,
|
|
|
sort_direction,
|
|
|
sort_direction,
|
|
|
sort_direction);
|
|
|
+ mg_free(esc);
|
|
|
|
|
|
/* Print first entry - link to a parent directory */
|
|
|
mg_printf(conn,
|
|
@@ -9383,7 +9424,7 @@ handle_directory_request(struct mg_connection *conn, const char *dir)
|
|
|
mg_free(data.entries);
|
|
|
}
|
|
|
|
|
|
- mg_printf(conn, "%s", "</table></body></html>");
|
|
|
+ mg_printf(conn, "%s", "</table></pre></body></html>");
|
|
|
conn->status_code = 200;
|
|
|
}
|
|
|
|