[FL-2588] RPC storage: Ignore incorrect file names #1318

Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
Nikolay Minaylov 2022-06-21 16:46:39 +03:00 committed by GitHub
parent dab1313a3b
commit 4b02a404ba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -100,6 +100,35 @@ static PB_CommandStatus rpc_system_storage_get_file_error(File* file) {
return rpc_system_storage_get_error(storage_file_get_error(file)); return rpc_system_storage_get_error(storage_file_get_error(file));
} }
static bool rpc_system_storage_is_filename_correct(const char* path) {
const char* name_pos = strrchr(path, '/');
if(name_pos == NULL) {
name_pos = path;
} else {
name_pos++;
}
while(*name_pos != '\0') {
if((*name_pos >= '0') && (*name_pos <= '9')) {
name_pos++;
continue;
} else if((*name_pos >= 'A') && (*name_pos <= 'Z')) {
name_pos++;
continue;
} else if((*name_pos >= 'a') && (*name_pos <= 'z')) {
name_pos++;
continue;
} else if(strchr(".!#\\$%&'()-@^_`{}~", *name_pos) != NULL) {
name_pos++;
continue;
}
return false;
}
return true;
}
static void rpc_system_storage_info_process(const PB_Main* request, void* context) { static void rpc_system_storage_info_process(const PB_Main* request, void* context) {
furi_assert(request); furi_assert(request);
furi_assert(context); furi_assert(context);
@ -245,18 +274,23 @@ static void rpc_system_storage_list_process(const PB_Main* request, void* contex
FileInfo fileinfo; FileInfo fileinfo;
char* name = malloc(MAX_NAME_LENGTH + 1); char* name = malloc(MAX_NAME_LENGTH + 1);
if(storage_dir_read(dir, &fileinfo, name, MAX_NAME_LENGTH)) { if(storage_dir_read(dir, &fileinfo, name, MAX_NAME_LENGTH)) {
if(i == COUNT_OF(list->file)) { if(rpc_system_storage_is_filename_correct(name)) {
list->file_count = i; if(i == COUNT_OF(list->file)) {
response.has_next = true; list->file_count = i;
rpc_send_and_release(session, &response); response.has_next = true;
i = 0; rpc_send_and_release(session, &response);
i = 0;
}
list->file[i].type = (fileinfo.flags & FSF_DIRECTORY) ?
PB_Storage_File_FileType_DIR :
PB_Storage_File_FileType_FILE;
list->file[i].size = fileinfo.size;
list->file[i].data = NULL;
list->file[i].name = name;
++i;
} else {
free(name);
} }
list->file[i].type = (fileinfo.flags & FSF_DIRECTORY) ? PB_Storage_File_FileType_DIR :
PB_Storage_File_FileType_FILE;
list->file[i].size = fileinfo.size;
list->file[i].data = NULL;
list->file[i].name = name;
++i;
} else { } else {
list->file_count = i; list->file_count = i;
finish = true; finish = true;
@ -345,6 +379,14 @@ static void rpc_system_storage_write_process(const PB_Main* request, void* conte
bool result = true; bool result = true;
if(!rpc_system_storage_is_filename_correct(request->content.storage_write_request.path)) {
rpc_storage->current_command_id = request->command_id;
rpc_send_and_release_empty(
session, rpc_storage->current_command_id, PB_CommandStatus_ERROR_STORAGE_INVALID_NAME);
rpc_system_storage_reset_state(rpc_storage, session, false);
return;
}
if((request->command_id != rpc_storage->current_command_id) && if((request->command_id != rpc_storage->current_command_id) &&
(rpc_storage->state == RpcStorageStateWriting)) { (rpc_storage->state == RpcStorageStateWriting)) {
rpc_system_storage_reset_state(rpc_storage, session, true); rpc_system_storage_reset_state(rpc_storage, session, true);
@ -384,13 +426,18 @@ static void rpc_system_storage_write_process(const PB_Main* request, void* conte
static bool rpc_system_storage_is_dir_is_empty(Storage* fs_api, const char* path) { static bool rpc_system_storage_is_dir_is_empty(Storage* fs_api, const char* path) {
FileInfo fileinfo; FileInfo fileinfo;
bool is_dir_is_empty = false; bool is_dir_is_empty = true;
FS_Error error = storage_common_stat(fs_api, path, &fileinfo); FS_Error error = storage_common_stat(fs_api, path, &fileinfo);
if((error == FSE_OK) && (fileinfo.flags & FSF_DIRECTORY)) { if((error == FSE_OK) && (fileinfo.flags & FSF_DIRECTORY)) {
File* dir = storage_file_alloc(fs_api); File* dir = storage_file_alloc(fs_api);
if(storage_dir_open(dir, path)) { if(storage_dir_open(dir, path)) {
char* name = malloc(MAX_NAME_LENGTH); char* name = malloc(MAX_NAME_LENGTH);
is_dir_is_empty = !storage_dir_read(dir, &fileinfo, name, MAX_NAME_LENGTH); while(storage_dir_read(dir, &fileinfo, name, MAX_NAME_LENGTH)) {
if(rpc_system_storage_is_filename_correct(name)) {
is_dir_is_empty = false;
break;
}
}
free(name); free(name);
} }
storage_dir_close(dir); storage_dir_close(dir);
@ -458,8 +505,12 @@ static void rpc_system_storage_mkdir_process(const PB_Main* request, void* conte
Storage* fs_api = furi_record_open("storage"); Storage* fs_api = furi_record_open("storage");
char* path = request->content.storage_mkdir_request.path; char* path = request->content.storage_mkdir_request.path;
if(path) { if(path) {
FS_Error error = storage_common_mkdir(fs_api, path); if(rpc_system_storage_is_filename_correct(path)) {
status = rpc_system_storage_get_error(error); FS_Error error = storage_common_mkdir(fs_api, path);
status = rpc_system_storage_get_error(error);
} else {
status = PB_CommandStatus_ERROR_STORAGE_INVALID_NAME;
}
} else { } else {
status = PB_CommandStatus_ERROR_INVALID_PARAMETERS; status = PB_CommandStatus_ERROR_INVALID_PARAMETERS;
} }
@ -551,11 +602,15 @@ static void rpc_system_storage_rename_process(const PB_Main* request, void* cont
Storage* fs_api = furi_record_open("storage"); Storage* fs_api = furi_record_open("storage");
FS_Error error = storage_common_rename( if(rpc_system_storage_is_filename_correct(request->content.storage_rename_request.new_path)) {
fs_api, FS_Error error = storage_common_rename(
request->content.storage_rename_request.old_path, fs_api,
request->content.storage_rename_request.new_path); request->content.storage_rename_request.old_path,
status = rpc_system_storage_get_error(error); request->content.storage_rename_request.new_path);
status = rpc_system_storage_get_error(error);
} else {
status = PB_CommandStatus_ERROR_STORAGE_INVALID_NAME;
}
furi_record_close("storage"); furi_record_close("storage");
rpc_send_and_release_empty(session, request->command_id, status); rpc_send_and_release_empty(session, request->command_id, status);