Skip to content

Commit 7482870

Browse files
committed
Throw an error when moving a directory into itself.
Fixes #1192
1 parent 494a9d3 commit 7482870

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

extmod/vfs_fat.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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_
237237
mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(vfs_in);
238238
const char *old_path = mp_obj_str_get_str(path_in);
239239
const char *new_path = mp_obj_str_get_str(path_out);
240-
FRESULT res = f_rename(&self->fatfs, old_path, new_path);
240+
241+
// Check to see if we're moving a directory into itself. This occurs when we're moving a
242+
// directory where the old path is a prefix of the new and the next character is a "/" and thus
243+
// preserves the original directory name.
244+
FILINFO fno;
245+
FRESULT res = f_stat(&self->fatfs, old_path, &fno);
246+
if (res != FR_OK) {
247+
mp_raise_OSError(fresult_to_errno_table[res]);
248+
}
249+
if ((fno.fattrib & AM_DIR) != 0 &&
250+
strlen(new_path) > strlen(old_path) &&
251+
new_path[strlen(old_path)] == '/' &&
252+
strncmp(old_path, new_path, strlen(old_path)) == 0) {
253+
mp_raise_OSError(MP_EINVAL);
254+
}
255+
256+
res = f_rename(&self->fatfs, old_path, new_path);
241257
if (res == FR_EXIST) {
242258
// if new_path exists then try removing it (but only if it's a file)
243259
fat_vfs_remove_internal(vfs_in, path_out, 0); // 0 == file attribute

0 commit comments

Comments
 (0)