Decode percent encoded file paths and set charset

Also, fix multiple file uploads from directory browser.

Fixes #6646
This commit is contained in:
Scott Shawcroft 2022-08-09 16:36:57 -07:00
parent 5084de1b73
commit e0fb308972
No known key found for this signature in database
GPG Key ID: 0DFD512649C052DA
2 changed files with 36 additions and 6 deletions

View File

@ -149,10 +149,10 @@ async function upload(e) {
) )
if (response.ok) { if (response.ok) {
refresh_list(); refresh_list();
}
}
files.value = ""; files.value = "";
upload_button.disabled = true; upload_button.disabled = true;
}
}
} }
async function del(e) { async function del(e) {

View File

@ -659,13 +659,13 @@ static void _reply_with_file(socketpool_socket_obj_t *socket, _request *request,
mp_printf(&_socket_print, "Content-Length: %d\r\n", total_length); mp_printf(&_socket_print, "Content-Length: %d\r\n", total_length);
// TODO: Make this a table to save space. // TODO: Make this a table to save space.
if (_endswith(filename, ".txt") || _endswith(filename, ".py")) { if (_endswith(filename, ".txt") || _endswith(filename, ".py")) {
_send_str(socket, "Content-Type: text/plain\r\n"); _send_strs(socket, "Content-Type: text/plain", ";charset=UTF-8\r\n", NULL);
} else if (_endswith(filename, ".js")) { } else if (_endswith(filename, ".js")) {
_send_str(socket, "Content-Type: text/javascript\r\n"); _send_strs(socket, "Content-Type: text/javascript", ";charset=UTF-8\r\n", NULL);
} else if (_endswith(filename, ".html")) { } else if (_endswith(filename, ".html")) {
_send_str(socket, "Content-Type: text/html\r\n"); _send_strs(socket, "Content-Type: text/html", ";charset=UTF-8\r\n", NULL);
} else if (_endswith(filename, ".json")) { } else if (_endswith(filename, ".json")) {
_send_str(socket, "Content-Type: application/json\r\n"); _send_strs(socket, "Content-Type: application/json", ";charset=UTF-8\r\n", NULL);
} else { } else {
_send_str(socket, "Content-Type: application/octet-stream\r\n"); _send_str(socket, "Content-Type: application/octet-stream\r\n");
} }
@ -966,6 +966,16 @@ static void _reply_websocket_upgrade(socketpool_socket_obj_t *socket, _request *
// socket is now closed and "disconnected". // socket is now closed and "disconnected".
} }
static uint8_t _hex2nibble(char h) {
if ('0' <= h && h <= '9') {
return h - '0';
} else if ('A' <= h && h <= 'F') {
return h - 'A' + 0xa;
}
// Shouldn't usually use lower case.
return h - 'a' + 0xa;
}
static bool _reply(socketpool_socket_obj_t *socket, _request *request) { static bool _reply(socketpool_socket_obj_t *socket, _request *request) {
if (request->redirect) { if (request->redirect) {
_reply_redirect(socket, request, request->path); _reply_redirect(socket, request, request->path);
@ -983,6 +993,26 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) {
_reply_forbidden(socket, request); _reply_forbidden(socket, request);
} }
} else { } else {
// Decode any percent encoded bytes so that we're left with UTF-8.
// We only do this on /fs/ paths and after redirect so that any
// path echoing we do stays encoded.
size_t o = 0;
size_t i = 0;
while (i < strlen(request->path)) {
if (request->path[i] == '%') {
request->path[o] = _hex2nibble(request->path[i + 1]) << 4 | _hex2nibble(request->path[i + 2]);
i += 3;
} else {
if (i != o) {
request->path[o] = request->path[i];
}
i += 1;
}
o += 1;
}
if (o < i) {
request->path[o] = '\0';
}
char *path = request->path + 3; char *path = request->path + 3;
size_t pathlen = strlen(path); size_t pathlen = strlen(path);
FATFS *fs = filesystem_circuitpy(); FATFS *fs = filesystem_circuitpy();