Line | Source | Count |
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 | #include "includes.h" | - |
33 | | - |
34 | #if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) | - |
35 | | - |
36 | #include <sys/types.h> | - |
37 | #include <sys/param.h> | - |
38 | #include <sys/stat.h> | - |
39 | | - |
40 | #include <errno.h> | - |
41 | #include <stdlib.h> | - |
42 | #include <stddef.h> | - |
43 | #include <string.h> | - |
44 | #include <unistd.h> | - |
45 | #include <limits.h> | - |
46 | | - |
47 | #ifndef SYMLOOP_MAX | - |
48 | # define SYMLOOP_MAX 32 | - |
49 | #endif | - |
50 | | - |
51 | | - |
52 | | - |
53 | | - |
54 | | - |
55 | | - |
56 | | - |
57 | | - |
58 | | - |
59 | | - |
60 | char * | - |
61 | realpath(const char *path, char *resolved) | - |
62 | { | - |
63 | struct stat sb; | - |
64 | char *p, *q, *s; | - |
65 | size_t left_len, resolved_len; | - |
66 | unsigned symlinks; | - |
67 | int serrno, slen, mem_allocated; | - |
68 | char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX]; | - |
69 | | - |
70 | if (path[0] == '\0') {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
71 | errno = ENOENT; | - |
72 | return (NULL); never executed: return ( ((void *)0) ); | 0 |
73 | } | - |
74 | | - |
75 | serrno = errno; | - |
76 | | - |
77 | if (resolved == NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
78 | resolved = malloc(PATH_MAX); | - |
79 | if (resolved == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
80 | return (NULL); never executed: return ( ((void *)0) ); | 0 |
81 | mem_allocated = 1; | - |
82 | } else never executed: end of block | 0 |
83 | mem_allocated = 0; never executed: mem_allocated = 0; | 0 |
84 | | - |
85 | symlinks = 0; | - |
86 | if (path[0] == '/') {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
87 | resolved[0] = '/'; | - |
88 | resolved[1] = '\0'; | - |
89 | if (path[1] == '\0')TRUE | never evaluated | FALSE | never evaluated |
| 0 |
90 | return (resolved); never executed: return (resolved); | 0 |
91 | resolved_len = 1; | - |
92 | left_len = strlcpy(left, path + 1, sizeof(left)); | - |
93 | } else { never executed: end of block | 0 |
94 | if (getcwd(resolved, PATH_MAX) == NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
95 | if (mem_allocated)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
96 | free(resolved); never executed: free(resolved); | 0 |
97 | else | - |
98 | strlcpy(resolved, ".", PATH_MAX); never executed: strlcpy(resolved, ".", 4096 ); | 0 |
99 | return (NULL); never executed: return ( ((void *)0) ); | 0 |
100 | } | - |
101 | resolved_len = strlen(resolved); | - |
102 | left_len = strlcpy(left, path, sizeof(left)); | - |
103 | } never executed: end of block | 0 |
104 | if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
105 | errno = ENAMETOOLONG; | - |
106 | goto err; never executed: goto err; | 0 |
107 | } | - |
108 | | - |
109 | | - |
110 | | - |
111 | | - |
112 | while (left_len != 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
113 | | - |
114 | | - |
115 | | - |
116 | | - |
117 | p = strchr(left, '/');TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
118 | s = p ? p : left + left_len;TRUE | never evaluated | FALSE | never evaluated |
| 0 |
119 | if (s - left >= (ptrdiff_t)sizeof(next_token)) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
120 | errno = ENAMETOOLONG; | - |
121 | goto err; never executed: goto err; | 0 |
122 | } | - |
123 | memcpy(next_token, left, s - left); | - |
124 | next_token[s - left] = '\0'; | - |
125 | left_len -= s - left; | - |
126 | if (p != NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
127 | memmove(left, s + 1, left_len + 1); never executed: memmove(left, s + 1, left_len + 1); | 0 |
128 | if (resolved[resolved_len - 1] != '/') {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
129 | if (resolved_len + 1 >= PATH_MAX) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
130 | errno = ENAMETOOLONG; | - |
131 | goto err; never executed: goto err; | 0 |
132 | } | - |
133 | resolved[resolved_len++] = '/'; | - |
134 | resolved[resolved_len] = '\0'; | - |
135 | } never executed: end of block | 0 |
136 | if (next_token[0] == '\0')TRUE | never evaluated | FALSE | never evaluated |
| 0 |
137 | continue; never executed: continue; | 0 |
138 | else if (strcmp(next_token, ".") == 0) never executed: __result = (((const unsigned char *) (const char *) ( next_token ))[3] - __s2[3]); never executed: end of block never executed: end of block never executed: __result = (((const unsigned char *) (const char *) ( "." ))[3] - __s2[3]); never executed: end of block never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
139 | continue; never executed: continue; | 0 |
140 | else if (strcmp(next_token, "..") == 0) { never executed: __result = (((const unsigned char *) (const char *) ( next_token ))[3] - __s2[3]); never executed: end of block never executed: end of block never executed: __result = (((const unsigned char *) (const char *) ( ".." ))[3] - __s2[3]); never executed: end of block never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
141 | | - |
142 | | - |
143 | | - |
144 | | - |
145 | if (resolved_len > 1) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
146 | resolved[resolved_len - 1] = '\0'; | - |
147 | q = strrchr(resolved, '/') + 1; | - |
148 | *q = '\0'; | - |
149 | resolved_len = q - resolved; | - |
150 | } never executed: end of block | 0 |
151 | continue; never executed: continue; | 0 |
152 | } | - |
153 | | - |
154 | | - |
155 | | - |
156 | | - |
157 | | - |
158 | | - |
159 | resolved_len = strlcat(resolved, next_token, PATH_MAX); | - |
160 | if (resolved_len >= PATH_MAX) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
161 | errno = ENAMETOOLONG; | - |
162 | goto err; never executed: goto err; | 0 |
163 | } | - |
164 | if (lstat(resolved, &sb) != 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
165 | if (errno == ENOENT && p == NULL) {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
166 | errno = serrno; | - |
167 | return (resolved); never executed: return (resolved); | 0 |
168 | } | - |
169 | goto err; never executed: goto err; | 0 |
170 | } | - |
171 | if (S_ISLNK(sb.st_mode)) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
172 | if (symlinks++ > SYMLOOP_MAX) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
173 | errno = ELOOP; | - |
174 | goto err; never executed: goto err; | 0 |
175 | } | - |
176 | slen = readlink(resolved, symlink, sizeof(symlink) - 1); | - |
177 | if (slen < 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
178 | goto err; never executed: goto err; | 0 |
179 | symlink[slen] = '\0'; | - |
180 | if (symlink[0] == '/') {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
181 | resolved[1] = 0; | - |
182 | resolved_len = 1; | - |
183 | } else if (resolved_len > 1) { never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
| 0 |
184 | | - |
185 | resolved[resolved_len - 1] = '\0'; | - |
186 | q = strrchr(resolved, '/') + 1; | - |
187 | *q = '\0'; | - |
188 | resolved_len = q - resolved; | - |
189 | } never executed: end of block | 0 |
190 | | - |
191 | | - |
192 | | - |
193 | | - |
194 | | - |
195 | | - |
196 | if (p != NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
197 | if (symlink[slen - 1] != '/') {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
198 | if (slen + 1 >=TRUE | never evaluated | FALSE | never evaluated |
| 0 |
199 | (ptrdiff_t)sizeof(symlink)) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
200 | errno = ENAMETOOLONG; | - |
201 | goto err; never executed: goto err; | 0 |
202 | } | - |
203 | symlink[slen] = '/'; | - |
204 | symlink[slen + 1] = 0; | - |
205 | } never executed: end of block | 0 |
206 | left_len = strlcat(symlink, left, sizeof(symlink)); | - |
207 | if (left_len >= sizeof(symlink)) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
208 | errno = ENAMETOOLONG; | - |
209 | goto err; never executed: goto err; | 0 |
210 | } | - |
211 | } never executed: end of block | 0 |
212 | left_len = strlcpy(left, symlink, sizeof(left)); | - |
213 | } never executed: end of block | 0 |
214 | } never executed: end of block | 0 |
215 | | - |
216 | | - |
217 | | - |
218 | | - |
219 | | - |
220 | if (resolved_len > 1 && resolved[resolved_len - 1] == '/')TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
221 | resolved[resolved_len - 1] = '\0'; never executed: resolved[resolved_len - 1] = '\0'; | 0 |
222 | return (resolved); never executed: return (resolved); | 0 |
223 | | - |
224 | err: | - |
225 | if (mem_allocated)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
226 | free(resolved); never executed: free(resolved); | 0 |
227 | return (NULL); never executed: return ( ((void *)0) ); | 0 |
228 | } | - |
229 | #endif /* !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) */ | - |
| | |