1 #include "config_ast.h"  // IWYU pragma: keep
2 
3 #include <fcntl.h>
4 #include <limits.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <unistd.h>
8 
9 #include "ast.h"
10 #include "terror.h"
11 
12 const char *linkname = "foo";
13 const char *filename = "foobarbaz";
14 
tmain()15 tmain() {
16     UNUSED(argc);
17     UNUSED(argv);
18 
19     char path[PATH_MAX];
20     int fd;
21     char tmp_parent_realpath[PATH_MAX];
22 
23     fd = open(filename, O_CREAT, 0666);
24     if (fd == -1) terror("Failed to create test file");
25     close(fd);
26 
27     if (symlink(filename, linkname) < 0) {
28         terror("Failed to create symbolic link");
29     }
30 
31     if (!realpath("/tmp/..", tmp_parent_realpath)) terror("Failed to get real path of /tmp");
32 
33     // Try to resolve physical path from symbolic link
34     strcpy(path, linkname);
35     pathcanon(path, PATH_MAX, PATH_PHYSICAL);
36     if (strcmp(path, filename)) terror("Failed to resolve symbolic link");
37 
38     // Try to resolve physical path from broken symbolic link
39     unlink(linkname);
40     strcpy(path, linkname);
41     pathcanon(path, PATH_MAX, PATH_PHYSICAL | PATH_EXISTS);
42     if (strcmp(path, "")) terror("Resolving broken link should fail");
43 
44     // Try to resolve a single `.`
45     strcpy(path, "/tmp/.");
46     pathcanon(path, PATH_MAX, 0);
47     if (strcmp(path, "/tmp")) terror("Failed to resolve `.` in path");
48 
49     // Try to resolve parent directory
50     strcpy(path, "/tmp/..");
51     pathcanon(path, PATH_MAX, PATH_EXISTS);
52     if (strcmp(path, "/")) terror("Failed to resolve `..` in path");
53 
54     // Try to resolve non-existing path
55     strcpy(path, "/non_existing_path_after_root/..");
56     pathcanon(path, PATH_MAX, PATH_PHYSICAL);
57     if (strcmp(path, "/")) terror("Failed to resolve path if it contains non-existing directory");
58 
59     // Check non-existing path
60     strcpy(path, "/non_existing_path_after_root");
61     pathcanon(path, PATH_MAX, PATH_EXISTS);
62     if (strcmp(path, "")) terror("Resolving non-existing path should fail if `PATH_EXISTS` is set");
63 
64     // Try to resolve physical path and check if it exists
65     strcpy(path, "/tmp/..");
66     pathcanon(path, PATH_MAX, PATH_PHYSICAL | PATH_EXISTS);
67     if (strcmp(path, tmp_parent_realpath)) {
68         terror("Failed to resolve `..` if `PATH_PHYSICAL | PATH_EXISTS` is set");
69     }
70 
71     // Try to resolve physical path
72     strcpy(path, "/tmp/..");
73     pathcanon(path, PATH_MAX, PATH_PHYSICAL);
74     if (strcmp(path, tmp_parent_realpath)) {
75         terror("Failed to resolve `..` if `PATH_PHYSICAL` is set");
76     }
77 
78     // This should not verify if each component in path is accessible
79     strcpy(path, "/non_existing_path_after_root/..");
80     pathcanon(path, PATH_MAX, 0);
81     if (strcmp(path, "/")) terror("Failed to resolve non existing with empty flags");
82 
83     // `PATH_DOTDOT` verifies if each path is accessible
84     strcpy(path, "/non_existing_path_after_root/..");
85     pathcanon(path, PATH_MAX, PATH_DOTDOT);
86     if (strcmp(path, "")) terror("Resolving non-existing path should fail if `PATH_DOTDOT` is set");
87 
88     strcpy(path, "/tmp/..");
89     pathcanon(path, PATH_MAX, PATH_DOTDOT);
90     if (strcmp(path, "/")) terror("Resolving path fails if `PATH_DOTDOT` is set");
91 
92     texit(0);
93 }
94