clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name hack.read.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 -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/games/hack/obj -resource-dir /usr/local/llvm16/lib/clang/16 -I . -internal-isystem /usr/local/llvm16/lib/clang/16/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/games/hack/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fno-jump-tables -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/scan/2024-01-11-140451-98009-1 -x c /usr/src/games/hack/hack.read.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 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | #include <stdlib.h> |
65 | |
66 | #include "hack.h" |
67 | |
68 | static boolean monstersym(char); |
69 | |
70 | int |
71 | doread(void) |
72 | { |
73 | struct obj *scroll; |
74 | boolean confused = (Confusion != 0); |
| 1 | Assuming field 'p_flgs' is not equal to 0 | |
|
75 | boolean known = FALSE; |
76 | |
77 | scroll = getobj("?", "read"); |
78 | if(!scroll) return(0); |
| 2 | | Assuming 'scroll' is non-null | |
|
79 | if(!scroll->dknown && Blind) { |
| 3 | | Assuming field 'dknown' is not equal to 0 | |
|
80 | pline("Being blind, you cannot read the formula on the scroll."); |
81 | return(0); |
82 | } |
83 | if(Blind) |
| 4 | | Assuming field 'p_flgs' is 0 | |
|
| |
84 | pline("As you pronounce the formula on it, the scroll disappears."); |
85 | else |
86 | pline("As you read the scroll, it disappears."); |
87 | if(confused) |
| |
88 | pline("Being confused, you mispronounce the magic words ... "); |
89 | |
90 | switch(scroll->otyp) { |
| 7 | | Control jumps to 'case 149:' at line 435 | |
|
91 | #ifdef MAIL |
92 | case SCR_MAIL: |
93 | readmail(); |
94 | break; |
95 | #endif /* MAIL */ |
96 | case SCR_ENCHANT_ARMOR: |
97 | { struct obj *otmp = some_armor(); |
98 | if(!otmp) { |
99 | strange_feeling(scroll,"Your skin glows then fades."); |
100 | return(1); |
101 | } |
102 | if(confused) { |
103 | pline("Your %s glows silver for a moment.", |
104 | objects[otmp->otyp].oc_name); |
105 | otmp->rustfree = 1; |
106 | break; |
107 | } |
108 | if(otmp->spe > 3 && rn2(otmp->spe)) { |
109 | pline("Your %s glows violently green for a while, then evaporates.", |
110 | objects[otmp->otyp].oc_name); |
111 | useup(otmp); |
112 | break; |
113 | } |
114 | pline("Your %s glows green for a moment.", |
115 | objects[otmp->otyp].oc_name); |
116 | otmp->cursed = 0; |
117 | otmp->spe++; |
118 | break; |
119 | } |
120 | case SCR_DESTROY_ARMOR: |
121 | if(confused) { |
122 | struct obj *otmp = some_armor(); |
123 | if(!otmp) { |
124 | strange_feeling(scroll,"Your bones itch."); |
125 | return(1); |
126 | } |
127 | pline("Your %s glows purple for a moment.", |
128 | objects[otmp->otyp].oc_name); |
129 | otmp->rustfree = 0; |
130 | break; |
131 | } |
132 | if(uarm) { |
133 | pline("Your armor turns to dust and falls to the floor!"); |
134 | useup(uarm); |
135 | } else if(uarmh) { |
136 | pline("Your helmet turns to dust and is blown away!"); |
137 | useup(uarmh); |
138 | } else if(uarmg) { |
139 | pline("Your gloves vanish!"); |
140 | useup(uarmg); |
141 | selftouch("You"); |
142 | } else { |
143 | strange_feeling(scroll,"Your skin itches."); |
144 | return(1); |
145 | } |
146 | break; |
147 | case SCR_CONFUSE_MONSTER: |
148 | if(confused) { |
149 | pline("Your hands begin to glow purple."); |
150 | Confusion += rnd(100); |
151 | } else { |
152 | pline("Your hands begin to glow blue."); |
153 | u.umconf = 1; |
154 | } |
155 | break; |
156 | case SCR_SCARE_MONSTER: |
157 | { int ct = 0; |
158 | struct monst *mtmp; |
159 | |
160 | for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) |
161 | if(cansee(mtmp->mx,mtmp->my)) { |
162 | if(confused) |
163 | mtmp->mflee = mtmp->mfroz = |
164 | mtmp->msleep = 0; |
165 | else |
166 | mtmp->mflee = 1; |
167 | ct++; |
168 | } |
169 | if(!ct) { |
170 | if(confused) |
171 | pline("You hear sad wailing in the distance."); |
172 | else |
173 | pline("You hear maniacal laughter in the distance."); |
174 | } |
175 | break; |
176 | } |
177 | case SCR_BLANK_PAPER: |
178 | if(confused) |
179 | pline("You see strange patterns on this scroll."); |
180 | else |
181 | pline("This scroll seems to be blank."); |
182 | break; |
183 | case SCR_REMOVE_CURSE: |
184 | { struct obj *obj; |
185 | if(confused) |
186 | pline("You feel like you need some help."); |
187 | else |
188 | pline("You feel like someone is helping you."); |
189 | for(obj = invent; obj ; obj = obj->nobj) |
190 | if(obj->owornmask) |
191 | obj->cursed = confused; |
192 | if(Punished && !confused) { |
193 | Punished = 0; |
194 | freeobj(uchain); |
195 | unpobj(uchain); |
196 | free(uchain); |
197 | uball->spe = 0; |
198 | uball->owornmask &= ~W_BALL; |
199 | uchain = uball = (struct obj *) 0; |
200 | } |
201 | break; |
202 | } |
203 | case SCR_CREATE_MONSTER: |
204 | { int cnt = 1; |
205 | |
206 | if(!rn2(73)) cnt += rnd(4); |
207 | if(confused) cnt += 12; |
208 | while(cnt--) |
209 | (void) makemon(confused ? PM_ACID_BLOB : |
210 | (struct permonst *) 0, u.ux, u.uy); |
211 | break; |
212 | } |
213 | case SCR_ENCHANT_WEAPON: |
214 | if(uwep && confused) { |
215 | pline("Your %s glows silver for a moment.", |
216 | objects[uwep->otyp].oc_name); |
217 | uwep->rustfree = 1; |
218 | } else |
219 | if(!chwepon(scroll, 1)) |
220 | return(1); |
221 | break; |
222 | case SCR_DAMAGE_WEAPON: |
223 | if(uwep && confused) { |
224 | pline("Your %s glows purple for a moment.", |
225 | objects[uwep->otyp].oc_name); |
226 | uwep->rustfree = 0; |
227 | } else |
228 | if(!chwepon(scroll, -1)) |
229 | return(1); |
230 | break; |
231 | case SCR_TAMING: |
232 | { int i,j; |
233 | int bd = confused ? 5 : 1; |
234 | struct monst *mtmp; |
235 | |
236 | for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++) |
237 | if ((mtmp = m_at(u.ux+i, u.uy+j))) |
238 | (void) tamedog(mtmp, NULL); |
239 | break; |
240 | } |
241 | case SCR_GENOCIDE: |
242 | { extern char genocided[], fut_geno[]; |
243 | char buf[BUFSZ]; |
244 | struct monst *mtmp, *mtmp2; |
245 | |
246 | pline("You have found a scroll of genocide!"); |
247 | known = TRUE; |
248 | if(confused) |
249 | *buf = u.usym; |
250 | else do { |
251 | pline("What monster do you want to genocide (Type the letter)? "); |
252 | getlin(buf); |
253 | } while(strlen(buf) != 1 || !monstersym(*buf)); |
254 | if(!strchr(fut_geno, *buf)) |
255 | charcat(fut_geno, *buf); |
256 | if(!strchr(genocided, *buf)) |
257 | charcat(genocided, *buf); |
258 | else { |
259 | pline("Such monsters do not exist in this world."); |
260 | break; |
261 | } |
262 | for(mtmp = fmon; mtmp; mtmp = mtmp2){ |
263 | mtmp2 = mtmp->nmon; |
264 | if(mtmp->data->mlet == *buf) |
265 | mondead(mtmp); |
266 | } |
267 | pline("Wiped out all %c's.", *buf); |
268 | if(*buf == u.usym) { |
269 | killer = "scroll of genocide"; |
270 | u.uhp = -1; |
271 | } |
272 | break; |
273 | } |
274 | case SCR_LIGHT: |
275 | if(!Blind) known = TRUE; |
276 | litroom(!confused); |
277 | break; |
278 | case SCR_TELEPORTATION: |
279 | if(confused) |
280 | level_tele(); |
281 | else { |
282 | #ifdef QUEST |
283 | int oux = u.ux, ouy = u.uy; |
284 | tele(); |
285 | if(dist(oux, ouy) > 100) known = TRUE; |
286 | #else /* QUEST */ |
287 | int uroom = inroom(u.ux, u.uy); |
288 | tele(); |
289 | if(uroom != inroom(u.ux, u.uy)) known = TRUE; |
290 | #endif /* QUEST */ |
291 | } |
292 | break; |
293 | case SCR_GOLD_DETECTION: |
294 | |
295 | |
296 | if(confused) { |
297 | struct trap *ttmp; |
298 | |
299 | if(!ftrap) { |
300 | strange_feeling(scroll, "Your toes stop itching."); |
301 | return(1); |
302 | } else { |
303 | for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) |
304 | if(ttmp->tx != u.ux || ttmp->ty != u.uy) |
305 | goto outtrapmap; |
306 | |
307 | pline("Your toes itch!"); |
308 | break; |
309 | outtrapmap: |
310 | cls(); |
311 | for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) |
312 | at(ttmp->tx, ttmp->ty, '$'); |
313 | prme(); |
314 | pline("You feel very greedy!"); |
315 | } |
316 | } else { |
317 | struct gold *gtmp; |
318 | |
319 | if(!fgold) { |
320 | strange_feeling(scroll, "You feel materially poor."); |
321 | return(1); |
322 | } else { |
323 | known = TRUE; |
324 | for(gtmp = fgold; gtmp; gtmp = gtmp->ngold) |
325 | if(gtmp->gx != u.ux || gtmp->gy != u.uy) |
326 | goto outgoldmap; |
327 | |
328 | pline("You notice some gold between your feet."); |
329 | break; |
330 | outgoldmap: |
331 | cls(); |
332 | for(gtmp = fgold; gtmp; gtmp = gtmp->ngold) |
333 | at(gtmp->gx, gtmp->gy, '$'); |
334 | prme(); |
335 | pline("You feel very greedy, and sense gold!"); |
336 | } |
337 | } |
338 | |
339 | more(); |
340 | docrt(); |
341 | break; |
342 | case SCR_FOOD_DETECTION: |
343 | { int ct = 0, ctu = 0; |
344 | struct obj *obj; |
345 | char foodsym = confused ? POTION_SYM : FOOD_SYM; |
346 | |
347 | for(obj = fobj; obj; obj = obj->nobj) |
348 | if(obj->olet == FOOD_SYM) { |
349 | if(obj->ox == u.ux && obj->oy == u.uy) ctu++; |
350 | else ct++; |
351 | } |
352 | if(!ct && !ctu) { |
353 | strange_feeling(scroll,"Your nose twitches."); |
354 | return(1); |
355 | } else if(!ct) { |
356 | known = TRUE; |
357 | pline("You smell %s close nearby.", |
358 | confused ? "something" : "food"); |
359 | |
360 | } else { |
361 | known = TRUE; |
362 | cls(); |
363 | for(obj = fobj; obj; obj = obj->nobj) |
364 | if(obj->olet == foodsym) |
365 | at(obj->ox, obj->oy, FOOD_SYM); |
366 | prme(); |
367 | pline("Your nose tingles and you smell %s!", |
368 | confused ? "something" : "food"); |
369 | more(); |
370 | docrt(); |
371 | } |
372 | break; |
373 | } |
374 | case SCR_IDENTIFY: |
375 | |
376 | if(confused) |
377 | pline("You identify this as an identify scroll."); |
378 | else |
379 | pline("This is an identify scroll."); |
380 | useup(scroll); |
381 | objects[SCR_IDENTIFY].oc_name_known = 1; |
382 | if(!confused) |
383 | while( |
384 | !ggetobj("identify", identify, rn2(5) ? 1 : rn2(5)) |
385 | && invent |
386 | ); |
387 | return(1); |
388 | case SCR_MAGIC_MAPPING: |
389 | { struct rm *lev; |
390 | int num, zx, zy; |
391 | |
392 | known = TRUE; |
393 | pline("On this scroll %s a map!", |
394 | confused ? "was" : "is"); |
395 | for(zy = 0; zy < ROWNO; zy++) |
396 | for(zx = 0; zx < COLNO; zx++) { |
397 | if(confused && rn2(7)) continue; |
398 | lev = &(levl[zx][zy]); |
399 | if((num = lev->typ) == 0) |
400 | continue; |
401 | if(num == SCORR) { |
402 | lev->typ = CORR; |
403 | lev->scrsym = CORR_SYM; |
404 | } else |
405 | if(num == SDOOR) { |
406 | lev->typ = DOOR; |
407 | lev->scrsym = '+'; |
408 | |
409 | } else if(lev->seen) continue; |
410 | #ifndef QUEST |
411 | if(num != ROOM) |
412 | #endif /* QUEST */ |
413 | { |
414 | lev->seen = lev->new = 1; |
415 | if(lev->scrsym == ' ' || !lev->scrsym) |
416 | newsym(zx,zy); |
417 | else |
418 | on_scr(zx,zy); |
419 | } |
420 | } |
421 | break; |
422 | } |
423 | case SCR_AMNESIA: |
424 | { int zx, zy; |
425 | |
426 | known = TRUE; |
427 | for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++) |
428 | if(!confused || rn2(7)) |
429 | if(!cansee(zx,zy)) |
430 | levl[zx][zy].seen = 0; |
431 | docrt(); |
432 | pline("Thinking of Maud you forget everything else."); |
433 | break; |
434 | } |
435 | case SCR_FIRE: |
436 | { int num; |
| 8 | | 'num' declared without an initial value | |
|
437 | struct monst *mtmp; |
438 | |
439 | known = TRUE; |
440 | if(confused) { |
| |
441 | pline("The scroll catches fire and you burn your hands."); |
442 | losehp(1, "scroll of fire"); |
443 | } else { |
444 | pline("The scroll erupts in a tower of flame!"); |
445 | if(Fire_resistance) |
446 | pline("You are uninjured."); |
447 | else { |
448 | num = rnd(6); |
449 | u.uhpmax -= num; |
450 | losehp(num, "scroll of fire"); |
451 | } |
452 | } |
453 | num = (2*num + 1)/3; |
| 10 | | The right operand of '*' is a garbage value |
|
454 | for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { |
455 | if(dist(mtmp->mx,mtmp->my) < 3) { |
456 | mtmp->mhp -= num; |
457 | if(strchr("FY", mtmp->data->mlet)) |
458 | mtmp->mhp -= 3*num; |
459 | if(mtmp->mhp < 1) { |
460 | killed(mtmp); |
461 | break; |
462 | } |
463 | } |
464 | } |
465 | break; |
466 | } |
467 | case SCR_PUNISHMENT: |
468 | known = TRUE; |
469 | if(confused) { |
470 | pline("You feel guilty."); |
471 | break; |
472 | } |
473 | pline("You are being punished for your misbehaviour!"); |
474 | if(Punished){ |
475 | pline("Your iron ball gets heavier."); |
476 | uball->owt += 15; |
477 | break; |
478 | } |
479 | Punished = INTRINSIC; |
480 | setworn(mkobj_at(CHAIN_SYM, u.ux, u.uy), W_CHAIN); |
481 | setworn(mkobj_at(BALL_SYM, u.ux, u.uy), W_BALL); |
482 | uball->spe = 1; |
483 | break; |
484 | default: |
485 | impossible("What weird language is this written in? (%u)", |
486 | scroll->otyp); |
487 | } |
488 | if(!objects[scroll->otyp].oc_name_known) { |
489 | if(known && !confused) { |
490 | objects[scroll->otyp].oc_name_known = 1; |
491 | more_experienced(0,10); |
492 | } else if(!objects[scroll->otyp].oc_uname) |
493 | docall(scroll); |
494 | } |
495 | useup(scroll); |
496 | return(1); |
497 | } |
498 | |
499 | |
500 | int |
501 | identify(struct obj *otmp) |
502 | { |
503 | objects[otmp->otyp].oc_name_known = 1; |
504 | otmp->known = otmp->dknown = 1; |
505 | prinv(otmp); |
506 | return(1); |
507 | } |
508 | |
509 | void |
510 | litroom(boolean on) |
511 | { |
512 | int num,zx,zy; |
513 | |
514 | |
515 | if(Blind) goto do_it; |
516 | if(!on) { |
517 | if(u.uswallow || !xdnstair || |
518 | levl[(int)u.ux][(int)u.uy].typ == CORR || |
519 | !levl[(int)u.ux][(int)u.uy].lit) { |
520 | pline("It seems even darker in here than before."); |
521 | return; |
522 | } else |
523 | pline("It suddenly becomes dark in here."); |
524 | } else { |
525 | if(u.uswallow){ |
526 | pline("%s's stomach is lit.", Monnam(u.ustuck)); |
527 | return; |
528 | } |
529 | if(!xdnstair){ |
530 | pline("Nothing Happens."); |
531 | return; |
532 | } |
533 | #ifdef QUEST |
534 | pline("The cave lights up around you, then fades."); |
535 | return; |
536 | #else /* QUEST */ |
537 | if (levl[(int)u.ux][(int)u.uy].typ == CORR) { |
538 | pline("The corridor lights up around you, then fades."); |
539 | return; |
540 | } else if (levl[(int)u.ux][(int)u.uy].lit) { |
541 | pline("The light here seems better now."); |
542 | return; |
543 | } else |
544 | pline("The room is lit."); |
545 | #endif /* QUEST */ |
546 | } |
547 | |
548 | do_it: |
549 | #ifdef QUEST |
550 | return; |
551 | #else /* QUEST */ |
552 | if (levl[(int)u.ux][(int)u.uy].lit == on) |
553 | return; |
554 | if (levl[(int)u.ux][(int)u.uy].typ == DOOR) { |
555 | if (IS_ROOM(levl[(int)u.ux][(int)u.uy+1].typ)) |
556 | zy = u.uy+1; |
557 | else if(IS_ROOM(levl[(int)u.ux][u.uy-1].typ)) |
558 | zy = u.uy-1; |
559 | else zy = u.uy; |
560 | if(IS_ROOM(levl[u.ux+1][(int)u.uy].typ)) |
561 | zx = u.ux+1; |
562 | else if(IS_ROOM(levl[u.ux-1][(int)u.uy].typ)) |
563 | zx = u.ux-1; |
564 | else zx = u.ux; |
565 | } else { |
566 | zx = u.ux; |
567 | zy = u.uy; |
568 | } |
569 | for(seelx = u.ux; (num = levl[seelx-1][zy].typ) != CORR && num != 0; |
570 | seelx--); |
571 | for(seehx = u.ux; (num = levl[seehx+1][zy].typ) != CORR && num != 0; |
572 | seehx++); |
573 | for(seely = u.uy; (num = levl[zx][seely-1].typ) != CORR && num != 0; |
574 | seely--); |
575 | for(seehy = u.uy; (num = levl[zx][seehy+1].typ) != CORR && num != 0; |
576 | seehy++); |
577 | for(zy = seely; zy <= seehy; zy++) |
578 | for(zx = seelx; zx <= seehx; zx++) { |
579 | levl[zx][zy].lit = on; |
580 | if (!Blind && dist(zx,zy) > 2) { |
581 | if(on) |
582 | prl(zx,zy); |
583 | else |
584 | nosee(zx,zy); |
585 | } |
586 | } |
587 | if(!on) |
588 | seehx = 0; |
589 | #endif /* QUEST */ |
590 | } |
591 | |
592 | |
593 | |
594 | static boolean |
595 | monstersym(char ch) |
596 | { |
597 | struct permonst *mp; |
598 | extern struct permonst pm_eel; |
599 | |
600 | |
601 | |
602 | |
603 | if (strchr("12 &:", ch)) |
604 | return FALSE; |
605 | |
606 | if (ch == pm_eel.mlet) |
607 | return TRUE; |
608 | for (mp = mons; mp < &mons[CMNUM+2]; mp++) |
609 | if (mp->mlet == ch) |
610 | return TRUE; |
611 | return FALSE; |
612 | } |