clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name pathsub.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/coreconf/nsinstall -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/coreconf/nsinstall -resource-dir /usr/lib/llvm-18/lib/clang/18 -D HAVE_STRERROR -D LINUX -D linux -D XP_UNIX -D XP_UNIX -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D NSS_DISABLE_SSE3 -D NSS_NO_INIT_SUPPORT -D USE_UTIL_DIRECTLY -D NO_NSPR_10_SUPPORT -D SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES -I ../../../dist/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/include -I ../../../dist/public/coreconf -I ../../../dist/private/coreconf -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -std=c99 -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-05-18-082241-28900-1 -x c pathsub.c
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | #if defined(FREEBSD) || defined(BSDI) || defined(DARWIN) |
9 | #include <sys/types.h> |
10 | #endif /* FREEBSD */ |
11 | #include <dirent.h> |
12 | #include <errno.h> |
13 | #include <stdarg.h> |
14 | #include <stdio.h> |
15 | #include <stdlib.h> |
16 | #include <string.h> |
17 | #include <unistd.h> |
18 | #include <sys/types.h> |
19 | #include <sys/stat.h> |
20 | #include "pathsub.h" |
21 | #ifdef USE_REENTRANT_LIBC |
22 | #include "libc_r.h" |
23 | #endif /* USE_REENTRANT_LIBC */ |
24 | |
25 | char *program; |
26 | |
27 | void |
28 | fail(char *format, ...) |
29 | { |
30 | int error; |
31 | va_list ap; |
32 | |
33 | #ifdef USE_REENTRANT_LIBC |
34 | R_STRERROR_INIT_R(); |
35 | #endif |
36 | |
37 | error = errno; |
38 | fprintf(stderr, "%s: ", program); |
39 | va_start(ap, format); |
40 | vfprintf(stderr, format, ap); |
41 | va_end(ap); |
42 | if (error) { |
43 | |
44 | #ifdef USE_REENTRANT_LIBC |
45 | R_STRERROR_R(errno); |
46 | fprintf(stderr, ": %s", r_strerror_r); |
47 | #else |
48 | fprintf(stderr, ": %s", strerror(errno)); |
49 | #endif |
50 | } |
51 | |
52 | putc('\n', stderr); |
53 | abort(); |
54 | exit(1); |
55 | } |
56 | |
57 | char * |
58 | getcomponent(char *path, char *name) |
59 | { |
60 | if (*path == '\0') |
61 | return 0; |
62 | if (*path == '/') { |
63 | *name++ = '/'; |
64 | } else { |
65 | do { |
66 | *name++ = *path++; |
67 | } while (*path != '/' && *path != '\0'); |
68 | } |
69 | *name = '\0'; |
70 | while (*path == '/') |
71 | path++; |
72 | return path; |
73 | } |
74 | |
75 | #ifdef UNIXWARE |
76 | |
77 | struct dirent * readdir(DIR *d) |
78 | { |
79 | static struct dirent *buf = NULL; |
80 | #define MAX_PATH_LEN 1024 |
81 | |
82 | if (buf == NULL) |
83 | buf = (struct dirent *)xmalloc(sizeof(struct dirent) + MAX_PATH_LEN) ; |
84 | return readdir_r(d, buf); |
85 | } |
86 | #endif |
87 | |
88 | |
89 | char * |
90 | ino2name(ino_t ino, char *dir) |
91 | { |
92 | DIR *dp; |
93 | struct dirent *ep; |
94 | char *name; |
95 | |
96 | dp = opendir(".."); |
97 | if (!dp) |
98 | fail("cannot read parent directory"); |
99 | for (;;) { |
100 | if (!(ep = readdir(dp))) |
101 | fail("cannot find current directory"); |
102 | if (ep->d_ino == ino) |
103 | break; |
104 | } |
105 | name = xstrdup(ep->d_name); |
106 | closedir(dp); |
107 | return name; |
108 | } |
109 | |
110 | void * |
111 | xmalloc(size_t size) |
112 | { |
113 | void *p; |
114 | |
115 | if (size <= 0) |
116 | fail("attempted to allocate %u bytes", size); |
117 | p = malloc(size); |
118 | if (!p) |
119 | fail("cannot allocate %u bytes", size); |
120 | return p; |
121 | } |
122 | |
123 | char * |
124 | xstrdup(char *s) |
125 | { |
126 | if (!s || !s[0]) |
127 | fail("Null pointer or empty string passed to xstrdup()"); |
128 | return strcpy((char*)xmalloc(strlen(s) + 1), s); |
129 | } |
130 | |
131 | char * |
132 | xbasename(char *path) |
133 | { |
134 | char *cp; |
135 | |
136 | if (!path || !path[0]) |
137 | fail("Null pointer or empty string passed to xbasename()"); |
138 | while ((cp = strrchr(path, '/')) && cp[1] == '\0') |
139 | *cp = '\0'; |
140 | if (!cp) return path; |
141 | return cp + 1; |
142 | } |
143 | |
144 | void |
145 | xchdir(char *dir) |
146 | { |
147 | if (!dir || !dir[0]) |
148 | fail("Null pointer or empty string passed to xchdir()"); |
149 | if (chdir(dir) < 0) |
150 | fail("cannot change directory to %s", dir); |
151 | } |
152 | |
153 | int |
154 | relatepaths(char *from, char *to, char *outpath) |
155 | { |
156 | char *cp, *cp2; |
157 | int len; |
158 | char buf[NAME_MAX]; |
159 | |
160 | if (!from || *from != '/') |
| |
161 | fail("relatepaths: from path does not start with /"); |
162 | if (!to || *to != '/') |
| 2 | | Assuming 'to' is non-null | |
|
| 3 | | Assuming the condition is false | |
|
| |
163 | fail("relatepaths: to path does not start with /"); |
164 | |
165 | for (cp = to, cp2 = from; *cp == *cp2; cp++, cp2++) |
| 5 | | Null pointer value stored to 'cp2' | |
|
| 6 | | Dereference of null pointer (loaded from variable 'cp2') |
|
166 | if (*cp == '\0') |
167 | break; |
168 | while (cp[-1] != '/') |
169 | cp--, cp2--; |
170 | if (cp - 1 == to) { |
171 | |
172 | len = strlen(strcpy(outpath, to)); |
173 | if (outpath[len] != '/') { |
174 | outpath[len++] = '/'; |
175 | outpath[len] = '\0'; |
176 | } |
177 | } else { |
178 | len = 0; |
179 | while ((cp2 = getcomponent(cp2, buf)) != 0) { |
180 | strcpy(outpath + len, "../"); |
181 | len += 3; |
182 | } |
183 | while ((cp = getcomponent(cp, buf)) != 0) { |
184 | snprintf(outpath + len, PATH_MAX - len, "%s/", buf); |
185 | len += strlen(outpath + len); |
186 | } |
187 | } |
188 | return len; |
189 | } |
190 | |
191 | void |
192 | reversepath(char *inpath, char *name, int len, char *outpath) |
193 | { |
194 | char *cp, *cp2; |
195 | char buf[NAME_MAX]; |
196 | struct stat sb; |
197 | |
198 | cp = strcpy(outpath + PATH_MAX - (len + 1), name); |
199 | cp2 = inpath; |
200 | while ((cp2 = getcomponent(cp2, buf)) != 0) { |
201 | if (strcmp(buf, ".") == 0) |
202 | continue; |
203 | if (strcmp(buf, "..") == 0) { |
204 | if (stat(".", &sb) < 0) |
205 | fail("cannot stat current directory"); |
206 | name = ino2name(sb.st_ino, ".."); |
207 | len = strlen(name); |
208 | cp -= len + 1; |
209 | strcpy(cp, name); |
210 | cp[len] = '/'; |
211 | free(name); |
212 | xchdir(".."); |
213 | } else { |
214 | cp -= 3; |
215 | memcpy(cp, "../", 3); |
216 | xchdir(buf); |
217 | } |
218 | } |
219 | strcpy(outpath, cp); |
220 | } |
221 | |
222 | void |
223 | diagnosePath(const char * path) |
224 | { |
225 | char * myPath; |
226 | char * slash; |
227 | int rv; |
228 | struct stat sb; |
229 | char buf[BUFSIZ]; |
230 | |
231 | if (!path || !path[0]) |
232 | fail("Null pointer or empty string passed to mkdirs()"); |
233 | myPath = strdup(path); |
234 | if (!myPath) |
235 | fail("strdup() failed!"); |
236 | do { |
237 | rv = lstat(myPath, &sb); |
238 | if (rv < 0) { |
239 | perror(myPath); |
240 | } else if (S_ISLNK(sb.st_mode)) { |
241 | rv = readlink(myPath, buf, sizeof(buf) - 1); |
242 | if (rv < 0) { |
243 | perror("readlink"); |
244 | buf[0] = 0; |
245 | } else { |
246 | buf[rv] = 0; |
247 | } |
248 | fprintf(stderr, "%s is a link to %s\n", myPath, buf); |
249 | } else if (S_ISDIR(sb.st_mode)) { |
250 | fprintf(stderr, "%s is a directory\n", myPath); |
251 | rv = access(myPath, X_OK); |
252 | if (rv < 0) { |
253 | fprintf(stderr, "%s: no search permission\n", myPath); |
254 | } |
255 | } else { |
256 | fprintf(stderr, "%s is a file !?!\n", myPath); |
257 | rv = access(myPath, F_OK); |
258 | if (rv < 0) { |
259 | fprintf(stderr, "%s does not exist\n", myPath); |
260 | } |
261 | } |
262 | |
263 | |
264 | slash = strrchr(myPath, '/'); |
265 | if (!slash) |
266 | slash = strrchr(myPath, '\\'); |
267 | if (!slash) |
268 | slash = myPath; |
269 | *slash = 0; |
270 | } while (myPath[0]); |
271 | free(myPath); |
272 | } |