Skip to content

Commit d3ea28d

Browse files
robert-hhdpgeorge
authored andcommitted
extmod/vfs_lfsx: Normalize path name in chdir.
This change scans for '.', '..' and multiple '/' and normalizes the new path name. If the resulting path does not exist, an error is raised. Non-existing interim path elements are ignored if they are removed during normalization.
1 parent a5ea4b9 commit d3ea28d

File tree

3 files changed

+81
-0
lines changed

3 files changed

+81
-0
lines changed

extmod/vfs_lfsx.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,8 +283,45 @@ STATIC mp_obj_t MP_VFS_LFSx(chdir)(mp_obj_t self_in, mp_obj_t path_in) {
283283
}
284284

285285
// If not at root add trailing / to make it easy to build paths
286+
// and then normalise the path
286287
if (vstr_len(&self->cur_dir) != 1) {
287288
vstr_add_byte(&self->cur_dir, '/');
289+
290+
#define CWD_LEN (vstr_len(&self->cur_dir))
291+
size_t to = 1;
292+
size_t from = 1;
293+
char *cwd = vstr_str(&self->cur_dir);
294+
while (from < CWD_LEN) {
295+
for (; cwd[from] == '/' && from < CWD_LEN; ++from) {
296+
// Scan for the start
297+
}
298+
if (from > to) {
299+
// Found excessive slash chars, squeeze them out
300+
vstr_cut_out_bytes(&self->cur_dir, to, from - to);
301+
from = to;
302+
}
303+
for (; cwd[from] != '/' && from < CWD_LEN; ++from) {
304+
// Scan for the next /
305+
}
306+
if ((from - to) == 1 && cwd[to] == '.') {
307+
// './', ignore
308+
vstr_cut_out_bytes(&self->cur_dir, to, ++from - to);
309+
from = to;
310+
} else if ((from - to) == 2 && cwd[to] == '.' && cwd[to + 1] == '.') {
311+
// '../', skip back
312+
if (to > 1) {
313+
// Only skip back if not at the tip
314+
for (--to; to > 1 && cwd[to - 1] != '/'; --to) {
315+
// Skip back
316+
}
317+
}
318+
vstr_cut_out_bytes(&self->cur_dir, to, ++from - to);
319+
from = to;
320+
} else {
321+
// Normal element, keep it and just move the offset
322+
to = ++from;
323+
}
324+
}
288325
}
289326

290327
return mp_const_none;

tests/extmod/vfs_lfs.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ def test(bdev, vfs_class):
9898
print(list(vfs.ilistdir()))
9999

100100
# getcwd, chdir
101+
vfs.mkdir("/testdir2")
102+
vfs.mkdir("/testdir/subdir")
101103
print(vfs.getcwd())
102104
vfs.chdir("/testdir")
103105
print(vfs.getcwd())
@@ -111,7 +113,29 @@ def test(bdev, vfs_class):
111113
# chdir back to root and remove testdir
112114
vfs.chdir("/")
113115
print(vfs.getcwd())
116+
vfs.chdir("testdir")
117+
print(vfs.getcwd())
118+
vfs.chdir("..")
119+
print(vfs.getcwd())
120+
vfs.chdir("testdir/subdir")
121+
print(vfs.getcwd())
122+
vfs.chdir("../..")
123+
print(vfs.getcwd())
124+
vfs.chdir("/./testdir2")
125+
print(vfs.getcwd())
126+
vfs.chdir("../testdir")
127+
print(vfs.getcwd())
128+
vfs.chdir("../..")
129+
print(vfs.getcwd())
130+
vfs.chdir(".//testdir")
131+
print(vfs.getcwd())
132+
vfs.chdir("subdir/./")
133+
print(vfs.getcwd())
134+
vfs.chdir("/")
135+
print(vfs.getcwd())
136+
vfs.rmdir("testdir/subdir")
114137
vfs.rmdir("testdir")
138+
vfs.rmdir("testdir2")
115139

116140

117141
bdev = RAMBlockDevice(30)

tests/extmod/vfs_lfs.py.exp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,16 @@ write 3
2323
(32768, 0, 0, 0, 0, 0, 0, 0, 0, 0)
2424
(32768, 0, 0, 0, 0, 0, 0, 0, 0, 0)
2525
/
26+
/testdir
27+
/
28+
/testdir/subdir
29+
/
30+
/testdir2
31+
/testdir
32+
/
33+
/testdir
34+
/testdir/subdir
35+
/
2636
test <class 'VfsLfs2'>
2737
(1024, 1024, 30, 28, 28, 0, 0, 0, 0, 255)
2838
(1024, 1024, 30, 28, 28, 0, 0, 0, 0, 255)
@@ -48,3 +58,13 @@ write 3
4858
(32768, 0, 0, 0, 0, 0, 0, 0, 0, 0)
4959
(32768, 0, 0, 0, 0, 0, 0, 0, 0, 0)
5060
/
61+
/testdir
62+
/
63+
/testdir/subdir
64+
/
65+
/testdir2
66+
/testdir
67+
/
68+
/testdir
69+
/testdir/subdir
70+
/

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy