summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Walther <cwalther@gmx.ch>2023-07-31 18:25:26 +0200
committerChristian Walther <cwalther@gmx.ch>2023-10-19 16:21:08 +0200
commite3ba6f952bda153cfc3389eb48c7645d71b2b094 (patch)
tree8dbbc2d610e3d7c2614388813c67420b2ae80698
parent86c7b957a85d69ffb19bc6e4db719e902abd3fc1 (diff)
extmod/vfs_posix: Fix relative root path.
A VfsPosix created with a relative root path would get confused when chdir() was called on it and become unable to properly resolve absolute paths, because changing directories effectively shifted its root. The simplest fix for that would be to say "don't do that", but since the unit tests themselves do it, fix it by making a relative path absolute before storing it. Signed-off-by: Christian Walther <cwalther@gmx.ch>
-rw-r--r--extmod/vfs_posix.c26
-rw-r--r--tests/extmod/vfs_posix.py13
-rw-r--r--tests/extmod/vfs_posix.py.exp1
3 files changed, 39 insertions, 1 deletions
diff --git a/extmod/vfs_posix.c b/extmod/vfs_posix.c
index d63bb5be7..1505682f1 100644
--- a/extmod/vfs_posix.c
+++ b/extmod/vfs_posix.c
@@ -46,6 +46,9 @@
#ifdef _MSC_VER
#include <direct.h> // For mkdir etc.
#endif
+#ifdef _WIN32
+#include <windows.h>
+#endif
typedef struct _mp_obj_vfs_posix_t {
mp_obj_base_t base;
@@ -107,7 +110,28 @@ STATIC mp_obj_t vfs_posix_make_new(const mp_obj_type_t *type, size_t n_args, siz
mp_obj_vfs_posix_t *vfs = mp_obj_malloc(mp_obj_vfs_posix_t, type);
vstr_init(&vfs->root, 0);
if (n_args == 1) {
- vstr_add_str(&vfs->root, mp_obj_str_get_str(args[0]));
+ const char *root = mp_obj_str_get_str(args[0]);
+ // if the root is relative, make it absolute, otherwise we'll get confused by chdir
+ #ifdef _WIN32
+ char buf[MICROPY_ALLOC_PATH_MAX + 1];
+ DWORD result = GetFullPathNameA(root, sizeof(buf), buf, NULL);
+ if (result > 0 && result < sizeof(buf)) {
+ vstr_add_str(&vfs->root, buf);
+ } else {
+ mp_raise_OSError(GetLastError());
+ }
+ #else
+ if (root[0] != '\0' && root[0] != '/') {
+ char buf[MICROPY_ALLOC_PATH_MAX + 1];
+ const char *cwd = getcwd(buf, sizeof(buf));
+ if (cwd == NULL) {
+ mp_raise_OSError(errno);
+ }
+ vstr_add_str(&vfs->root, cwd);
+ vstr_add_char(&vfs->root, '/');
+ }
+ vstr_add_str(&vfs->root, root);
+ #endif
vstr_add_char(&vfs->root, '/');
}
vfs->root_len = vfs->root.len;
diff --git a/tests/extmod/vfs_posix.py b/tests/extmod/vfs_posix.py
index 05dc0f537..ebbd08a4a 100644
--- a/tests/extmod/vfs_posix.py
+++ b/tests/extmod/vfs_posix.py
@@ -99,6 +99,19 @@ if hasattr(vfs, "statvfs"):
print(type(list(vfs.ilistdir("."))[0][0]))
print(type(list(vfs.ilistdir(b"."))[0][0]))
+# chdir should not affect absolute paths (regression test)
+vfs.mkdir("/subdir")
+vfs.mkdir("/subdir/micropy_test_dir")
+with vfs.open("/subdir/micropy_test_dir/test2", "w") as f:
+ f.write("wrong")
+vfs.chdir("/subdir")
+with vfs.open("/test2", "r") as f:
+ print(f.read())
+os.chdir(curdir)
+vfs.remove("/subdir/micropy_test_dir/test2")
+vfs.rmdir("/subdir/micropy_test_dir")
+vfs.rmdir("/subdir")
+
# remove
os.remove(temp_dir + "/test2")
print(os.listdir(temp_dir))
diff --git a/tests/extmod/vfs_posix.py.exp b/tests/extmod/vfs_posix.py.exp
index 99922e621..bd1ec7bad 100644
--- a/tests/extmod/vfs_posix.py.exp
+++ b/tests/extmod/vfs_posix.py.exp
@@ -10,6 +10,7 @@ next_file_no <= base_file_no True
<class 'tuple'>
<class 'str'>
<class 'bytes'>
+hello
[]
remove OSError
False