Bug Summary

File:src/sbin/fdisk/misc.c
Warning:line 188, column 34
Division by zero

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 misc.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/sbin/fdisk/obj -resource-dir /usr/local/llvm16/lib/clang/16 -D HAS_MBR -internal-isystem /usr/local/llvm16/lib/clang/16/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/sbin/fdisk/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/sbin/fdisk/misc.c
1/* $OpenBSD: misc.c,v 1.88 2022/07/10 20:34:31 krw Exp $ */
2
3/*
4 * Copyright (c) 1997 Tobias Weingartner
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/types.h>
20#include <sys/disklabel.h>
21
22#include <ctype.h>
23#include <err.h>
24#include <errno(*__errno()).h>
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28
29#include "part.h"
30#include "disk.h"
31#include "misc.h"
32
33const struct unit_type unit_types[] = {
34 { "b" , 1LL , "Bytes" },
35 { " " , 0LL , "Sectors" },
36 { "K" , 1024LL , "Kilobytes" },
37 { "M" , 1024LL * 1024 , "Megabytes" },
38 { "G" , 1024LL * 1024 *1024 , "Gigabytes" },
39 { "T" , 1024LL * 1024 * 1024 * 1024 , "Terabytes" },
40};
41#define SECTORS1 1
42
43double
44units_size(const char *units, const uint64_t sectors,
45 const struct unit_type **ut)
46{
47 double size;
48 unsigned int i;
49
50 *ut = &unit_types[SECTORS1];
51 size = sectors;
52
53 for (i = 0; i < nitems(unit_types)(sizeof((unit_types)) / sizeof((unit_types)[0])); i++) {
54 if (strncasecmp(unit_types[i].ut_abbr, units, 1) == 0)
55 *ut = &unit_types[i];
56 }
57
58 if ((*ut)->ut_conversion == 0)
59 return size;
60 else
61 return (size * dl.d_secsize) / (*ut)->ut_conversion;
62}
63
64void
65string_from_line(char *buf, const size_t buflen, const int trim)
66{
67 static char *line;
68 static size_t sz;
69 ssize_t len;
70 size_t n;
71 unsigned int i;
72
73 len = getline(&line, &sz, stdin(&__sF[0]));
74 if (len == -1)
75 errx(1, "eof");
76
77 switch (trim) {
78 case UNTRIMMED0:
79 line[strcspn(line, "\n")] = '\0';
80 n = strlcpy(buf, line, buflen);
81 break;
82 case TRIMMED1:
83 for (i = strlen(line); i > 0; i--) {
84 if (isspace((unsigned char)line[i - 1]) == 0)
85 break;
86 line[i - 1] = '\0';
87 }
88 n = strlcpy(buf, line + strspn(line, WHITESPACE" \f\n\r\t\v"), buflen);
89 break;
90 }
91
92 if (n >= buflen) {
93 printf("input too long\n");
94 memset(buf, 0, buflen);
95 }
96}
97
98int
99ask_yn(const char *str)
100{
101 int ch, first;
102 extern int y_flag;
103
104 if (y_flag)
105 return 1;
106
107 printf("%s [n] ", str);
108 fflush(stdout(&__sF[1]));
109
110 first = ch = getchar()(!__isthreaded ? (--((&__sF[0]))->_r < 0 ? __srget(
(&__sF[0])) : (int)(*((&__sF[0]))->_p++)) : (getc)
((&__sF[0])))
;
111 while (ch != '\n' && ch != EOF(-1))
112 ch = getchar()(!__isthreaded ? (--((&__sF[0]))->_r < 0 ? __srget(
(&__sF[0])) : (int)(*((&__sF[0]))->_p++)) : (getc)
((&__sF[0])))
;
113
114 if (ch == EOF(-1) || first == EOF(-1))
115 errx(1, "eof");
116
117 return first == 'y' || first == 'Y';
118}
119
120/*
121 * adapted from sbin/disklabel/editor.c
122 */
123uint64_t
124getuint64(const char *prompt, uint64_t oval, const uint64_t minval,
125 const uint64_t maxval)
126{
127 char buf[BUFSIZ1024], *endptr, *p, operator = '\0';
128 const int secsize = dl.d_secsize;
1
'secsize' initialized here
129 size_t n;
130 int64_t mult = 1;
131 double d, d2;
132 int rslt, secpercyl, saveerr;
133 char unit;
134
135 if (oval > maxval)
2
Assuming 'oval' is <= 'maxval'
3
Taking false branch
136 oval = maxval;
137 if (oval < minval)
4
Assuming 'oval' is >= 'minval'
5
Taking false branch
138 oval = minval;
139
140 secpercyl = disk.dk_sectors * disk.dk_heads;
141
142 do {
23
Loop condition is true. Execution continues on line 143
143 printf("%s [%llu - %llu]: [%llu] ", prompt, minval, maxval,
144 oval);
145 string_from_line(buf, sizeof(buf), TRIMMED1);
146
147 if (buf[0] == '\0') {
6
Assuming the condition is false
24
Assuming the condition is false
148 rslt = snprintf(buf, sizeof(buf), "%llu", oval);
149 if (rslt < 0 || rslt >= sizeof(buf))
150 errx(1, "default value too long");
151 } else if (buf[0] == '*' && buf[1] == '\0') {
7
Assuming the condition is false
25
Assuming the condition is false
152 return maxval;
153 }
154
155 /* deal with units */
156 n = strlen(buf);
157 switch (tolower((unsigned char)buf[n-1])) {
8
Control jumps to 'case 98:' at line 163
26
Control jumps to 'case 103:' at line 186
158 case 'c':
159 unit = 'c';
160 mult = secpercyl;
161 buf[--n] = '\0';
162 break;
163 case 'b':
164 unit = 'b';
165 mult = -(int64_t)secsize;
166 buf[--n] = '\0';
167 break;
9
Execution continues on line 203
168 case 's':
169 unit = 's';
170 mult = 1;
171 buf[--n] = '\0';
172 break;
173 case 'k':
174 unit = 'k';
175 if (secsize > 1024)
176 mult = -(int64_t)secsize / 1024LL;
177 else
178 mult = 1024LL / secsize;
179 buf[--n] = '\0';
180 break;
181 case 'm':
182 unit = 'm';
183 mult = (1024LL * 1024) / secsize;
184 buf[--n] = '\0';
185 break;
186 case 'g':
187 unit = 'g';
188 mult = (1024LL * 1024 * 1024) / secsize;
27
Division by zero
189 buf[--n] = '\0';
190 break;
191 case 't':
192 unit = 't';
193 mult = (1024LL * 1024 * 1024 * 1024) / secsize;
194 buf[--n] = '\0';
195 break;
196 default:
197 unit = ' ';
198 mult = 1;
199 break;
200 }
201
202 /* deal with the operator */
203 p = &buf[0];
204 if (*p == '+' || *p == '-')
10
Assuming the condition is false
11
Assuming the condition is false
12
Taking false branch
205 operator = *p++;
206 else
207 operator = ' ';
208
209 endptr = p;
210 errno(*__errno()) = 0;
211 d = strtod(p, &endptr);
212 saveerr = errno(*__errno());
213 d2 = d;
214 if (mult > 0)
13
Assuming 'mult' is <= 0
14
Taking false branch
215 d *= mult;
216 else {
217 d /= (-mult);
218 d2 = d;
219 }
220
221 /* Apply the operator */
222 if (operator == '+')
15
Taking false branch
223 d = oval + d;
224 else if (operator == '-') {
225 d = oval - d;
226 d2 = d;
227 }
228
229 if (saveerr == ERANGE34 || d > maxval || d < minval || d < d2) {
16
Assuming 'saveerr' is not equal to ERANGE
17
Assuming 'd' is <= 'maxval'
18
Assuming 'd' is >= 'minval'
19
Assuming 'd' is >= 'd2'
20
Taking false branch
230 printf("%s is out of range: %c%s%c\n", prompt, operator,
231 p, unit);
232 } else if (*endptr != '\0') {
21
Assuming the condition is true
22
Taking true branch
233 printf("%s is invalid: %c%s%c\n", prompt, operator,
234 p, unit);
235 } else {
236 break;
237 }
238 } while (1);
239
240 return (uint64_t)d;
241}
242
243int
244hex_octet(char *buf)
245{
246 char *cp;
247 long num;
248
249 cp = buf;
250 num = strtol(buf, &cp, 16);
251
252 if (cp == buf || *cp != '\0')
253 return -1;
254
255 if (num < 0 || num > 0xff)
256 return -1;
257
258 return num;
259}