Просмотр исходного кода

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

Co-authored-by: あく <alleteam@gmail.com>
Nikolay Minaylov 3 лет назад
Родитель
Сommit
4b02a404ba
1 измененных файлов с 75 добавлено и 20 удалено
  1. 75 20
      applications/rpc/rpc_storage.c

+ 75 - 20
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);