1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
#include "../tests.h"
#include <camellia/path.h>
#include <string.h>
#include <camellia/compat.h>
#include <camellia/fs/misc.h>
static void test_path_simplify(void) {
const char *testcases[][2] = {
{"/", "/"},
{"/.", "/"},
{"//", "/"},
{"/asdf", "/asdf"},
{"/asdf/", "/asdf/"},
{"/asdf//", "/asdf/"},
{"/asdf/./", "/asdf/"},
{"/a/./b", "/a/b"},
{"/a/./b/", "/a/b/"},
// some slightly less easy cases
{"/asdf/..", "/"},
{"/asdf/../", "/"},
{"/asdf/.", "/asdf/"},
{"/asdf//.", "/asdf/"},
{"/foo/bar/..", "/foo/"},
{"/foo/bar/../baz", "/foo/baz"},
{"/foo/bar/../baz/", "/foo/baz/"},
{"/foo/bar/xyz/..", "/foo/bar/"},
{"/foo/bar/xyz/../", "/foo/bar/"},
// going under the root or close to it
{"/..", NULL},
{"/../asdf", NULL},
{"/../asdf/", NULL},
{"/./a/../..", NULL},
{"/a/a/../..", "/"},
{"/a/../a/..", "/"},
{"/a/../../a", NULL},
{"/../a/../a", NULL},
{"/../../a/a", NULL},
{"/////../..", NULL},
{"//a//../..", NULL},
// relative paths aren't allowed
{"relative", NULL},
{"some/stuff", NULL},
{"./stuff", NULL},
{"../stuff", NULL},
{"", NULL},
};
char buf[256];
for (size_t i = 0; i < sizeof(testcases) / sizeof(testcases[0]); i++) {
const char *input = testcases[i][0];
const char *expected = testcases[i][1];
int len = path_simplify(input, buf, strlen(input));
if (expected == NULL) {
test(len == 0);
} else {
// TODO an argument for printing info on test failure
test(len == (int)strlen(expected) && !memcmp(expected, buf, len));
}
}
}
static void mount_resolve_drv(const char *path) {
if (mount_at(path) != 0) return;
struct ufs_request res;
char buf[512];
while (!c0_fs_wait(buf, sizeof(buf), &res)) {
// TODO does the first argument of c0_fs_respond need to be non-const?
c0_fs_respond((void*)path, strlen(path), 0);
}
exit(1);
}
static void test_mount_resolve(void) {
const char *testcases[][2] = {
{"/", "/"},
{"/test", "/"},
{"/dir", "/dir"},
{"/dir/..", "/"},
{"/dir/../dir", "/dir"},
{"/dirry", "/"},
{"/dir/", "/dir"},
{"/dir/shadowed", "/dir"},
{"/dir/shadowed/", "/dir"},
};
mount_resolve_drv("/");
mount_resolve_drv("/dir/shadowed");
mount_resolve_drv("/dir");
char buf[16];
for (size_t i = 0; i < sizeof(testcases) / sizeof(testcases[0]); i++) {
const char *input = testcases[i][0];
const char *expected = testcases[i][1];
hid_t h = _sys_open(input, strlen(input), 0);
test(h >= 0);
int len = _sys_read(h, buf, sizeof buf, 0);
test(len == (int)strlen(expected) && !memcmp(expected, buf, len));
_sys_close(h);
}
}
void r_k_path(void) {
run_test(test_path_simplify);
run_test(test_mount_resolve);
}
|