From 7482870164d614adb3de99f68d04535c3f035923 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 13 Mar 2019 15:07:19 -0700 Subject: [PATCH] Throw an error when moving a directory into itself. Fixes #1192 --- extmod/vfs_fat.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c index 95dd6819ae..c7e8a81e81 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