summaryrefslogtreecommitdiff
path: root/extmod/vfs_fat.c
diff options
context:
space:
mode:
authorScott Shawcroft <scott@tannewt.org>2019-03-13 15:07:19 -0700
committerScott Shawcroft <scott@tannewt.org>2019-03-13 16:10:52 -0700
commit7482870164d614adb3de99f68d04535c3f035923 (patch)
treeba1635691ba962464a1c9b54878281d91c203887 /extmod/vfs_fat.c
parent494a9d382531762fe15ddfbef094944e2b7096c2 (diff)
Throw an error when moving a directory into itself.
Fixes #1192
Diffstat (limited to 'extmod/vfs_fat.c')
-rw-r--r--extmod/vfs_fat.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c
index 95dd6819a..c7e8a81e8 100644
--- a/extmod/vfs_fat.c
+++ b/extmod/vfs_fat.c
@@ -237,7 +237,23 @@ STATIC mp_obj_t fat_vfs_rename(mp_obj_t vfs_in, mp_obj_t path_in, mp_obj_t path_
mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(vfs_in);
const char *old_path = mp_obj_str_get_str(path_in);
const char *new_path = mp_obj_str_get_str(path_out);
- FRESULT res = f_rename(&self->fatfs, old_path, new_path);
+
+ // Check to see if we're moving a directory into itself. This occurs when we're moving a
+ // directory where the old path is a prefix of the new and the next character is a "/" and thus
+ // preserves the original directory name.
+ FILINFO fno;
+ FRESULT res = f_stat(&self->fatfs, old_path, &fno);
+ if (res != FR_OK) {
+ mp_raise_OSError(fresult_to_errno_table[res]);
+ }
+ if ((fno.fattrib & AM_DIR) != 0 &&
+ strlen(new_path) > strlen(old_path) &&
+ new_path[strlen(old_path)] == '/' &&
+ strncmp(old_path, new_path, strlen(old_path)) == 0) {
+ mp_raise_OSError(MP_EINVAL);
+ }
+
+ res = f_rename(&self->fatfs, old_path, new_path);
if (res == FR_EXIST) {
// if new_path exists then try removing it (but only if it's a file)
fat_vfs_remove_internal(vfs_in, path_out, 0); // 0 == file attribute