clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name parse.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -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 -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D NO_X11 -D XP_PC -D HW_THREADS -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -std=gnu89 -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -stack-protector 2 -fgnuc-version=4.2.1 -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c /home/maarten/src/libreoffice/core/soltools/mkdepend/parse.c
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 | #include <ctype.h> |
31 | |
32 | #include "def.h" |
33 | static char *hash_lookup( char *symbol, struct symhash *symbols ); |
34 | static int gobble( struct filepointer *filep, struct inclist *file, |
35 | struct inclist *file_red, struct symhash *symbols ); |
36 | static int deftype ( char *line, struct filepointer *filep, struct inclist *file, |
37 | int parse_it, struct symhash *symbols); |
38 | static int zero_value(char const *exp, struct symhash *symbols); |
39 | |
40 | extern struct symhash *maininclist; |
41 | |
42 | int find_includes(struct filepointer *filep, struct inclist *file, struct inclist *file_red, int recursion, boolean failOK, struct IncludesCollection* incCollection, struct symhash *symbols) |
43 | { |
44 | char *line; |
45 | int type; |
46 | |
47 | while ((line = get_line(filep))) { |
| 1 | Loop condition is true. Entering loop body | |
|
48 | type = deftype(line, filep, file, TRUE, symbols); |
| |
| 13 | | Returning from 'deftype' | |
|
49 | switch(type) { |
| 14 | | Control jumps to 'case 16:' at line 66 | |
|
50 | case IF: |
51 | doif: |
52 | type = find_includes(filep, file, |
53 | file_red, recursion+1, failOK, incCollection, symbols); |
54 | while ((type == ELIF) || (type == ELIFFALSE) || |
55 | (type == ELIFGUESSFALSE)) |
56 | type = gobble(filep, file, file_red, symbols); |
57 | break; |
58 | case IFFALSE: |
59 | doiffalse: |
60 | type = gobble(filep, file, file_red, symbols); |
61 | if (type == ELIF) |
62 | goto doif; |
63 | else if ((type == ELIFFALSE) || (type == ELIFGUESSFALSE)) |
64 | goto doiffalse; |
65 | break; |
66 | case ELIFFALSE: |
67 | case ELIFGUESSFALSE: |
68 | case ELIF: |
69 | if (!recursion) |
| 15 | | Assuming 'recursion' is 0 | |
|
| |
70 | gobble(filep, file, file_red, symbols); |
71 | if (recursion) |
| |
72 | return type; |
73 | define(line, &symbols); |
| |
74 | break; |
75 | case ERROR: |
76 | warning("%s: %d: %s\n", file_red->i_file, |
77 | filep->f_line, line); |
78 | break; |
79 | |
80 | case -1: |
81 | warning("%s", file_red->i_file); |
82 | if (file_red != file) |
83 | warning1(" (reading %s)", file->i_file); |
84 | warning1(", line %d: unknown directive == \"%s\"\n", |
85 | filep->f_line, line); |
86 | break; |
87 | case -2: |
88 | warning("%s", file_red->i_file); |
89 | if (file_red != file) |
90 | warning1(" (reading %s)", file->i_file); |
91 | warning1(", line %d: incomplete include == \"%s\"\n", |
92 | filep->f_line, line); |
93 | break; |
94 | } |
95 | } |
96 | |
97 | return -1; |
98 | } |
99 | |
100 | int gobble(struct filepointer *filep, |
101 | struct inclist *file, |
102 | struct inclist *file_red, |
103 | struct symhash *symbols) |
104 | { |
105 | char *line; |
106 | int type; |
107 | |
108 | while ((line = get_line(filep))) { |
109 | type = deftype(line, filep, file, FALSE, symbols); |
110 | switch(type) { |
111 | case IF: |
112 | case IFFALSE: |
113 | type = gobble(filep, file, file_red, symbols); |
114 | while ((type == ELIF) || (type == ELIFFALSE) || |
115 | (type == ELIFGUESSFALSE)) |
116 | type = gobble(filep, file, file_red, symbols); |
117 | break; |
118 | case ERROR: |
119 | break; |
120 | case ELIF: |
121 | case ELIFFALSE: |
122 | case ELIFGUESSFALSE: |
123 | return type; |
124 | case -1: |
125 | warning("%s, line %d: unknown directive == \"%s\"\n", |
126 | file_red->i_file, filep->f_line, line); |
127 | break; |
128 | } |
129 | } |
130 | return -1; |
131 | } |
132 | |
133 | |
134 | |
135 | |
136 | int deftype (char *line, struct filepointer *filep, struct inclist * file, |
137 | int parse_it, struct symhash *symbols) |
138 | { |
139 | char *p; |
140 | char *directive, savechar; |
141 | int ret; |
142 | (void)file; |
143 | (void)filep; |
144 | |
145 | |
146 | |
147 | directive=line+1; |
148 | while (*directive == ' ' || *directive == '\t') |
| 3 | | Assuming the condition is false | |
|
| 4 | | Assuming the condition is false | |
|
| 5 | | Loop condition is false. Execution continues on line 151 | |
|
149 | directive++; |
150 | |
151 | p = directive; |
152 | while (*p >= 'a' && *p <= 'z') |
| 6 | | Assuming the condition is false | |
|
153 | p++; |
154 | savechar = *p; |
155 | *p = '\0'; |
156 | ret = match(directive, directives); |
157 | *p = savechar; |
158 | |
159 | |
160 | |
161 | |
162 | |
163 | |
164 | |
165 | if (ret == ELIF && !parse_it) |
| 7 | | Assuming 'ret' is not equal to ELIF | |
|
166 | { |
167 | while (*p == ' ' || *p == '\t') |
168 | p++; |
169 | |
170 | |
171 | |
172 | debug(0,("%s, line %d: #elif %s ", |
173 | file->i_file, filep->f_line, p)); |
174 | ret = zero_value(p, symbols); |
175 | if (ret != IF) |
176 | { |
177 | debug(0,("false...\n")); |
178 | if (ret == IFFALSE) |
179 | return ELIFFALSE; |
180 | else |
181 | return ELIFGUESSFALSE; |
182 | } |
183 | else |
184 | { |
185 | debug(0,("true...\n")); |
186 | return ELIF; |
187 | } |
188 | } |
189 | |
190 | if (ret < 0 || ! parse_it) |
| |
| |
191 | return ret; |
192 | |
193 | |
194 | |
195 | |
196 | while (*p == ' ' || *p == '\t') |
| 10 | | Loop condition is false. Execution continues on line 198 | |
|
197 | p++; |
198 | switch (ret) { |
| 11 | | 'Default' branch taken. Execution continues on line 216 | |
|
199 | case IF: |
200 | |
201 | |
202 | |
203 | ret = zero_value(p, symbols); |
204 | debug(0,("%s, line %d: %s #if %s\n", |
205 | file->i_file, filep->f_line, ret?"false":"true", p)); |
206 | break; |
207 | case ELIF: |
208 | case ERROR: |
209 | debug(0,("%s, line %d: #%s\n", |
210 | file->i_file, filep->f_line, directives[ret])); |
211 | |
212 | |
213 | |
214 | break; |
215 | } |
216 | return ret; |
| 12 | | Returning value (loaded from 'ret'), which participates in a condition later | |
|
217 | } |
218 | |
219 | |
220 | |
221 | |
222 | |
223 | static struct symhash *global_symbols = NULL; |
224 | |
225 | char * isdefined( char *symbol ) |
226 | { |
227 | return hash_lookup( symbol, global_symbols ); |
228 | } |
229 | |
230 | |
231 | |
232 | |
233 | int zero_value(char const *exp, struct symhash *symbols) |
234 | { |
235 | global_symbols = symbols; |
236 | if (cppsetup(exp)) |
237 | return IFFALSE; |
238 | else |
239 | return IF; |
240 | } |
241 | |
242 | void define( char *def, struct symhash **symbols ) |
243 | { |
244 | char *val; |
245 | |
246 | |
247 | val = def; |
248 | while (isalnum((unsigned char)*val) || *val == '_') |
| 19 | | Assuming the condition is false | |
|
| 20 | | Assuming the condition is false | |
|
| 21 | | Loop condition is false. Execution continues on line 250 | |
|
249 | val++; |
250 | if (*val) |
| 22 | | Assuming the condition is false | |
|
| |
251 | *val++ = '\0'; |
252 | while (*val == ' ' || *val == '\t') |
| 24 | | Loop condition is false. Execution continues on line 255 | |
|
253 | val++; |
254 | |
255 | if (!*val) |
| |
256 | val = "1"; |
257 | hash_define( def, val, symbols ); |
| |
258 | } |
259 | |
260 | static int hash( char *str ) |
261 | { |
262 | |
263 | unsigned int hashval = 0; |
264 | |
265 | for ( ; *str; str++ ) |
266 | { |
267 | hashval = ( hashval * SYMHASHSEED ) + ( *str ); |
268 | } |
269 | |
270 | return hashval & ( SYMHASHMEMBERS - 1 ); |
271 | } |
272 | |
273 | struct symhash *hash_copy( struct symhash *symbols ) |
274 | { |
275 | int i; |
276 | struct symhash *newsym; |
277 | if ( !symbols ) |
278 | return NULL; |
279 | |
280 | newsym = (struct symhash *) malloc( sizeof( struct symhash ) ); |
281 | |
282 | for ( i = 0; i < SYMHASHMEMBERS; ++i ) |
283 | { |
284 | if ( !symbols->s_pairs[ i ] ) |
285 | newsym->s_pairs[ i ] = NULL; |
286 | else |
287 | { |
288 | struct pair *it = symbols->s_pairs[ i ]; |
289 | struct pair *nw = newsym->s_pairs[ i ] = (struct pair*) malloc( sizeof( struct pair ) ); |
290 | nw->p_name = it->p_name; |
291 | nw->p_value = it->p_value; |
292 | nw->p_next = NULL; |
293 | |
294 | while ( it->p_next ) |
295 | { |
296 | nw->p_next = (struct pair*) malloc( sizeof( struct pair ) ); |
297 | it = it->p_next; |
298 | nw = nw->p_next; |
299 | nw->p_name = it->p_name; |
300 | nw->p_value = it->p_value; |
301 | nw->p_next = NULL; |
302 | } |
303 | } |
304 | } |
305 | return newsym; |
306 | } |
307 | |
308 | void hash_free( struct symhash *symbols ) |
309 | { |
310 | int i; |
311 | |
312 | if ( !symbols ) |
313 | return; |
314 | |
315 | for ( i = 0; i < SYMHASHMEMBERS; ++i ) |
316 | { |
317 | struct pair *it = symbols->s_pairs[ i ]; |
318 | struct pair *next; |
319 | while ( it ) |
320 | { |
321 | next = it->p_next; |
322 | free( it ); |
323 | it = next; |
324 | } |
325 | } |
326 | free( symbols->s_pairs ); |
327 | } |
328 | |
329 | void hash_define( char *name, char const *val, struct symhash **symbols ) |
330 | { |
331 | int hashval; |
332 | struct pair *it; |
333 | |
334 | if ( !symbols ) |
| |
335 | return; |
336 | |
337 | |
338 | if ( *symbols == NULL ) |
| 28 | | Assuming the condition is true | |
|
| |
339 | { |
340 | int i; |
341 | |
342 | *symbols = (struct symhash *) malloc( sizeof( struct symhash ) ); |
| 30 | | Value assigned to 'symbols' | |
|
343 | if ( *symbols == NULL ) |
| 31 | | Assuming the condition is true | |
|
| |
344 | fatalerr( "malloc()/realloc() failure in insert_defn()\n" ); |
345 | |
346 | for ( i = 0; i < SYMHASHMEMBERS; ++i ) |
| 33 | | Loop condition is true. Entering loop body | |
|
347 | (*symbols)->s_pairs[i] = NULL; |
| 34 | | Array access (via field 's_pairs') results in a null pointer dereference |
|
348 | } |
349 | |
350 | hashval = hash( name ); |
351 | it = (*symbols)->s_pairs[ hashval ]; |
352 | |
353 | |
354 | if ( it == NULL ) |
355 | { |
356 | it = (*symbols)->s_pairs[ hashval ] = (struct pair*) malloc( sizeof( struct pair ) ); |
357 | it->p_name = copy( name ); |
358 | it->p_value = copy( val ); |
359 | it->p_next = NULL; |
360 | } |
361 | else if ( strcmp( it->p_name, name ) == 0 ) |
362 | { |
363 | it->p_value = copy( val ); |
364 | } |
365 | else |
366 | { |
367 | while ( it->p_next && ( strcmp( it->p_next->p_name, name ) != 0 ) ) |
368 | { |
369 | it = it->p_next; |
370 | } |
371 | if ( it->p_next ) |
372 | it->p_next->p_name = copy( name ); |
373 | else |
374 | { |
375 | it->p_next = (struct pair*) malloc( sizeof( struct pair ) ); |
376 | it->p_next->p_name = copy( name ); |
377 | it->p_next->p_value = copy( val ); |
378 | it->p_next->p_next = NULL; |
379 | } |
380 | } |
381 | } |
382 | |
383 | char *hash_lookup( char *symbol, struct symhash *symbols ) |
384 | { |
385 | struct pair *it; |
386 | |
387 | if ( !symbols ) |
388 | return NULL; |
389 | |
390 | it = symbols->s_pairs[ hash( symbol ) ]; |
391 | |
392 | while ( it && ( strcmp( it->p_name, symbol ) != 0 ) ) |
393 | { |
394 | it = it->p_next; |
395 | } |
396 | if ( it ) |
397 | return it->p_value; |
398 | |
399 | return NULL; |
400 | } |
401 | |
402 | |