summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Soffke <christian.soffke@gmail.com>2024-08-05 20:45:40 +0200
committerChristian Soffke <christian.soffke@gmail.com>2024-08-11 19:32:55 +0200
commitce417b3e1bea6a18889965bafee4094d4dd3e083 (patch)
treec3da0e8cc8e79a198da72dab7183e3c5e76cf59f
parent48400b6ec112118b69123d2374a3bb7d8df78f89 (diff)
downloadrockbox-ce417b3e1bea6a18889965bafee4094d4dd3e083.tar.gz
rockbox-ce417b3e1bea6a18889965bafee4094d4dd3e083.zip
fileop: check dst path length during pre-scan
Use the known difference in path length between src and dst in order to detect an insufficient buffer size not just for the source, but also for the destination path during the pre-scan already. Change-Id: I9e4caeb9b9d2cb1e9577f418f2b777ab17718acf
-rw-r--r--apps/fileop.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/apps/fileop.c b/apps/fileop.c
index 1aaee3bb64..65a3b37e0a 100644
--- a/apps/fileop.c
+++ b/apps/fileop.c
@@ -51,6 +51,7 @@ struct file_op_params
51 unsigned long long total_size; 51 unsigned long long total_size;
52 unsigned long long processed_size; 52 unsigned long long processed_size;
53 size_t append; /* Append position in 'path' for stack push */ 53 size_t append; /* Append position in 'path' for stack push */
54 size_t extra_len; /* Length added by dst path compared to src */
54}; 55};
55 56
56static int prompt_name(char* buf, size_t bufsz) 57static int prompt_name(char* buf, size_t bufsz)
@@ -131,6 +132,7 @@ static void init_file_op(struct file_op_params *param,
131 param->toplevel_name = selected_file; 132 param->toplevel_name = selected_file;
132 } 133 }
133 param->is_dir = dir_exists(param->path); 134 param->is_dir = dir_exists(param->path);
135 param->extra_len = 0;
134 param->objects = 0; /* how many files and subdirectories*/ 136 param->objects = 0; /* how many files and subdirectories*/
135 param->processed = 0; 137 param->processed = 0;
136 param->total_size = 0; 138 param->total_size = 0;
@@ -209,7 +211,7 @@ static int directory_fileop(struct file_op_params *param, enum file_op_current f
209 break; 211 break;
210 } 212 }
211 213
212 if (param->append >= sizeof (param->path)) { 214 if (param->append + param->extra_len >= sizeof (param->path)) {
213 rc = FORC_PATH_TOO_LONG; 215 rc = FORC_PATH_TOO_LONG;
214 break; /* no space left in buffer */ 216 break; /* no space left in buffer */
215 } 217 }
@@ -523,6 +525,10 @@ int copy_move_fileobject(const char *src_path, const char *dst_path, unsigned in
523 /* Try renaming first */ 525 /* Try renaming first */
524 rc = move_by_rename(&src, dst.path, &flags); 526 rc = move_by_rename(&src, dst.path, &flags);
525 if (rc < FORC_SUCCESS) { 527 if (rc < FORC_SUCCESS) {
528 int extra_len = dst.append - src.append;
529 if (extra_len > 0)
530 src.extra_len = extra_len;
531
526 rc = check_count_fileobjects(&src); 532 rc = check_count_fileobjects(&src);
527 if (rc == FORC_SUCCESS) { 533 if (rc == FORC_SUCCESS) {
528 rc = copy_move_directory(&src, &dst, flags); 534 rc = copy_move_directory(&src, &dst, flags);