Browse Source

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>
pull/12137/head
Christian Walther 1 year ago
parent
commit
be28829ae8
  1. 9
      extmod/vfs_posix.c
  2. 19
      tests/extmod/vfs_posix_paths.py
  3. 12
      tests/extmod/vfs_posix_paths.py.exp

9
extmod/vfs_posix.c

@ -186,7 +186,14 @@ STATIC mp_obj_t vfs_posix_getcwd(mp_obj_t self_in) {
if (ret == NULL) { if (ret == NULL) {
mp_raise_OSError(errno); 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)); return mp_obj_new_str(ret, strlen(ret));
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(vfs_posix_getcwd_obj, vfs_posix_getcwd); STATIC MP_DEFINE_CONST_FUN_OBJ_1(vfs_posix_getcwd_obj, vfs_posix_getcwd);

19
tests/extmod/vfs_posix_paths.py

@ -68,6 +68,25 @@ vfs.rmdir("/subdir")
# done with vfs, restore CWD # done with vfs, restore CWD
os.chdir(curdir) 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 # rmdir
os.rmdir(temp_dir) os.rmdir(temp_dir)
print(temp_dir in os.listdir()) print(temp_dir in os.listdir())

12
tests/extmod/vfs_posix_paths.py.exp

@ -2,7 +2,7 @@ listdir("/"): ['subdir']
listdir("."): ['subdir'] listdir("."): ['subdir']
getcwd() in {"", "/"}: True getcwd() in {"", "/"}: True
chdir("subdir"): None chdir("subdir"): None
getcwd(): subdir getcwd(): /subdir
mkdir("two"): None mkdir("two"): None
listdir("/"): ['subdir'] listdir("/"): ['subdir']
listdir("/subdir"): ['file.py', 'one', 'two'] listdir("/subdir"): ['file.py', 'one', 'two']
@ -10,4 +10,14 @@ listdir("."): ['file.py', 'one', 'two']
print('hello') print('hello')
hello hello
<module 'file' from 'file.py'> <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 False

Loading…
Cancel
Save