1 /*
2  * Copyright (c) 2009-2022 Travis Geiselbrecht
3  *
4  * Use of this source code is governed by a MIT-style
5  * license that can be found in the LICENSE file or at
6  * https://opensource.org/licenses/MIT
7  */
8 #include <lib/fs.h>
9 #include <lk/err.h>
10 
11 #include <string.h>
12 #include <string.h>
13 #include <stdio.h>
14 #include <lib/unittest.h>
15 
16 // returns true if the input path passed through the path normalization
17 // routine matches the expected output.
test_normalize(const char * in,const char * out)18 static bool test_normalize(const char *in, const char *out) {
19     char path[1024];
20 
21     strlcpy(path, in, sizeof(path));
22     fs_normalize_path(path);
23     return !strcmp(path, out);
24 }
25 
test_path_normalize(void)26 static bool test_path_normalize(void) {
27     BEGIN_TEST;
28 
29     EXPECT_TRUE(test_normalize("/", ""), "");
30     EXPECT_TRUE(test_normalize("/test", "/test"), "");
31     EXPECT_TRUE(test_normalize("/test/", "/test"), "");
32     EXPECT_TRUE(test_normalize("test/", "test"), "");
33     EXPECT_TRUE(test_normalize("test", "test"), "");
34     EXPECT_TRUE(test_normalize("/test//", "/test"), "");
35     EXPECT_TRUE(test_normalize("/test/foo", "/test/foo"), "");
36     EXPECT_TRUE(test_normalize("/test/foo/", "/test/foo"), "");
37     EXPECT_TRUE(test_normalize("/test/foo/bar", "/test/foo/bar"), "");
38     EXPECT_TRUE(test_normalize("/test/foo/bar//", "/test/foo/bar"), "");
39     EXPECT_TRUE(test_normalize("/test//foo/bar//", "/test/foo/bar"), "");
40     EXPECT_TRUE(test_normalize("/test//./foo/bar//", "/test/foo/bar"), "");
41     EXPECT_TRUE(test_normalize("/test//./.foo/bar//", "/test/.foo/bar"), "");
42     EXPECT_TRUE(test_normalize("/test//./..foo/bar//", "/test/..foo/bar"), "");
43     EXPECT_TRUE(test_normalize("/test//./../foo/bar//", "/foo/bar"), "");
44     EXPECT_TRUE(test_normalize("/test/../foo", "/foo"), "");
45     EXPECT_TRUE(test_normalize("/test/bar/../foo", "/test/foo"), "");
46     EXPECT_TRUE(test_normalize("../foo", "foo"), "");
47     EXPECT_TRUE(test_normalize("../foo/", "foo"), "");
48     EXPECT_TRUE(test_normalize("/../foo", "foo"), "");
49     EXPECT_TRUE(test_normalize("/../foo/", "foo"), "");
50     EXPECT_TRUE(test_normalize("/../../foo", "foo"), "");
51     EXPECT_TRUE(test_normalize("/bleh/../../foo", "foo"), "");
52     EXPECT_TRUE(test_normalize("/bleh/bar/../../foo", "/foo"), "");
53     EXPECT_TRUE(test_normalize("/bleh/bar/../../foo/..", ""), "");
54     EXPECT_TRUE(test_normalize("/bleh/bar/../../foo/../meh", "/meh"), "");
55 
56     END_TEST;
57 }
58 
59 #define TEST_MNT "/test"
60 #define TEST_FILE TEST_MNT "/stdio_file_tests.txt"
61 
test_stdio_fs_teardown(void * ptr)62 static inline void test_stdio_fs_teardown(void *ptr) {
63     fs_remove_file(TEST_FILE);
64     fs_unmount(TEST_MNT);
65 }
66 
test_stdio_fs(void)67 static bool test_stdio_fs(void) {
68     __attribute__((cleanup(test_stdio_fs_teardown))) BEGIN_TEST;
69 
70     // Setup
71     const char *content = "Hello World\n";
72     const size_t content_len = strlen(content);
73     fs_mount(TEST_MNT, "memfs", NULL);
74 
75     // Tests
76     FILE *stream = fopen(TEST_FILE, "w");
77     ASSERT_NE(NULL, stream, "failed to open/create file " TEST_MNT);
78 
79     char buf[1024];
80     // test stdout fprintf, fputs
81     EXPECT_EQ(content_len, fprintf(stdout, "%s", content), "");
82     EXPECT_EQ(content_len, fputs(content, stdout), "");
83 
84     // test fwrite
85     EXPECT_EQ(content_len, fwrite(content, 1, content_len, stream), "");
86 
87     // test fread
88     ASSERT_EQ(NO_ERROR, fseek(stream, 0, SEEK_SET), "fseek failed");
89     EXPECT_EQ(content_len, fread(buf, 1, content_len, stream), "");
90     EXPECT_BYTES_EQ((const uint8_t *)content, (const uint8_t *)buf, content_len,
91                     "fread content mismatched");
92 
93     // testing fputs
94     ASSERT_EQ(NO_ERROR, fseek(stream, 0, SEEK_SET), "fseek failed");
95     EXPECT_EQ(content_len, fputs(content, stream), "");
96 
97     // testing fgets
98     ASSERT_EQ(NO_ERROR, fseek(stream, 0, SEEK_SET), "fseek failed");
99     ASSERT_NE(NULL, fgets(buf, content_len + 1, stream), "");
100     EXPECT_BYTES_EQ((const uint8_t *)content, (const uint8_t *)buf, content_len,
101                     "fgets content mismatched");
102 
103     END_TEST;
104 }
105 
106 BEGIN_TEST_CASE(fs_tests);
107 RUN_TEST(test_path_normalize);
108 RUN_TEST(test_stdio_fs);
109 END_TEST_CASE(fs_tests);
110