Bug Summary

File:src/lib/libz/gzwrite.c
Warning:line 283, column 44
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 gzwrite.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/lib/libz/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/lib/libz/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/lib/libz/gzwrite.c
1/* gzwrite.c -- zlib functions for writing gzip files
2 * Copyright (C) 2004-2019 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6#include "gzguts.h"
7
8/* Initialize state for writing a gzip file. Mark initialization by setting
9 state->size to non-zero. Return -1 on a memory allocation failure, or 0 on
10 success. */
11localstatic int gz_init(gz_statep state) {
12 int ret;
13 z_streamp strm = &(state->strm);
14
15 /* allocate input buffer (double size for gzprintf) */
16 state->in = (unsigned char *)malloc(state->want << 1);
17 if (state->in == NULL((void *)0)) {
18 gz_error(state, Z_MEM_ERROR(-4), "out of memory");
19 return -1;
20 }
21
22 /* only need output buffer and deflate state if compressing */
23 if (!state->direct) {
24 /* allocate output buffer */
25 state->out = (unsigned char *)malloc(state->want);
26 if (state->out == NULL((void *)0)) {
27 free(state->in);
28 gz_error(state, Z_MEM_ERROR(-4), "out of memory");
29 return -1;
30 }
31
32 /* allocate deflate memory, set up for gzip compression */
33 strm->zalloc = Z_NULL0;
34 strm->zfree = Z_NULL0;
35 strm->opaque = Z_NULL0;
36 ret = deflateInit2(strm, state->level, Z_DEFLATED,deflateInit2_((strm),(state->level),(8),(15 + 16),(8), (state
->strategy), "1.3.0.1-motley", (int)sizeof(z_stream))
37 MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy)deflateInit2_((strm),(state->level),(8),(15 + 16),(8), (state
->strategy), "1.3.0.1-motley", (int)sizeof(z_stream))
;
38 if (ret != Z_OK0) {
39 free(state->out);
40 free(state->in);
41 gz_error(state, Z_MEM_ERROR(-4), "out of memory");
42 return -1;
43 }
44 strm->next_in = NULL((void *)0);
45 }
46
47 /* mark state as initialized */
48 state->size = state->want;
49
50 /* initialize write buffer if compressing */
51 if (!state->direct) {
52 strm->avail_out = state->size;
53 strm->next_out = state->out;
54 state->x.next = strm->next_out;
55 }
56 return 0;
57}
58
59/* Compress whatever is at avail_in and next_in and write to the output file.
60 Return -1 if there is an error writing to the output file or if gz_init()
61 fails to allocate memory, otherwise 0. flush is assumed to be a valid
62 deflate() flush value. If flush is Z_FINISH, then the deflate() state is
63 reset to start a new gzip stream. If gz->direct is true, then simply write
64 to the output file without compressing, and ignore flush. */
65localstatic int gz_comp(gz_statep state, int flush) {
66 int ret, writ;
67 unsigned have, put, max = ((unsigned)-1 >> 2) + 1;
68 z_streamp strm = &(state->strm);
69
70 /* allocate memory if this is the first time through */
71 if (state->size == 0 && gz_init(state) == -1)
72 return -1;
73
74 /* write directly if requested */
75 if (state->direct) {
76 while (strm->avail_in) {
77 put = strm->avail_in > max ? max : strm->avail_in;
78 writ = write(state->fd, strm->next_in, put);
79 if (writ < 0) {
80 gz_error(state, Z_ERRNO(-1), zstrerror()strerror((*__errno())));
81 return -1;
82 }
83 strm->avail_in -= (unsigned)writ;
84 strm->next_in += writ;
85 }
86 return 0;
87 }
88
89 /* check for a pending reset */
90 if (state->reset) {
91 /* don't start a new gzip member unless there is data to write */
92 if (strm->avail_in == 0)
93 return 0;
94 deflateReset(strm);
95 state->reset = 0;
96 }
97
98 /* run deflate() on provided input until it produces no more output */
99 ret = Z_OK0;
100 do {
101 /* write out current buffer contents if full, or if flushing, but if
102 doing Z_FINISH then don't write until we get to Z_STREAM_END */
103 if (strm->avail_out == 0 || (flush != Z_NO_FLUSH0 &&
104 (flush != Z_FINISH4 || ret == Z_STREAM_END1))) {
105 while (strm->next_out > state->x.next) {
106 put = strm->next_out - state->x.next > (int)max ? max :
107 (unsigned)(strm->next_out - state->x.next);
108 writ = write(state->fd, state->x.next, put);
109 if (writ < 0) {
110 gz_error(state, Z_ERRNO(-1), zstrerror()strerror((*__errno())));
111 return -1;
112 }
113 state->x.next += writ;
114 }
115 if (strm->avail_out == 0) {
116 strm->avail_out = state->size;
117 strm->next_out = state->out;
118 state->x.next = state->out;
119 }
120 }
121
122 /* compress */
123 have = strm->avail_out;
124 ret = deflate(strm, flush);
125 if (ret == Z_STREAM_ERROR(-2)) {
126 gz_error(state, Z_STREAM_ERROR(-2),
127 "internal error: deflate stream corrupt");
128 return -1;
129 }
130 have -= strm->avail_out;
131 } while (have);
132
133 /* if that completed a deflate stream, allow another to start */
134 if (flush == Z_FINISH4)
135 state->reset = 1;
136
137 /* all done, no errors */
138 return 0;
139}
140
141/* Compress len zeros to output. Return -1 on a write error or memory
142 allocation failure by gz_comp(), or 0 on success. */
143localstatic int gz_zero(gz_statep state, z_off64_toff_t len) {
144 int first;
145 unsigned n;
146 z_streamp strm = &(state->strm);
147
148 /* consume whatever's left in the input buffer */
149 if (strm->avail_in && gz_comp(state, Z_NO_FLUSH0) == -1)
150 return -1;
151
152 /* compress len zeros (len guaranteed > 0) */
153 first = 1;
154 while (len) {
155 n = GT_OFF(state->size)(sizeof(int) == sizeof(off_t) && (state->size) >
0x7fffffff)
|| (z_off64_toff_t)state->size > len ?
156 (unsigned)len : state->size;
157 if (first) {
158 memset(state->in, 0, n);
159 first = 0;
160 }
161 strm->avail_in = n;
162 strm->next_in = state->in;
163 state->x.pos += n;
164 if (gz_comp(state, Z_NO_FLUSH0) == -1)
165 return -1;
166 len -= n;
167 }
168 return 0;
169}
170
171/* Write len bytes from buf to file. Return the number of bytes written. If
172 the returned value is less than len, then there was an error. */
173localstatic z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) {
174 z_size_t put = len;
175
176 /* if len is zero, avoid unnecessary operations */
177 if (len == 0)
178 return 0;
179
180 /* allocate memory if this is the first time through */
181 if (state->size == 0 && gz_init(state) == -1)
182 return 0;
183
184 /* check for seek request */
185 if (state->seek) {
186 state->seek = 0;
187 if (gz_zero(state, state->skip) == -1)
188 return 0;
189 }
190
191 /* for small len, copy to input buffer, otherwise compress directly */
192 if (len < state->size) {
193 /* copy to input buffer, compress when full */
194 do {
195 unsigned have, copy;
196
197 if (state->strm.avail_in == 0)
198 state->strm.next_in = state->in;
199 have = (unsigned)((state->strm.next_in + state->strm.avail_in) -
200 state->in);
201 copy = state->size - have;
202 if (copy > len)
203 copy = (unsigned)len;
204 memcpy(state->in + have, buf, copy);
205 state->strm.avail_in += copy;
206 state->x.pos += copy;
207 buf = (const char *)buf + copy;
208 len -= copy;
209 if (len && gz_comp(state, Z_NO_FLUSH0) == -1)
210 return 0;
211 } while (len);
212 }
213 else {
214 /* consume whatever's left in the input buffer */
215 if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH0) == -1)
216 return 0;
217
218 /* directly compress user buffer to file */
219 state->strm.next_in = (z_const Bytef *)buf;
220 do {
221 unsigned n = (unsigned)-1;
222 if (n > len)
223 n = (unsigned)len;
224 state->strm.avail_in = n;
225 state->x.pos += n;
226 if (gz_comp(state, Z_NO_FLUSH0) == -1)
227 return 0;
228 len -= n;
229 } while (len);
230 }
231
232 /* input was all buffered or compressed */
233 return put;
234}
235
236/* -- see zlib.h -- */
237int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len) {
238 gz_statep state;
239
240 /* get internal structure */
241 if (file == NULL((void *)0))
242 return 0;
243 state = (gz_statep)file;
244
245 /* check that we're writing and that there's no error */
246 if (state->mode != GZ_WRITE31153 || state->err != Z_OK0)
247 return 0;
248
249 /* since an int is returned, make sure len fits in one, otherwise return
250 with an error (this avoids a flaw in the interface) */
251 if ((int)len < 0) {
252 gz_error(state, Z_DATA_ERROR(-3), "requested length does not fit in int");
253 return 0;
254 }
255
256 /* write len bytes from buf (the return value will fit in an int) */
257 return (int)gz_write(state, buf, len);
258}
259
260/* -- see zlib.h -- */
261z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, z_size_t nitems,
262 gzFile file) {
263 z_size_t len;
264 gz_statep state;
265
266 /* get internal structure */
267 if (file == NULL((void *)0))
1
Assuming 'file' is not equal to NULL
2
Taking false branch
268 return 0;
269 state = (gz_statep)file;
270
271 /* check that we're writing and that there's no error */
272 if (state->mode != GZ_WRITE31153 || state->err != Z_OK0)
3
Assuming field 'mode' is equal to GZ_WRITE
4
Assuming field 'err' is equal to Z_OK
5
Taking false branch
273 return 0;
274
275 /* compute bytes to read -- error on overflow */
276 len = nitems * size;
277 if (size && len / size != nitems) {
6
Assuming 'size' is 0
278 gz_error(state, Z_STREAM_ERROR(-2), "request does not fit in a size_t");
279 return 0;
280 }
281
282 /* write len bytes to buf, return the number of full items written */
283 return len ? gz_write(state, buf, len) / size : 0;
7
Assuming 'len' is not equal to 0
8
'?' condition is true
9
Division by zero
284}
285
286/* -- see zlib.h -- */
287int ZEXPORT gzputc(gzFile file, int c) {
288 unsigned have;
289 unsigned char buf[1];
290 gz_statep state;
291 z_streamp strm;
292
293 /* get internal structure */
294 if (file == NULL((void *)0))
295 return -1;
296 state = (gz_statep)file;
297 strm = &(state->strm);
298
299 /* check that we're writing and that there's no error */
300 if (state->mode != GZ_WRITE31153 || state->err != Z_OK0)
301 return -1;
302
303 /* check for seek request */
304 if (state->seek) {
305 state->seek = 0;
306 if (gz_zero(state, state->skip) == -1)
307 return -1;
308 }
309
310 /* try writing to input buffer for speed (state->size == 0 if buffer not
311 initialized) */
312 if (state->size) {
313 if (strm->avail_in == 0)
314 strm->next_in = state->in;
315 have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
316 if (have < state->size) {
317 state->in[have] = (unsigned char)c;
318 strm->avail_in++;
319 state->x.pos++;
320 return c & 0xff;
321 }
322 }
323
324 /* no room in buffer or not initialized, use gz_write() */
325 buf[0] = (unsigned char)c;
326 if (gz_write(state, buf, 1) != 1)
327 return -1;
328 return c & 0xff;
329}
330
331/* -- see zlib.h -- */
332int ZEXPORT gzputs(gzFile file, const char *s) {
333 z_size_t len, put;
334 gz_statep state;
335
336 /* get internal structure */
337 if (file == NULL((void *)0))
338 return -1;
339 state = (gz_statep)file;
340
341 /* check that we're writing and that there's no error */
342 if (state->mode != GZ_WRITE31153 || state->err != Z_OK0)
343 return -1;
344
345 /* write string */
346 len = strlen(s);
347 if ((int)len < 0 || (unsigned)len != len) {
348 gz_error(state, Z_STREAM_ERROR(-2), "string length does not fit in int");
349 return -1;
350 }
351 put = gz_write(state, s, len);
352 return put < len ? -1 : (int)len;
353}
354
355#if defined(STDC) || defined(Z_HAVE_STDARG_H)
356#include <stdarg.h>
357
358/* -- see zlib.h -- */
359int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) {
360 int len;
361 unsigned left;
362 char *next;
363 gz_statep state;
364 z_streamp strm;
365
366 /* get internal structure */
367 if (file == NULL((void *)0))
368 return Z_STREAM_ERROR(-2);
369 state = (gz_statep)file;
370 strm = &(state->strm);
371
372 /* check that we're writing and that there's no error */
373 if (state->mode != GZ_WRITE31153 || state->err != Z_OK0)
374 return Z_STREAM_ERROR(-2);
375
376 /* make sure we have some buffer space */
377 if (state->size == 0 && gz_init(state) == -1)
378 return state->err;
379
380 /* check for seek request */
381 if (state->seek) {
382 state->seek = 0;
383 if (gz_zero(state, state->skip) == -1)
384 return state->err;
385 }
386
387 /* do the printf() into the input buffer, put length in len -- the input
388 buffer is double-sized just for this function, so there is guaranteed to
389 be state->size bytes available after the current contents */
390 if (strm->avail_in == 0)
391 strm->next_in = state->in;
392 next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in);
393 next[state->size - 1] = 0;
394#ifdef NO_vsnprintf
395# ifdef HAS_vsprintf_void
396 (void)vsprintf(next, format, va);
397 for (len = 0; len < state->size; len++)
398 if (next[len] == 0) break;
399# else
400 len = vsprintf(next, format, va);
401# endif
402#else
403# ifdef HAS_vsnprintf_void
404 (void)vsnprintf(next, state->size, format, va);
405 len = strlen(next);
406# else
407 len = vsnprintf(next, state->size, format, va);
408# endif
409#endif
410
411 /* check that printf() results fit in buffer */
412 if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0)
413 return 0;
414
415 /* update buffer and position, compress first half if past that */
416 strm->avail_in += (unsigned)len;
417 state->x.pos += len;
418 if (strm->avail_in >= state->size) {
419 left = strm->avail_in - state->size;
420 strm->avail_in = state->size;
421 if (gz_comp(state, Z_NO_FLUSH0) == -1)
422 return state->err;
423 memmove(state->in, state->in + state->size, left);
424 strm->next_in = state->in;
425 strm->avail_in = left;
426 }
427 return len;
428}
429
430int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) {
431 va_list va;
432 int ret;
433
434 va_start(va, format)__builtin_va_start((va), format);
435 ret = gzvprintf(file, format, va);
436 va_end(va)__builtin_va_end((va));
437 return ret;
438}
439
440#else /* !STDC && !Z_HAVE_STDARG_H */
441
442/* -- see zlib.h -- */
443int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3,
444 int a4, int a5, int a6, int a7, int a8, int a9, int a10,
445 int a11, int a12, int a13, int a14, int a15, int a16,
446 int a17, int a18, int a19, int a20) {
447 unsigned len, left;
448 char *next;
449 gz_statep state;
450 z_streamp strm;
451
452 /* get internal structure */
453 if (file == NULL((void *)0))
454 return Z_STREAM_ERROR(-2);
455 state = (gz_statep)file;
456 strm = &(state->strm);
457
458 /* check that can really pass pointer in ints */
459 if (sizeof(int) != sizeof(void *))
460 return Z_STREAM_ERROR(-2);
461
462 /* check that we're writing and that there's no error */
463 if (state->mode != GZ_WRITE31153 || state->err != Z_OK0)
464 return Z_STREAM_ERROR(-2);
465
466 /* make sure we have some buffer space */
467 if (state->size == 0 && gz_init(state) == -1)
468 return state->error;
469
470 /* check for seek request */
471 if (state->seek) {
472 state->seek = 0;
473 if (gz_zero(state, state->skip) == -1)
474 return state->error;
475 }
476
477 /* do the printf() into the input buffer, put length in len -- the input
478 buffer is double-sized just for this function, so there is guaranteed to
479 be state->size bytes available after the current contents */
480 if (strm->avail_in == 0)
481 strm->next_in = state->in;
482 next = (char *)(strm->next_in + strm->avail_in);
483 next[state->size - 1] = 0;
484#ifdef NO_snprintf
485# ifdef HAS_sprintf_void
486 sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12,
487 a13, a14, a15, a16, a17, a18, a19, a20);
488 for (len = 0; len < size; len++)
489 if (next[len] == 0)
490 break;
491# else
492 len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
493 a12, a13, a14, a15, a16, a17, a18, a19, a20);
494# endif
495#else
496# ifdef HAS_snprintf_void
497 snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9,
498 a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
499 len = strlen(next);
500# else
501 len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8,
502 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
503# endif
504#endif
505
506 /* check that printf() results fit in buffer */
507 if (len == 0 || len >= state->size || next[state->size - 1] != 0)
508 return 0;
509
510 /* update buffer and position, compress first half if past that */
511 strm->avail_in += len;
512 state->x.pos += len;
513 if (strm->avail_in >= state->size) {
514 left = strm->avail_in - state->size;
515 strm->avail_in = state->size;
516 if (gz_comp(state, Z_NO_FLUSH0) == -1)
517 return state->err;
518 memmove(state->in, state->in + state->size, left);
519 strm->next_in = state->in;
520 strm->avail_in = left;
521 }
522 return (int)len;
523}
524
525#endif
526
527/* -- see zlib.h -- */
528int ZEXPORT gzflush(gzFile file, int flush) {
529 gz_statep state;
530
531 /* get internal structure */
532 if (file == NULL((void *)0))
533 return Z_STREAM_ERROR(-2);
534 state = (gz_statep)file;
535
536 /* check that we're writing and that there's no error */
537 if (state->mode != GZ_WRITE31153 || state->err != Z_OK0)
538 return Z_STREAM_ERROR(-2);
539
540 /* check flush parameter */
541 if (flush < 0 || flush > Z_FINISH4)
542 return Z_STREAM_ERROR(-2);
543
544 /* check for seek request */
545 if (state->seek) {
546 state->seek = 0;
547 if (gz_zero(state, state->skip) == -1)
548 return state->err;
549 }
550
551 /* compress remaining data with requested flush */
552 (void)gz_comp(state, flush);
553 return state->err;
554}
555
556/* -- see zlib.h -- */
557int ZEXPORT gzsetparams(gzFile file, int level, int strategy) {
558 gz_statep state;
559 z_streamp strm;
560
561 /* get internal structure */
562 if (file == NULL((void *)0))
563 return Z_STREAM_ERROR(-2);
564 state = (gz_statep)file;
565 strm = &(state->strm);
566
567 /* check that we're writing and that there's no error */
568 if (state->mode != GZ_WRITE31153 || state->err != Z_OK0 || state->direct)
569 return Z_STREAM_ERROR(-2);
570
571 /* if no change is requested, then do nothing */
572 if (level == state->level && strategy == state->strategy)
573 return Z_OK0;
574
575 /* check for seek request */
576 if (state->seek) {
577 state->seek = 0;
578 if (gz_zero(state, state->skip) == -1)
579 return state->err;
580 }
581
582 /* change compression parameters for subsequent input */
583 if (state->size) {
584 /* flush previous input with previous parameters before changing */
585 if (strm->avail_in && gz_comp(state, Z_BLOCK5) == -1)
586 return state->err;
587 deflateParams(strm, level, strategy);
588 }
589 state->level = level;
590 state->strategy = strategy;
591 return Z_OK0;
592}
593
594/* -- see zlib.h -- */
595int ZEXPORT gzclose_w(gzFile file) {
596 int ret = Z_OK0;
597 gz_statep state;
598
599 /* get internal structure */
600 if (file == NULL((void *)0))
601 return Z_STREAM_ERROR(-2);
602 state = (gz_statep)file;
603
604 /* check that we're writing */
605 if (state->mode != GZ_WRITE31153)
606 return Z_STREAM_ERROR(-2);
607
608 /* check for seek request */
609 if (state->seek) {
610 state->seek = 0;
611 if (gz_zero(state, state->skip) == -1)
612 ret = state->err;
613 }
614
615 /* flush, free memory, and close file */
616 if (gz_comp(state, Z_FINISH4) == -1)
617 ret = state->err;
618 if (state->size) {
619 if (!state->direct) {
620 (void)deflateEnd(&(state->strm));
621 free(state->out);
622 }
623 free(state->in);
624 }
625 gz_error(state, Z_OK0, NULL((void *)0));
626 free(state->path);
627 if (close(state->fd) == -1)
628 ret = Z_ERRNO(-1);
629 free(state);
630 return ret;
631}