Bug Summary

File:src/usr.bin/hexdump/odsyntax.c
Warning:line 244, column 4
Value stored to 'y' is never read

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 odsyntax.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/usr.bin/hexdump/obj -resource-dir /usr/local/lib/clang/13.0.0 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.bin/hexdump/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/usr.bin/hexdump/odsyntax.c
1/* $OpenBSD: odsyntax.c,v 1.28 2017/05/30 05:58:44 tedu Exp $ */
2/* $NetBSD: odsyntax.c,v 1.15 2001/12/07 15:14:29 bjh21 Exp $ */
3
4/*-
5 * Copyright (c) 1990, 1993
6 * The Regents of the University of California. 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
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33#include <sys/types.h>
34
35#include <ctype.h>
36#include <err.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <unistd.h>
40
41#include "hexdump.h"
42
43#define PADDING" " " "
44
45int odmode;
46
47static void odadd(const char *);
48static void odoffset(int, char ***);
49static __dead__attribute__((__noreturn__)) void oldusage(void);
50static void posixtypes(char *);
51
52/*
53 * formats used for -t
54 */
55static const char *fmt[4][4] = {
56 {
57 "16/1 \"%3d \" \"\\n\"",
58 "8/2 \" %05d \" \"\\n\"",
59 "4/4 \" %010d \" \"\\n\"",
60 "2/8 \" %019d \" \"\\n\""
61 }, {
62 "16/1 \"%03o \" \"\\n\"",
63 "8/2 \" %06o \" \"\\n\"",
64 "4/4 \" %011o\" \"\\n\"",
65 "2/8 \" %022o \" \"\\n\""
66 }, {
67 "16/1 \"%03u \" \"\\n\"",
68 "8/2 \" %05u \" \"\\n\"",
69 "4/4 \" %010u \" \"\\n\"",
70 "2/8 \" %020u \" \"\\n\""
71 }, {
72 "16/1 \" %02x \" \"\\n\"",
73 "8/2 \" %04x \" \"\\n\"",
74 "4/4 \" %08x \" \"\\n\"",
75 "2/8 \" %16x \" \"\\n\""
76 }
77};
78
79void
80oldsyntax(int argc, char ***argvp)
81{
82 static char empty[] = "", padding[] = PADDING" ";
83 int ch;
84 char *p, **argv;
85
86#define TYPE_OFFSET7 7
87 add("\"%07.7_Ao\n\"");
88 add("\"%07.7_ao \"");
89
90 odmode = 1;
91 argv = *argvp;
92 while ((ch = getopt(argc, argv,
93 "A:aBbcDdeFfHhIij:LlN:Oost:vXx")) != -1)
94 switch (ch) {
95 case 'A':
96 switch (*optarg) {
97 case 'd': case 'o': case 'x':
98 fshead->nextfu->fmt[TYPE_OFFSET7] = *optarg;
99 fshead->nextfs->nextfu->fmt[TYPE_OFFSET7] =
100 *optarg;
101 break;
102 case 'n':
103 fshead->nextfu->fmt = empty;
104 fshead->nextfs->nextfu->fmt = padding;
105 break;
106 default:
107 errx(1, "%s: invalid address base", optarg);
108 }
109 break;
110 case 'a':
111 odadd("16/1 \"%3_u \" \"\\n\"");
112 break;
113 case 'B':
114 case 'o':
115 odadd("8/2 \" %06o \" \"\\n\"");
116 break;
117 case 'b':
118 odadd("16/1 \"%03o \" \"\\n\"");
119 break;
120 case 'c':
121 odadd("16/1 \"%3_c \" \"\\n\"");
122 break;
123 case 'd':
124 odadd("8/2 \" %05u \" \"\\n\"");
125 break;
126 case 'D':
127 odadd("4/4 \" %010u \" \"\\n\"");
128 break;
129 case 'e':
130 case 'F':
131 odadd("2/8 \" %21.14e \" \"\\n\"");
132 break;
133 case 'f':
134 odadd("4/4 \" %14.7e \" \"\\n\"");
135 break;
136 case 'H':
137 case 'X':
138 odadd("4/4 \" %08x \" \"\\n\"");
139 break;
140 case 'h':
141 case 'x':
142 odadd("8/2 \" %04x \" \"\\n\"");
143 break;
144 case 'I':
145 case 'L':
146 case 'l':
147 odadd("4/4 \" %11d \" \"\\n\"");
148 break;
149 case 'i':
150 odadd("8/2 \" %6d \" \"\\n\"");
151 break;
152 case 'j':
153 if ((skip = strtol(optarg, &p, 0)) < 0)
154 errx(1, "%s: bad skip value", optarg);
155 switch(*p) {
156 case 'b':
157 skip *= 512;
158 break;
159 case 'k':
160 skip *= 1024;
161 break;
162 case 'm':
163 skip *= 1048576;
164 break;
165 }
166 break;
167 case 'N':
168 if ((length = atoi(optarg)) < 0)
169 errx(1, "%s: bad length value", optarg);
170 break;
171 case 'O':
172 odadd("4/4 \" %011o \" \"\\n\"");
173 break;
174 case 's':
175 odadd("8/2 \" %05d \" \"\\n\"");
176 break;
177 case 't':
178 posixtypes(optarg);
179 break;
180 case 'v':
181 vflag = ALL;
182 break;
183 default:
184 oldusage();
185 }
186
187 if (fshead->nextfs->nextfs == NULL((void *)0))
188 odadd(" 8/2 \"%06o \" \"\\n\"");
189
190 argc -= optind;
191 *argvp += optind;
192
193 if (argc)
194 odoffset(argc, argvp);
195}
196
197/*
198 * Interpret a POSIX-style -t argument.
199 */
200static void
201posixtypes(char *type_string)
202{
203 int x, y, nbytes;
204
205 while (*type_string) {
206 switch (*type_string) {
207 case 'a':
208 type_string++;
209 odadd("16/1 \"%3_u \" \"\\n\"");
210 break;
211 case 'c':
212 type_string++;
213 odadd("16/1 \"%3_c \" \"\\n\"");
214 break;
215 case 'f':
216 type_string++;
217 if (*type_string == 'F' ||
218 *type_string == '4') {
219 type_string++;
220 odadd("4/4 \" %14.7e\" \"\\n\"");
221 } else if (*type_string == 'L' ||
222 *type_string == '8') {
223 type_string++;
224 odadd("2/8 \" %16.14e\" \"\\n\"");
225 } else if (*type_string == 'D')
226 /* long doubles vary in size */
227 oldusage();
228 else
229 odadd("2/8 \" %16.14e\" \"\\n\"");
230 break;
231 case 'd':
232 x = 0;
233 goto extensions;
234 case 'o':
235 x = 1;
236 goto extensions;
237 case 'u':
238 x = 2;
239 goto extensions;
240 case 'x':
241 x = 3;
242 extensions:
243 type_string++;
244 y = 2;
Value stored to 'y' is never read
245 if (isupper((unsigned char)*type_string)) {
246 switch(*type_string) {
247 case 'C':
248 nbytes = sizeof(char);
249 break;
250 case 'S':
251 nbytes = sizeof(short);
252 break;
253 case 'I':
254 nbytes = sizeof(int);
255 break;
256 case 'L':
257 nbytes = sizeof(long);
258 break;
259 default:
260 warnx("Bad type-size qualifier '%c'",
261 *type_string);
262 oldusage();
263 }
264 type_string++;
265 } else if (isdigit((unsigned char)*type_string))
266 nbytes = strtol(type_string, &type_string, 10);
267 else
268 nbytes = 4;
269
270 switch (nbytes) {
271 case 1:
272 y = 0;
273 break;
274 case 2:
275 y = 1;
276 break;
277 case 4:
278 y = 2;
279 break;
280 case 8:
281 y = 3;
282 break;
283 default:
284 warnx("%d-byte integer formats are not "
285 "supported", nbytes);
286 oldusage();
287 }
288 odadd(fmt[x][y]);
289 break;
290 default:
291 oldusage();
292 }
293 }
294}
295
296static __dead__attribute__((__noreturn__)) void
297oldusage(void)
298{
299 extern char *__progname;
300 fprintf(stderr(&__sF[2]), "usage: %s [-aBbcDdeFfHhIiLlOosvXx] [-A base] "
301 "[-j offset] [-N length]\n"
302 "\t[-t type_string] [file ...]\n", __progname);
303 exit(1);
304}
305
306static void
307odoffset(int argc, char ***argvp)
308{
309 char *num, *p;
310 int base;
311 char *end;
312
313 /*
314 * The offset syntax of od(1) was genuinely bizarre. First, if
315 * it started with a plus it had to be an offset. Otherwise, if
316 * there were at least two arguments, a number or lower-case 'x'
317 * followed by a number makes it an offset. By default it was
318 * octal; if it started with 'x' or '0x' it was hex. If it ended
319 * in a '.', it was decimal. If a 'b' or 'B' was appended, it
320 * multiplied the number by 512 or 1024 byte units. There was
321 * no way to assign a block count to a hex offset.
322 *
323 * We assume it's a file if the offset is bad.
324 */
325 p = argc == 1 ? (*argvp)[0] : (*argvp)[1];
326 if (!p)
327 return;
328
329 if (*p != '+' && (argc < 2 ||
330 (!isdigit((unsigned char)p[0]) &&
331 (p[0] != 'x' || !isxdigit((unsigned char)p[1])))))
332 return;
333
334 base = 0;
335 /*
336 * skip over leading '+', 'x[0-9a-fA-f]' or '0x', and
337 * set base.
338 */
339 if (p[0] == '+')
340 ++p;
341 if (p[0] == 'x' && isxdigit((unsigned char)p[1])) {
342 ++p;
343 base = 16;
344 } else if (p[0] == '0' && p[1] == 'x') {
345 p += 2;
346 base = 16;
347 }
348
349 /* skip over the number */
350 if (base == 16)
351 for (num = p; isxdigit((unsigned char)*p); ++p);
352 else
353 for (num = p; isdigit((unsigned char)*p); ++p);
354
355 /* check for no number */
356 if (num == p)
357 return;
358
359 /* if terminates with a '.', base is decimal */
360 if (*p == '.') {
361 if (base)
362 return;
363 base = 10;
364 }
365
366 skip = strtol(num, &end, base ? base : 8);
367
368 /* if end isn't the same as p, we got a non-octal digit */
369 if (end != p) {
370 skip = 0;
371 return;
372 }
373
374 if (*p == '.')
375 ++p;
376 if (*p) {
377 if (*p == 'B') {
378 skip *= 1024;
379 ++p;
380 } else if (*p == 'b') {
381 skip *= 512;
382 ++p;
383 }
384 }
385 if (*p) {
386 skip = 0;
387 return;
388 }
389 /*
390 * If the offset uses a non-octal base, the base of the offset
391 * is changed as well. This isn't pretty, but it's easy.
392 */
393 if (base == 16) {
394 fshead->nextfu->fmt[TYPE_OFFSET7] = 'x';
395 fshead->nextfs->nextfu->fmt[TYPE_OFFSET7] = 'x';
396 } else if (base == 10) {
397 fshead->nextfu->fmt[TYPE_OFFSET7] = 'd';
398 fshead->nextfs->nextfu->fmt[TYPE_OFFSET7] = 'd';
399 }
400
401 /* Terminate file list. */
402 (*argvp)[argc > 1] = NULL((void *)0);
403}
404
405static void
406odadd(const char *format)
407{
408 static int needpad;
409
410 if (needpad)
411 add("\""PADDING" ""\"");
412 add(format);
413 needpad = 1;
414}