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-19/lib/clang/19 -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/Linux6.12_x86_64_gcc_glibc_PTH_64_DBG.OBJ/include -I ../../../dist/public/coreconf -I ../../../dist/private/coreconf -internal-isystem /usr/lib/llvm-19/lib/clang/19/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 -fskip-odr-check-in-gmf -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2025-01-06-222215-268153-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 | |
76 | char * |
77 | ino2name(ino_t ino, char *dir) |
78 | { |
79 | DIR *dp; |
80 | struct dirent *ep; |
81 | char *name; |
82 | |
83 | dp = opendir(".."); |
84 | if (!dp) |
85 | fail("cannot read parent directory"); |
86 | for (;;) { |
87 | if (!(ep = readdir(dp))) |
88 | fail("cannot find current directory"); |
89 | if (ep->d_ino == ino) |
90 | break; |
91 | } |
92 | name = xstrdup(ep->d_name); |
93 | closedir(dp); |
94 | return name; |
95 | } |
96 | |
97 | void * |
98 | xmalloc(size_t size) |
99 | { |
100 | void *p; |
101 | |
102 | if (size <= 0) |
103 | fail("attempted to allocate %u bytes", size); |
104 | p = malloc(size); |
105 | if (!p) |
106 | fail("cannot allocate %u bytes", size); |
107 | return p; |
108 | } |
109 | |
110 | char * |
111 | xstrdup(char *s) |
112 | { |
113 | if (!s || !s[0]) |
114 | fail("Null pointer or empty string passed to xstrdup()"); |
115 | return strcpy((char*)xmalloc(strlen(s) + 1), s); |
116 | } |
117 | |
118 | char * |
119 | xbasename(char *path) |
120 | { |
121 | char *cp; |
122 | |
123 | if (!path || !path[0]) |
124 | fail("Null pointer or empty string passed to xbasename()"); |
125 | while ((cp = strrchr(path, '/')) && cp[1] == '\0') |
126 | *cp = '\0'; |
127 | if (!cp) return path; |
128 | return cp + 1; |
129 | } |
130 | |
131 | void |
132 | xchdir(char *dir) |
133 | { |
134 | if (!dir || !dir[0]) |
135 | fail("Null pointer or empty string passed to xchdir()"); |
136 | if (chdir(dir) < 0) |
137 | fail("cannot change directory to %s", dir); |
138 | } |
139 | |
140 | int |
141 | relatepaths(char *from, char *to, char *outpath) |
142 | { |
143 | char *cp, *cp2; |
144 | int len; |
145 | char buf[NAME_MAX]; |
146 | |
147 | if (!from || *from != '/') |
148 | fail("relatepaths: from path does not start with /"); |
149 | if (!to || *to != '/') |
150 | fail("relatepaths: to path does not start with /"); |
151 | |
152 | for (cp = to, cp2 = from; *cp == *cp2; cp++, cp2++) |
153 | if (*cp == '\0') |
154 | break; |
155 | while (cp[-1] != '/') |
156 | cp--, cp2--; |
157 | if (cp - 1 == to) { |
158 | |
159 | len = strlen(strcpy(outpath, to)); |
160 | if (outpath[len] != '/') { |
161 | outpath[len++] = '/'; |
162 | outpath[len] = '\0'; |
163 | } |
164 | } else { |
165 | len = 0; |
166 | while ((cp2 = getcomponent(cp2, buf)) != 0) { |
167 | strcpy(outpath + len, "../"); |
168 | len += 3; |
169 | } |
170 | while ((cp = getcomponent(cp, buf)) != 0) { |
171 | snprintf(outpath + len, PATH_MAX - len, "%s/", buf); |
172 | len += strlen(outpath + len); |
173 | } |
174 | } |
175 | return len; |
176 | } |
177 | |
178 | void |
179 | reversepath(char *inpath, char *name, int len, char *outpath) |
180 | { |
181 | char *cp, *cp2; |
182 | char buf[NAME_MAX]; |
183 | struct stat sb; |
184 | |
185 | cp = strcpy(outpath + PATH_MAX - (len + 1), name); |
186 | cp2 = inpath; |
187 | while ((cp2 = getcomponent(cp2, buf)) != 0) { |
188 | if (strcmp(buf, ".") == 0) |
189 | continue; |
190 | if (strcmp(buf, "..") == 0) { |
191 | if (stat(".", &sb) < 0) |
192 | fail("cannot stat current directory"); |
193 | name = ino2name(sb.st_ino, ".."); |
194 | len = strlen(name); |
195 | cp -= len + 1; |
196 | strcpy(cp, name); |
197 | cp[len] = '/'; |
198 | free(name); |
199 | xchdir(".."); |
200 | } else { |
201 | cp -= 3; |
202 | memcpy(cp, "../", 3); |
203 | xchdir(buf); |
204 | } |
205 | } |
206 | strcpy(outpath, cp); |
207 | } |
208 | |
209 | void |
210 | diagnosePath(const char * path) |
211 | { |
212 | char * myPath; |
213 | char * slash; |
214 | int rv; |
215 | struct stat sb; |
216 | char buf[BUFSIZ]; |
217 | |
218 | if (!path || !path[0]) |
| |
219 | fail("Null pointer or empty string passed to mkdirs()"); |
220 | myPath = strdup(path); |
| 2 | | Null pointer passed to 1st parameter expecting 'nonnull' |
|
221 | if (!myPath) |
222 | fail("strdup() failed!"); |
223 | do { |
224 | rv = lstat(myPath, &sb); |
225 | if (rv < 0) { |
226 | perror(myPath); |
227 | } else if (S_ISLNK(sb.st_mode)) { |
228 | rv = readlink(myPath, buf, sizeof(buf) - 1); |
229 | if (rv < 0) { |
230 | perror("readlink"); |
231 | buf[0] = 0; |
232 | } else { |
233 | buf[rv] = 0; |
234 | } |
235 | fprintf(stderr, "%s is a link to %s\n", myPath, buf); |
236 | } else if (S_ISDIR(sb.st_mode)) { |
237 | fprintf(stderr, "%s is a directory\n", myPath); |
238 | rv = access(myPath, X_OK); |
239 | if (rv < 0) { |
240 | fprintf(stderr, "%s: no search permission\n", myPath); |
241 | } |
242 | } else { |
243 | fprintf(stderr, "%s is a file !?!\n", myPath); |
244 | rv = access(myPath, F_OK); |
245 | if (rv < 0) { |
246 | fprintf(stderr, "%s does not exist\n", myPath); |
247 | } |
248 | } |
249 | |
250 | |
251 | slash = strrchr(myPath, '/'); |
252 | if (!slash) |
253 | slash = strrchr(myPath, '\\'); |
254 | if (!slash) |
255 | slash = myPath; |
256 | *slash = 0; |
257 | } while (myPath[0]); |
258 | free(myPath); |
259 | } |