Bug Summary

File:src/usr.bin/cut/cut.c
Warning:line 246, column 10
The left operand of '!=' is a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name cut.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/usr.bin/cut/obj -resource-dir /usr/local/llvm16/lib/clang/16 -internal-isystem /usr/local/llvm16/lib/clang/16/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.bin/cut/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/usr.bin/cut/cut.c
1/* $OpenBSD: cut.c,v 1.28 2023/03/08 04:43:10 guenther Exp $ */
2/* $NetBSD: cut.c,v 1.9 1995/09/02 05:59:23 jtc Exp $ */
3
4/*
5 * Copyright (c) 1989, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * Adam S. Moskowitz of Menlo Consulting and Marciano Pitargue.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#include <assert.h>
37#include <ctype.h>
38#include <err.h>
39#include <errno(*__errno()).h>
40#include <limits.h>
41#include <locale.h>
42#include <stdio.h>
43#include <stdlib.h>
44#include <string.h>
45#include <unistd.h>
46
47char dchar[5];
48int dlen;
49
50int bflag;
51int cflag;
52int dflag;
53int fflag;
54int nflag;
55int sflag;
56
57void b_cut(FILE *, char *);
58void c_cut(FILE *, char *);
59void f_cut(FILE *, char *);
60void get_list(char *);
61void usage(void);
62
63int
64main(int argc, char *argv[])
65{
66 FILE *fp;
67 void (*fcn)(FILE *, char *);
68 int ch, rval;
69
70 setlocale(LC_CTYPE2, "");
71
72 if (pledge("stdio rpath", NULL((void *)0)) == -1)
73 err(1, "pledge");
74
75 dchar[0] = '\t'; /* default delimiter */
76 dchar[1] = '\0';
77 dlen = 1;
78
79 while ((ch = getopt(argc, argv, "b:c:d:f:sn")) != -1)
80 switch(ch) {
81 case 'b':
82 get_list(optarg);
83 bflag = 1;
84 break;
85 case 'c':
86 get_list(optarg);
87 cflag = 1;
88 break;
89 case 'd':
90 if ((dlen = mblen(optarg, MB_CUR_MAX__mb_cur_max())) == -1)
91 usage();
92 assert(dlen < sizeof(dchar))((dlen < sizeof(dchar)) ? (void)0 : __assert2("/usr/src/usr.bin/cut/cut.c"
, 92, __func__, "dlen < sizeof(dchar)"))
;
93 (void)memcpy(dchar, optarg, dlen);
94 dchar[dlen] = '\0';
95 dflag = 1;
96 break;
97 case 'f':
98 get_list(optarg);
99 fflag = 1;
100 break;
101 case 'n':
102 nflag = 1;
103 break;
104 case 's':
105 sflag = 1;
106 break;
107 default:
108 usage();
109 }
110 argc -= optind;
111 argv += optind;
112
113 if (bflag + cflag + fflag != 1 ||
114 (nflag && !bflag) ||
115 ((dflag || sflag) && !fflag))
116 usage();
117
118 if (MB_CUR_MAX__mb_cur_max() == 1) {
119 nflag = 0;
120 if (cflag) {
121 bflag = 1;
122 cflag = 0;
123 }
124 }
125
126 fcn = fflag ? f_cut : (cflag || nflag) ? c_cut : b_cut;
127
128 rval = 0;
129 if (*argv)
130 for (; *argv; ++argv) {
131 if (strcmp(*argv, "-") == 0)
132 fcn(stdin(&__sF[0]), "stdin");
133 else {
134 if ((fp = fopen(*argv, "r"))) {
135 fcn(fp, *argv);
136 (void)fclose(fp);
137 } else {
138 rval = 1;
139 warn("%s", *argv);
140 }
141 }
142 }
143 else {
144 if (pledge("stdio", NULL((void *)0)) == -1)
145 err(1, "pledge");
146
147 fcn(stdin(&__sF[0]), "stdin");
148 }
149 exit(rval);
150}
151
152int autostart, autostop, maxval;
153
154char positions[_POSIX2_LINE_MAX2048 + 1];
155
156int
157read_number(char **p)
158{
159 int dash, n;
160 const char *errstr;
161 char *q;
162
163 q = *p + strcspn(*p, "-");
164 dash = *q == '-';
165 *q = '\0';
166 n = strtonum(*p, 1, _POSIX2_LINE_MAX2048, &errstr);
167 if (errstr != NULL((void *)0))
168 errx(1, "[-bcf] list: %s %s (allowed 1-%d)", *p, errstr,
169 _POSIX2_LINE_MAX2048);
170 if (dash)
171 *q = '-';
172 *p = q;
173
174 return n;
175}
176
177void
178get_list(char *list)
179{
180 int setautostart, start, stop;
181 char *p;
182
183 /*
184 * set a byte in the positions array to indicate if a field or
185 * column is to be selected; use +1, it's 1-based, not 0-based.
186 * This parser is less restrictive than the Draft 9 POSIX spec.
187 * POSIX doesn't allow lists that aren't in increasing order or
188 * overlapping lists. We also handle "-3-5" although there's no
189 * real reason too.
190 */
191 while ((p = strsep(&list, ", \t"))) {
192 setautostart = start = stop = 0;
193 if (*p == '-') {
194 ++p;
195 setautostart = 1;
196 }
197 if (isdigit((unsigned char)*p)) {
198 start = stop = read_number(&p);
199 if (setautostart && start > autostart)
200 autostart = start;
201 }
202 if (*p == '-') {
203 if (isdigit((unsigned char)p[1])) {
204 ++p;
205 stop = read_number(&p);
206 }
207 if (*p == '-') {
208 ++p;
209 if (!autostop || autostop > stop)
210 autostop = stop;
211 }
212 }
213 if (*p != '\0' || !stop || !start)
214 errx(1, "[-bcf] list: illegal list value");
215 if (maxval < stop)
216 maxval = stop;
217 if (start <= stop)
218 memset(positions + start, 1, stop - start + 1);
219 }
220
221 /* overlapping ranges */
222 if (autostop && maxval > autostop)
223 maxval = autostop;
224
225 /* set autostart */
226 if (autostart)
227 memset(positions + 1, '1', autostart);
228}
229
230void
231b_cut(FILE *fp, char *fname)
232{
233 int ch, col;
1
'ch' declared without an initial value
234 char *pos;
235
236 for (;;) {
2
Loop condition is true. Entering loop body
237 pos = positions + 1;
238 for (col = maxval; col; --col) {
3
Loop condition is false. Execution continues on line 246
239 if ((ch = getc(fp)(!__isthreaded ? (--(fp)->_r < 0 ? __srget(fp) : (int)(
*(fp)->_p++)) : (getc)(fp))
) == EOF(-1))
240 return;
241 if (ch == '\n')
242 break;
243 if (*pos++)
244 (void)putchar(ch)(!__isthreaded ? __sputc(ch, (&__sF[1])) : (putc)(ch, (&
__sF[1])))
;
245 }
246 if (ch != '\n') {
4
The left operand of '!=' is a garbage value
247 if (autostop)
248 while ((ch = getc(fp)(!__isthreaded ? (--(fp)->_r < 0 ? __srget(fp) : (int)(
*(fp)->_p++)) : (getc)(fp))
) != EOF(-1) && ch != '\n')
249 (void)putchar(ch)(!__isthreaded ? __sputc(ch, (&__sF[1])) : (putc)(ch, (&
__sF[1])))
;
250 else
251 while ((ch = getc(fp)(!__isthreaded ? (--(fp)->_r < 0 ? __srget(fp) : (int)(
*(fp)->_p++)) : (getc)(fp))
) != EOF(-1) && ch != '\n')
252 ;
253 }
254 (void)putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
255 }
256}
257
258void
259c_cut(FILE *fp, char *fname)
260{
261 static char *line = NULL((void *)0);
262 static size_t linesz = 0;
263 ssize_t linelen;
264 char *cp, *pos, *maxpos;
265 int len;
266
267 while ((linelen = getline(&line, &linesz, fp)) != -1) {
268 if (line[linelen - 1] == '\n')
269 line[linelen - 1] = '\0';
270
271 cp = line;
272 pos = positions + 1;
273 maxpos = pos + maxval;
274 while(pos < maxpos && *cp != '\0') {
275 len = mblen(cp, MB_CUR_MAX__mb_cur_max());
276 if (len == -1)
277 len = 1;
278 pos += nflag ? len : 1;
279 if (pos[-1] == '\0')
280 cp += len;
281 else
282 while (len--)
283 putchar(*cp++)(!__isthreaded ? __sputc(*cp++, (&__sF[1])) : (putc)(*cp++
, (&__sF[1])))
;
284 }
285 if (autostop)
286 puts(cp);
287 else
288 putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
289 }
290}
291
292void
293f_cut(FILE *fp, char *fname)
294{
295 static char *line = NULL((void *)0);
296 static size_t linesz = 0;
297 ssize_t linelen;
298 char *sp, *ep, *pos, *maxpos;
299 int output;
300
301 while ((linelen = getline(&line, &linesz, fp)) != -1) {
302 if (line[linelen - 1] == '\n')
303 line[linelen - 1] = '\0';
304
305 if ((ep = strstr(line, dchar)) == NULL((void *)0)) {
306 if (!sflag)
307 puts(line);
308 continue;
309 }
310
311 pos = positions + 1;
312 maxpos = pos + maxval;
313 output = 0;
314 sp = line;
315 for (;;) {
316 if (*pos++) {
317 if (output)
318 fputs(dchar, stdout(&__sF[1]));
319 while (sp < ep)
320 putchar(*sp++)(!__isthreaded ? __sputc(*sp++, (&__sF[1])) : (putc)(*sp++
, (&__sF[1])))
;
321 output = 1;
322 } else
323 sp = ep;
324 if (*sp == '\0' || pos == maxpos)
325 break;
326 sp += dlen;
327 if ((ep = strstr(sp, dchar)) == NULL((void *)0))
328 ep = strchr(sp, '\0');
329 }
330 if (autostop)
331 puts(sp);
332 else
333 putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
334 }
335}
336
337void
338usage(void)
339{
340 (void)fprintf(stderr(&__sF[2]),
341 "usage: cut -b list [-n] [file ...]\n"
342 " cut -c list [file ...]\n"
343 " cut -f list [-s] [-d delim] [file ...]\n");
344 exit(1);
345}