summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Walther <cwalther@gmx.ch>2023-07-30 14:48:22 +0200
committerChristian Walther <cwalther@gmx.ch>2023-10-19 16:21:09 +0200
commitbe28829ae8d22e1a0373bda116022ee446fb2ed8 (patch)
tree096b53d36c4d123e937cf8c6a9779ffd8a905aac
parent0c4fb1687193a6c6f5edbb9404ecb7e5d6f3bec3 (diff)
extmod/vfs_posix: Fix getcwd() on non-root VFS.
The unwritten API contract expected of a VFS.getcwd() by mp_vfs_getcwd() is that its return value should be either "" or "/" when the CWD is at the root of the VFS and otherwise start with a slash and not end with a slash. This was not correctly implemented in VfsPosix for instances with a non-empty root - the required leading slash, if any, was cut off because the root length includes a trailing slash. This would result in missing slashes in the middle of the return value of os.getcwd() or in uninitialized garbage from beyond a string's null terminator when the CWD was at the VFS root. Signed-off-by: Christian Walther <cwalther@gmx.ch>
-rw-r--r--extmod/vfs_posix.c9
-rw-r--r--tests/extmod/vfs_posix_paths.py19
-rw-r--r--tests/extmod/vfs_posix_paths.py.exp12
3 files changed, 38 insertions, 2 deletions
diff --git a/extmod/vfs_posix.c b/extmod/vfs_posix.c
index 6df91a273..e29b47ccc 100644
--- a/extmod/vfs_posix.c
+++ b/extmod/vfs_posix.c
@@ -186,7 +186,14 @@ STATIC mp_obj_t vfs_posix_getcwd(mp_obj_t self_in) {
if (ret == NULL) {
mp_raise_OSError(errno);
}
- ret += self->root_len;
+ if (self->root_len > 0) {
+ ret += self->root_len - 1;
+ #ifdef _WIN32
+ if (*ret == '\\') {
+ *(char *)ret = '/';
+ }
+ #endif
+ }
return mp_obj_new_str(ret, strlen(ret));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(vfs_posix_getcwd_obj, vfs_posix_getcwd);
diff --git a/tests/extmod/vfs_posix_paths.py b/tests/extmod/vfs_posix_paths.py
index 8cdad7706..5806a3452 100644
--- a/tests/extmod/vfs_posix_paths.py
+++ b/tests/extmod/vfs_posix_paths.py
@@ -68,6 +68,25 @@ vfs.rmdir("/subdir")
# done with vfs, restore CWD
os.chdir(curdir)
+# some integration tests with a mounted VFS
+os.mount(os.VfsPosix(temp_dir_abs), "/mnt")
+os.mkdir("/mnt/dir")
+print('chdir("/mnt/dir"):', os.chdir("/mnt/dir"))
+print("getcwd():", os.getcwd())
+print('chdir("/mnt"):', os.chdir("/mnt"))
+print("getcwd():", os.getcwd())
+print('chdir("/"):', os.chdir("/"))
+print("getcwd():", os.getcwd())
+print('chdir("/mnt/dir"):', os.chdir("/mnt/dir"))
+print("getcwd():", os.getcwd())
+print('chdir(".."):', os.chdir(".."))
+print("getcwd():", os.getcwd())
+os.rmdir("/mnt/dir")
+os.umount("/mnt")
+
+# restore CWD
+os.chdir(curdir)
+
# rmdir
os.rmdir(temp_dir)
print(temp_dir in os.listdir())
diff --git a/tests/extmod/vfs_posix_paths.py.exp b/tests/extmod/vfs_posix_paths.py.exp
index 5828453c9..ecc13222a 100644
--- a/tests/extmod/vfs_posix_paths.py.exp
+++ b/tests/extmod/vfs_posix_paths.py.exp
@@ -2,7 +2,7 @@ listdir("/"): ['subdir']
listdir("."): ['subdir']
getcwd() in {"", "/"}: True
chdir("subdir"): None
-getcwd(): subdir
+getcwd(): /subdir
mkdir("two"): None
listdir("/"): ['subdir']
listdir("/subdir"): ['file.py', 'one', 'two']
@@ -10,4 +10,14 @@ listdir("."): ['file.py', 'one', 'two']
print('hello')
hello
<module 'file' from 'file.py'>
+chdir("/mnt/dir"): None
+getcwd(): /mnt/dir
+chdir("/mnt"): None
+getcwd(): /mnt
+chdir("/"): None
+getcwd(): /
+chdir("/mnt/dir"): None
+getcwd(): /mnt/dir
+chdir(".."): None
+getcwd(): /mnt
False