Skip to content

Commit 2fed36e

Browse files
committed
vfs: account for . and .. when resolving paths
1 parent 0754f2e commit 2fed36e

File tree

2 files changed

+53
-2
lines changed

2 files changed

+53
-2
lines changed

fs/vfs/src/include/vfs/vfs.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,4 @@ extern int mpCount;
2929

3030
int findFSServer(const char *);
3131
void registerMountpoint(MountCommand *);
32-
char *resolve(char *, char *, char *, const char *);
32+
char *resolve(char *, char *, char *, char *);

fs/vfs/src/resolve.c

+52-1
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,69 @@
1010
#include <vfs.h>
1111
#include <string.h>
1212

13+
/* clean(): helper function to clean up a path
14+
* params: path - path to be cleaned, the string will be directly modified
15+
* params: pointer to path
16+
*/
17+
18+
static char *clean(char *path) {
19+
if(strlen(path) == 1) return path; // root will never need to be cleaned
20+
21+
// first try to get rid of excessive slashes
22+
for(int i = 0; i < strlen(path); i++) {
23+
if((path[i] == '/') && (i < strlen(path)-1) && (path[i+1] == '/')) {
24+
memmove(&path[i], &path[i+1], strlen(&path[i])+1);
25+
continue;
26+
}
27+
}
28+
29+
// if the last character is a slash, remove it except for the root dir
30+
if(strlen(path) == 1) return path;
31+
while(path[strlen(path)-1] == '/') path[strlen(path)-1] = 0;
32+
33+
// parse '../' to reflect the parent directory
34+
for(int i = 0; i < strlen(path); i++) {
35+
if((path[i] == '.') && (path[i+1] == '.') && ((path[i+2] == '/') || (!path[i+2]))) {
36+
// find the parent
37+
int parent = i-2;
38+
for(; parent > 0; parent--) {
39+
if(path[parent] == '/') break;
40+
}
41+
42+
parent++;
43+
memmove(&path[parent], &path[i+3], strlen(&path[i+3])+1);
44+
}
45+
}
46+
47+
// remove './' because it refers to the self directory
48+
for(int i = 0; i < strlen(path); i++) {
49+
if((path[i] == '.') && ((path[i+1] == '/') || (!path[i+1]))) {
50+
memmove(&path[i], &path[i+2], strlen(&path[i+2])+1);
51+
continue;
52+
}
53+
}
54+
55+
// and finally remove any trailing slashes left while processing the string
56+
if(strlen(path) == 1) return path;
57+
while(path[strlen(path)-1] == '/') path[strlen(path)-1] = 0;
58+
59+
return path;
60+
}
61+
1362
/* resolve(): resolves a path relative to a mountpoint
1463
* params: buffer - destination to store the resolved path
1564
* params: type - buffer to store file system type
1665
* params: path - source absolute path
1766
* returns: pointer to resolved path on success, NULL on fail
1867
*/
1968

20-
char *resolve(char *buffer, char *type, char *source, const char *path) {
69+
char *resolve(char *buffer, char *type, char *source, char *path) {
2170
// iterate over the mountpoints to determine which device this path is
2271
// located on
2372
if(!mpCount) return NULL;
2473

74+
clean(path);
75+
2576
for(int i = 0; i < mpCount; i++) {
2677
size_t mplen = strlen(mps[i].path);
2778
if(!memcmp(path, mps[i].path, mplen)) {

0 commit comments

Comments
 (0)