From 4b02a404badac4efa86a1793ca28c627c0629f53 Mon Sep 17 00:00:00 2001 From: Nikolay Minaylov Date: Tue, 21 Jun 2022 16:46:39 +0300 Subject: [PATCH] [FL-2588] RPC storage: Ignore incorrect file names #1318 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- applications/rpc/rpc_storage.c | 95 +++++++++++++++++++++++++++------- 1 file changed, 75 insertions(+), 20 deletions(-) diff --git a/applications/rpc/rpc_storage.c b/applications/rpc/rpc_storage.c index e6a59ea8d..624d7c7b8 100644 --- a/applications/rpc/rpc_storage.c +++ b/applications/rpc/rpc_storage.c @@ -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)); } +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) { furi_assert(request); furi_assert(context); @@ -245,18 +274,23 @@ static void rpc_system_storage_list_process(const PB_Main* request, void* contex FileInfo fileinfo; char* name = malloc(MAX_NAME_LENGTH + 1); if(storage_dir_read(dir, &fileinfo, name, MAX_NAME_LENGTH)) { - if(i == COUNT_OF(list->file)) { - list->file_count = i; - response.has_next = true; - rpc_send_and_release(session, &response); - i = 0; + if(rpc_system_storage_is_filename_correct(name)) { + if(i == COUNT_OF(list->file)) { + list->file_count = i; + response.has_next = true; + 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 { list->file_count = i; finish = true; @@ -345,6 +379,14 @@ static void rpc_system_storage_write_process(const PB_Main* request, void* conte 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) && (rpc_storage->state == RpcStorageStateWriting)) { 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) { FileInfo fileinfo; - bool is_dir_is_empty = false; + bool is_dir_is_empty = true; FS_Error error = storage_common_stat(fs_api, path, &fileinfo); if((error == FSE_OK) && (fileinfo.flags & FSF_DIRECTORY)) { File* dir = storage_file_alloc(fs_api); if(storage_dir_open(dir, path)) { 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); } 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"); char* path = request->content.storage_mkdir_request.path; if(path) { - FS_Error error = storage_common_mkdir(fs_api, path); - status = rpc_system_storage_get_error(error); + if(rpc_system_storage_is_filename_correct(path)) { + 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 { 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"); - FS_Error error = storage_common_rename( - fs_api, - request->content.storage_rename_request.old_path, - request->content.storage_rename_request.new_path); - status = rpc_system_storage_get_error(error); + if(rpc_system_storage_is_filename_correct(request->content.storage_rename_request.new_path)) { + FS_Error error = storage_common_rename( + fs_api, + request->content.storage_rename_request.old_path, + 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"); rpc_send_and_release_empty(session, request->command_id, status);