Skip to content

Commit 74083da

Browse files
authored
Merge pull request #1645 from tannewt/fix_directory_move
Fix directory move into itself and prevent more fs changes when read-only
2 parents 494a9d3 + e05ab64 commit 74083da

File tree

2 files changed

+29
-3
lines changed

2 files changed

+29
-3
lines changed

extmod/vfs_fat.c

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
#include "lib/oofatfs/ff.h"
4040
#include "extmod/vfs_fat.h"
4141
#include "lib/timeutils/timeutils.h"
42-
42+
#include "supervisor/filesystem.h"
4343
#include "supervisor/shared/translate.h"
4444

4545
#if _MAX_SS == _MIN_SS
@@ -99,6 +99,12 @@ STATIC mp_obj_t fat_vfs_make_new(const mp_obj_type_t *type, size_t n_args, const
9999
return MP_OBJ_FROM_PTR(vfs);
100100
}
101101

102+
STATIC void verify_fs_writable(fs_user_mount_t *vfs) {
103+
if (!filesystem_is_writable_by_python(vfs)) {
104+
mp_raise_OSError(MP_EROFS);
105+
}
106+
}
107+
102108
#if _FS_REENTRANT
103109
STATIC mp_obj_t fat_vfs_del(mp_obj_t self_in) {
104110
mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(self_in);
@@ -201,6 +207,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(fat_vfs_ilistdir_obj, 1, 2, fat_vfs_i
201207

202208
STATIC mp_obj_t fat_vfs_remove_internal(mp_obj_t vfs_in, mp_obj_t path_in, mp_int_t attr) {
203209
mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(vfs_in);
210+
verify_fs_writable(self);
204211
const char *path = mp_obj_str_get_str(path_in);
205212

206213
FILINFO fno;
@@ -235,9 +242,26 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_rmdir_obj, fat_vfs_rmdir);
235242

236243
STATIC mp_obj_t fat_vfs_rename(mp_obj_t vfs_in, mp_obj_t path_in, mp_obj_t path_out) {
237244
mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(vfs_in);
245+
verify_fs_writable(self);
238246
const char *old_path = mp_obj_str_get_str(path_in);
239247
const char *new_path = mp_obj_str_get_str(path_out);
240-
FRESULT res = f_rename(&self->fatfs, old_path, new_path);
248+
249+
// Check to see if we're moving a directory into itself. This occurs when we're moving a
250+
// directory where the old path is a prefix of the new and the next character is a "/" and thus
251+
// preserves the original directory name.
252+
FILINFO fno;
253+
FRESULT res = f_stat(&self->fatfs, old_path, &fno);
254+
if (res != FR_OK) {
255+
mp_raise_OSError(fresult_to_errno_table[res]);
256+
}
257+
if ((fno.fattrib & AM_DIR) != 0 &&
258+
strlen(new_path) > strlen(old_path) &&
259+
new_path[strlen(old_path)] == '/' &&
260+
strncmp(old_path, new_path, strlen(old_path)) == 0) {
261+
mp_raise_OSError(MP_EINVAL);
262+
}
263+
264+
res = f_rename(&self->fatfs, old_path, new_path);
241265
if (res == FR_EXIST) {
242266
// if new_path exists then try removing it (but only if it's a file)
243267
fat_vfs_remove_internal(vfs_in, path_out, 0); // 0 == file attribute
@@ -255,6 +279,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(fat_vfs_rename_obj, fat_vfs_rename);
255279

256280
STATIC mp_obj_t fat_vfs_mkdir(mp_obj_t vfs_in, mp_obj_t path_o) {
257281
mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(vfs_in);
282+
verify_fs_writable(self);
258283
const char *path = mp_obj_str_get_str(path_o);
259284
FRESULT res = f_mkdir(&self->fatfs, path);
260285
if (res == FR_OK) {
@@ -419,6 +444,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_getlabel_obj, vfs_fat_getlabel);
419444

420445
STATIC mp_obj_t vfs_fat_setlabel(mp_obj_t self_in, mp_obj_t label_in) {
421446
fs_user_mount_t *self = MP_OBJ_TO_PTR(self_in);
447+
verify_fs_writable(self);
422448
const char *label_str = mp_obj_str_get_str(label_in);
423449
FRESULT res = f_setlabel(&self->fatfs, label_str);
424450
if (res != FR_OK) {

ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ CIRCUITPY_FREQUENCYIO = 0
1616
CHIP_VARIANT = SAMD21G18A
1717
CHIP_FAMILY = samd21
1818

19-
CFLAGS_INLINE_LIMIT = 55
19+
CFLAGS_INLINE_LIMIT = 50
2020

2121
# Include these Python libraries in firmware.
2222
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice

0 commit comments

Comments
 (0)