1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <limits.h>
6 #include <stdio.h>
7 #include <string.h>
8 #include <unistd.h>
9 #include <lib/fdio/private.h>
10 
11 #include <unittest/unittest.h>
12 
13 #define TEST_CLEAN(p1, p2, dir)                                               \
14     {                                                                         \
15         const char in[] = (p1);                                               \
16         const char out_gold[] = (p2);                                         \
17         size_t outlen;                                                        \
18         bool is_dir;                                                          \
19         EXPECT_EQ(__fdio_cleanpath(in, out, &outlen, &is_dir), ZX_OK, ""); \
20         EXPECT_EQ(is_dir, dir, "");                                           \
21         char msg[PATH_MAX * 3 + 128];                                         \
22         sprintf(msg, "[%s] --> [%s], expected [%s]", in, out, out_gold);      \
23         EXPECT_EQ(strcmp(out, out_gold), 0, msg);                             \
24     }
25 
26 
basic_test(void)27 bool basic_test(void) {
28     BEGIN_TEST;
29     char out[PATH_MAX];
30     TEST_CLEAN("/foo", "/foo", false);
31     TEST_CLEAN("/foo/bar/baz", "/foo/bar/baz", false);
32     END_TEST;
33 }
34 
dotdot_test(void)35 bool dotdot_test(void) {
36     BEGIN_TEST;
37     char out[PATH_MAX];
38     TEST_CLEAN("/foo/bar/../baz", "/foo/baz", false);
39     TEST_CLEAN("/foo/bar/../baz/..", "/foo", true);
40     TEST_CLEAN("/foo/bar/../baz/../", "/foo", true);
41     TEST_CLEAN("../../..", "../../..", true);
42     TEST_CLEAN("/../../..", "/", true);
43     TEST_CLEAN("/./././../foo", "/foo", false);
44     END_TEST;
45 }
46 
dot_test(void)47 bool dot_test(void) {
48     BEGIN_TEST;
49     char out[PATH_MAX];
50     TEST_CLEAN("/.", "/", true);
51     TEST_CLEAN("/./././.", "/", true);
52     TEST_CLEAN("/././././", "/", true);
53     TEST_CLEAN("/foobar/././.", "/foobar", true);
54     TEST_CLEAN("/foobar/./../././././///.", "/", true);
55     TEST_CLEAN(".", ".", true);
56     TEST_CLEAN("./.", ".", true);
57     TEST_CLEAN("./././../foo", "../foo", false);
58     END_TEST;
59 }
60 
minimal_test(void)61 bool minimal_test(void) {
62     BEGIN_TEST;
63     char out[PATH_MAX];
64     TEST_CLEAN("", ".", true);
65     TEST_CLEAN("/", "/", true);
66     TEST_CLEAN("//", "/", true);
67     TEST_CLEAN("///", "/", true);
68     TEST_CLEAN("a", "a", false);
69     TEST_CLEAN("a/", "a", true);
70     TEST_CLEAN("a/.", "a", true);
71     TEST_CLEAN("a/..", ".", true);
72     TEST_CLEAN("a/../.", ".", true);
73     TEST_CLEAN("/a/../.", "/", true);
74     TEST_CLEAN(".", ".", true);
75     TEST_CLEAN("..", "..", true);
76     TEST_CLEAN("...", "...", false);
77     END_TEST;
78 }
79 
80 BEGIN_TEST_CASE(fdio_path_canonicalization_test)
81 RUN_TEST(basic_test);
82 RUN_TEST(dotdot_test);
83 RUN_TEST(dot_test);
84 RUN_TEST(minimal_test);
85 END_TEST_CASE(fdio_path_canonicalization_test)
86