Bug Summary

File:src/games/hack/hack.save.c
Warning:line 224, column 18
The right operand of '==' is a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name hack.save.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 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -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/lib/clang/13.0.0 -I . -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/games/hack/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -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/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/games/hack/hack.save.c
1/* $OpenBSD: hack.save.c,v 1.14 2019/06/28 13:32:52 deraadt Exp $ */
2
3/*
4 * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
5 * Amsterdam
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met:
11 *
12 * - Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
15 * - Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * - Neither the name of the Stichting Centrum voor Wiskunde en
20 * Informatica, nor the names of its contributors may be used to endorse or
21 * promote products derived from this software without specific prior
22 * written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
25 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
27 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
28 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 */
36
37/*
38 * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
39 * All rights reserved.
40 *
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
43 * are met:
44 * 1. Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright
47 * notice, this list of conditions and the following disclaimer in the
48 * documentation and/or other materials provided with the distribution.
49 * 3. The name of the author may not be used to endorse or promote products
50 * derived from this software without specific prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
53 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
54 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
55 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
56 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
57 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
58 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
59 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
60 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
61 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62 */
63
64#include <signal.h>
65#include <stdio.h>
66#include <stdlib.h>
67#include <unistd.h>
68
69#include "hack.h"
70
71extern char genocided[60]; /* defined in Decl.c */
72extern char fut_geno[60]; /* idem */
73extern char SAVEF[], nul[];
74extern char pl_character[PL_CSIZ20];
75
76static int dosave0(int);
77
78int
79dosave(void)
80{
81 if(dosave0(0)) {
82 settty("Be seeing you ...\n");
83 exit(0);
84 }
85 return(0);
86}
87
88void
89hackhangup(int notused)
90{
91 (void) dosave0(1);
92 exit(1);
93}
94
95/* returns 1 if save successful */
96static int
97dosave0(int hu)
98{
99 int fd, ofd;
100 int tmp; /* not register ! */
101
102 (void) signal(SIGHUP1, SIG_IGN(void (*)(int))1);
103 (void) signal(SIGINT2, SIG_IGN(void (*)(int))1);
104 if((fd = open(SAVEF, O_CREAT0x0200 | O_TRUNC0x0400 | O_WRONLY0x0001, FMASK0660)) == -1) {
105 if(!hu) pline("Cannot open save file. (Continue or Quit)");
106 (void) unlink(SAVEF); /* ab@unido */
107 return(0);
108 }
109 if(flags.moonphase == FULL_MOON4) /* ut-sally!fletcher */
110 u.uluck--; /* and unido!ab */
111 savelev(fd,dlevel);
112 saveobjchn(fd, invent);
113 saveobjchn(fd, fcobj);
114 savemonchn(fd, fallen_down);
115 tmp = getuid();
116 bwrite(fd, &tmp, sizeof tmp);
117 bwrite(fd, &flags, sizeof(struct flag));
118 bwrite(fd, &dlevel, sizeof dlevel);
119 bwrite(fd, &maxdlevel, sizeof maxdlevel);
120 bwrite(fd, &moves, sizeof moves);
121 bwrite(fd, &u, sizeof(struct you));
122 if(u.ustuck)
123 bwrite(fd, &(u.ustuck->m_id), sizeof u.ustuck->m_id);
124 bwrite(fd, pl_character, sizeof pl_character);
125 bwrite(fd, genocided, sizeof genocided);
126 bwrite(fd, fut_geno, sizeof fut_geno);
127 savenames(fd);
128 for(tmp = 1; tmp <= maxdlevel; tmp++) {
129 extern int hackpid;
130 extern boolean level_exists[];
131
132 if(tmp == dlevel || !level_exists[tmp]) continue;
133 glo(tmp);
134 if((ofd = open(lock, O_RDONLY0x0000)) == -1) {
135 if(!hu) pline("Error while saving: cannot read %s.", lock);
136 (void) close(fd);
137 (void) unlink(SAVEF);
138 if(!hu) done("tricked");
139 return(0);
140 }
141 getlev(ofd, hackpid, tmp);
142 (void) close(ofd);
143 bwrite(fd, &tmp, sizeof tmp); /* level number */
144 savelev(fd,tmp); /* actual level */
145 (void) unlink(lock);
146 }
147 (void) close(fd);
148 glo(dlevel);
149 (void) unlink(lock); /* get rid of current level --jgm */
150 glo(0);
151 (void) unlink(lock);
152 return(1);
153}
154
155int
156dorecover(int fd)
157{
158 int nfd;
159 int tmp; /* not a register ! */
160 unsigned mid; /* idem */
1
'mid' declared without an initial value
161 struct obj *otmp;
162 extern boolean restoring;
163
164 restoring = TRUE1;
165 getlev(fd, 0, 0);
166 invent = restobjchn(fd);
167 for(otmp = invent; otmp; otmp = otmp->nobj)
2
Loop condition is true. Entering loop body
5
Loop condition is false. Execution continues on line 170
168 if(otmp->owornmask)
3
Assuming field 'owornmask' is 0
4
Taking false branch
169 setworn(otmp, otmp->owornmask);
170 fcobj = restobjchn(fd);
171 fallen_down = restmonchn(fd);
172 mread(fd, (char *) &tmp, sizeof tmp);
173 if(tmp != getuid()) { /* strange ... */
6
Assuming the condition is false
7
Taking false branch
174 (void) close(fd);
175 (void) unlink(SAVEF);
176 puts("Saved game was not yours.");
177 restoring = FALSE0;
178 return(0);
179 }
180 mread(fd, (char *) &flags, sizeof(struct flag));
181 mread(fd, (char *) &dlevel, sizeof dlevel);
182 mread(fd, (char *) &maxdlevel, sizeof maxdlevel);
183 mread(fd, (char *) &moves, sizeof moves);
184 mread(fd, (char *) &u, sizeof(struct you));
185 if(u.ustuck)
8
Assuming field 'ustuck' is null
9
Taking false branch
186 mread(fd, (char *) &mid, sizeof mid);
187 mread(fd, (char *) pl_character, sizeof pl_character);
188 mread(fd, (char *) genocided, sizeof genocided);
189 mread(fd, (char *) fut_geno, sizeof fut_geno);
190 restnames(fd);
191 while(1) {
10
Loop condition is true. Entering loop body
192 if(read(fd, (char *) &tmp, sizeof tmp) != sizeof tmp)
11
Assuming the condition is true
12
Taking true branch
193 break;
13
Execution continues on line 201
194 getlev(fd, 0, tmp);
195 glo(tmp);
196 if((nfd = open(lock, O_CREAT0x0200 | O_TRUNC0x0400 | O_WRONLY0x0001, FMASK0660)) == -1)
197 panic("Cannot open temp file %s!\n", lock);
198 savelev(nfd,tmp);
199 (void) close(nfd);
200 }
201 (void) lseek(fd, (off_t)0, SEEK_SET0);
202 getlev(fd, 0, 0);
203 (void) close(fd);
204 (void) unlink(SAVEF);
205 if(Punishedu.uprops[(19 +5)].p_flgs) {
14
Assuming field 'p_flgs' is 0
15
Taking false branch
206 for(otmp = fobj; otmp; otmp = otmp->nobj)
207 if(otmp->olet == CHAIN_SYM'_') goto chainfnd;
208 panic("Cannot find the iron chain?");
209 chainfnd:
210 uchain = otmp;
211 if(!uball){
212 for(otmp = fobj; otmp; otmp = otmp->nobj)
213 if(otmp->olet == BALL_SYM'0' && otmp->spe)
214 goto ballfnd;
215 panic("Cannot find the iron ball?");
216 ballfnd:
217 uball = otmp;
218 }
219 }
220 if(u.ustuck) {
16
Assuming field 'ustuck' is non-null
17
Taking true branch
221 struct monst *mtmp;
222
223 for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
18
Loop condition is true. Entering loop body
224 if(mtmp->m_id == mid) goto monfnd;
19
The right operand of '==' is a garbage value
225 panic("Cannot find the monster ustuck.");
226 monfnd:
227 u.ustuck = mtmp;
228 }
229#ifndef QUEST
230 setsee(); /* only to recompute seelx etc. - these weren't saved */
231#endif /* QUEST */
232 docrt();
233 restoring = FALSE0;
234 return(1);
235}
236
237struct obj *
238restobjchn(int fd)
239{
240 struct obj *otmp, *otmp2;
241 struct obj *first = 0;
242 int xl;
243 while(1) {
244 mread(fd, (char *) &xl, sizeof(xl));
245 if(xl == -1) break;
246 otmp = newobj(xl)(struct obj *) alloc((unsigned)(xl) + sizeof(struct obj));
247 if(!first) first = otmp;
248 else otmp2->nobj = otmp;
249 mread(fd, (char *) otmp, (unsigned) xl + sizeof(struct obj));
250 if(!otmp->o_id) otmp->o_id = flags.ident++;
251 otmp2 = otmp;
252 }
253 if(first && otmp2->nobj){
254 impossible("Restobjchn: error reading objchn.");
255 otmp2->nobj = 0;
256 }
257 return(first);
258}
259
260struct monst *
261restmonchn(int fd)
262{
263 struct monst *mtmp, *mtmp2;
264 struct monst *first = 0;
265 int xl;
266
267 struct permonst *monbegin;
268 long differ;
269
270 mread(fd, (char *)&monbegin, sizeof(monbegin));
271 differ = (char *)(&mons[0]) - (char *)(monbegin);
272
273 while(1) {
274 mread(fd, (char *) &xl, sizeof(xl));
275 if(xl == -1) break;
276 mtmp = newmonst(xl)(struct monst *) alloc((unsigned)(xl) + sizeof(struct monst));
277 if(!first) first = mtmp;
278 else mtmp2->nmon = mtmp;
279 mread(fd, (char *) mtmp, (unsigned) xl + sizeof(struct monst));
280 if(!mtmp->m_id)
281 mtmp->m_id = flags.ident++;
282 mtmp->data = (struct permonst *)
283 ((char *) mtmp->data + differ);
284 if(mtmp->minvent)
285 mtmp->minvent = restobjchn(fd);
286 mtmp2 = mtmp;
287 }
288 if(first && mtmp2->nmon){
289 impossible("Restmonchn: error reading monchn.");
290 mtmp2->nmon = 0;
291 }
292 return(first);
293}