Bug Summary

File:root/firefox-clang/modules/zlib/src/gzwrite.c
Warning:line 470, column 48
Subtraction of a null pointer (via field 'next_in') and a non-null pointer (via field 'in') results in undefined behavior

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -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 -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/modules/zlib/src -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/modules/zlib/src -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -I /root/firefox-clang/modules/zlib/src -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/modules/zlib/src -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=tautological-type-limit-compare -Wno-range-loop-analysis -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-unknown-warning-option -Wno-character-conversion -Wno-deprecated-non-prototype -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-11-12-001017-1011516-1 -x c /root/firefox-clang/modules/zlib/src/gzwrite.c
1/* gzwrite.c -- zlib functions for writing gzip files
2 * Copyright (C) 2004-2026 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_initMOZ_Z_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)) {
8
Assuming field 'in' is not equal to NULL
9
Taking false branch
18 gz_errorMOZ_Z_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) {
10
Assuming field 'direct' is not equal to 0, which participates in a condition later
11
Taking false branch
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_errorMOZ_Z_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,MOZ_Z_deflateInit2_((strm),(state->level),(8),(15 + 16),(8
), (state->strategy), "1.4", (int)sizeof(z_stream))
37 MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy)MOZ_Z_deflateInit2_((strm),(state->level),(8),(15 + 16),(8
), (state->strategy), "1.4", (int)sizeof(z_stream))
;
38 if (ret != Z_OK0) {
39 free(state->out);
40 free(state->in);
41 gz_errorMOZ_Z_gz_error(state, Z_MEM_ERROR(-4), "out of memory");
42 return -1;
43 }
44 }
45 strm->next_in = NULL((void*)0);
12
Null pointer value stored to field 'next_in'
46
47 /* mark state as initialized */
48 state->size = state->want;
49
50 /* initialize write buffer if compressing */
51 if (!state->direct
12.1
Field 'direct' is not equal to 0
) {
13
Taking false branch
52 strm->avail_out = state->size;
53 strm->next_out = state->out;
54 state->x.next = strm->next_out;
55 }
56 return 0;
14
Returning without writing to 'state->skip', which participates in a condition later
15
Returning without writing to 'state->err', which participates in a condition later
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_compMOZ_Z_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_initMOZ_Z_gz_init(state) == -1)
72 return -1;
73
74 /* write directly if requested */
75 if (state->direct) {
76 while (strm->avail_in) {
77 errno(*__errno_location ()) = 0;
78 state->again = 0;
79 put = strm->avail_in > max ? max : strm->avail_in;
80 writ = (int)write(state->fd, strm->next_in, put);
81 if (writ < 0) {
82 if (BLOCKED(errno)(((*__errno_location ())) == 11 || ((*__errno_location ())) ==
11)
)
83 state->again = 1;
84 gz_errorMOZ_Z_gz_error(state, Z_ERRNO(-1), zstrerror()strerror((*__errno_location ())));
85 return -1;
86 }
87 strm->avail_in -= (unsigned)writ;
88 strm->next_in += writ;
89 }
90 return 0;
91 }
92
93 /* check for a pending reset */
94 if (state->reset) {
95 /* don't start a new gzip member unless there is data to write and
96 we're not flushing */
97 if (strm->avail_in == 0 && flush == Z_NO_FLUSH0)
98 return 0;
99 deflateResetMOZ_Z_deflateReset(strm);
100 state->reset = 0;
101 }
102
103 /* run deflate() on provided input until it produces no more output */
104 ret = Z_OK0;
105 do {
106 /* write out current buffer contents if full, or if flushing, but if
107 doing Z_FINISH then don't write until we get to Z_STREAM_END */
108 if (strm->avail_out == 0 || (flush != Z_NO_FLUSH0 &&
109 (flush != Z_FINISH4 || ret == Z_STREAM_END1))) {
110 while (strm->next_out > state->x.next) {
111 errno(*__errno_location ()) = 0;
112 state->again = 0;
113 put = strm->next_out - state->x.next > (int)max ? max :
114 (unsigned)(strm->next_out - state->x.next);
115 writ = (int)write(state->fd, state->x.next, put);
116 if (writ < 0) {
117 if (BLOCKED(errno)(((*__errno_location ())) == 11 || ((*__errno_location ())) ==
11)
)
118 state->again = 1;
119 gz_errorMOZ_Z_gz_error(state, Z_ERRNO(-1), zstrerror()strerror((*__errno_location ())));
120 return -1;
121 }
122 state->x.next += writ;
123 }
124 if (strm->avail_out == 0) {
125 strm->avail_out = state->size;
126 strm->next_out = state->out;
127 state->x.next = state->out;
128 }
129 }
130
131 /* compress */
132 have = strm->avail_out;
133 ret = deflateMOZ_Z_deflate(strm, flush);
134 if (ret == Z_STREAM_ERROR(-2)) {
135 gz_errorMOZ_Z_gz_error(state, Z_STREAM_ERROR(-2),
136 "internal error: deflate stream corrupt");
137 return -1;
138 }
139 have -= strm->avail_out;
140 } while (have);
141
142 /* if that completed a deflate stream, allow another to start */
143 if (flush == Z_FINISH4)
144 state->reset = 1;
145
146 /* all done, no errors */
147 return 0;
148}
149
150/* Compress state->skip (> 0) zeros to output. Return -1 on a write error or
151 memory allocation failure by gz_comp(), or 0 on success. state->skip is
152 updated with the number of successfully written zeros, in case there is a
153 stall on a non-blocking write destination. */
154localstatic int gz_zeroMOZ_Z_gz_zero(gz_statep state) {
155 int first, ret;
156 unsigned n;
157 z_streamp strm = &(state->strm);
158
159 /* allocate memory if this is the first time through -- the input buffer
160 must exist before it is zeroed below */
161 if (state->size == 0 && gz_initMOZ_Z_gz_init(state) == -1)
162 return -1;
163
164 /* consume whatever's left in the input buffer */
165 if (strm->avail_in && gz_compMOZ_Z_gz_comp(state, Z_NO_FLUSH0) == -1)
166 return -1;
167
168 /* compress state->skip zeros */
169 first = 1;
170 do {
171 n = GT_OFF(state->size)(sizeof(int) == sizeof(off_t) && (state->size) >
MOZ_Z_gz_intmax())
|| (z_off64_toff_t)state->size > state->skip ?
172 (unsigned)state->skip : state->size;
173 if (first) {
174 memset(state->in, 0, n);
175 first = 0;
176 }
177 strm->avail_in = n;
178 strm->next_in = state->in;
179 ret = gz_compMOZ_Z_gz_comp(state, Z_NO_FLUSH0);
180 n -= strm->avail_in;
181 state->x.pos += n;
182 state->skip -= n;
183 if (ret == -1) {
184 /* discard any unconsumed zero fill -- it was not yet accounted
185 for in state->skip, so it will be generated again when the
186 operation is retried */
187 strm->avail_in = 0;
188 strm->next_in = state->in;
189 return -1;
190 }
191 } while (state->skip);
192 return 0;
193}
194
195/* Write len bytes from buf to file. Return the number of bytes written. If
196 the returned value is less than len, then there was an error. If the error
197 was a non-blocking stall, then the number of bytes consumed is returned.
198 For any other error, 0 is returned. */
199localstatic z_size_t gz_writeMOZ_Z_gz_write(gz_statep state, voidpc buf, z_size_t len) {
200 z_size_t put = len;
201 int ret;
202
203 /* if len is zero, avoid unnecessary operations */
204 if (len == 0)
205 return 0;
206
207 /* allocate memory if this is the first time through */
208 if (state->size == 0 && gz_initMOZ_Z_gz_init(state) == -1)
209 return 0;
210
211 /* check for seek request */
212 if (state->skip && gz_zeroMOZ_Z_gz_zero(state) == -1)
213 return 0;
214
215 /* for small len, copy to input buffer, otherwise compress directly */
216 if (len < state->size) {
217 /* copy to input buffer, compress when full */
218 for (;;) {
219 unsigned have, copy;
220
221 if (state->strm.avail_in == 0)
222 state->strm.next_in = state->in;
223 have = (unsigned)((state->strm.next_in + state->strm.avail_in) -
224 state->in);
225 copy = state->size - have;
226 if (copy > len)
227 copy = (unsigned)len;
228 memcpy(state->in + have, buf, copy);
229 state->strm.avail_in += copy;
230 state->x.pos += copy;
231 buf = (const char *)buf + copy;
232 len -= copy;
233 if (len == 0)
234 break;
235 if (gz_compMOZ_Z_gz_comp(state, Z_NO_FLUSH0) == -1)
236 return state->again ? put - len : 0;
237 }
238 }
239 else {
240 /* consume whatever's left in the input buffer */
241 if (state->strm.avail_in && gz_compMOZ_Z_gz_comp(state, Z_NO_FLUSH0) == -1)
242 return 0;
243
244 /* directly compress user buffer to file */
245 state->strm.next_in = (z_const Bytef *)buf;
246 do {
247 unsigned n = (unsigned)-1;
248
249 if (n > len)
250 n = (unsigned)len;
251 state->strm.avail_in = n;
252 ret = gz_compMOZ_Z_gz_comp(state, Z_NO_FLUSH0);
253 n -= state->strm.avail_in;
254 state->x.pos += n;
255 len -= n;
256 if (ret == -1) {
257 state->strm.avail_in = 0;
258 state->strm.next_in = state->in;
259 return state->again ? put - len : 0;
260 }
261 } while (len);
262 state->strm.next_in = state->in;
263 }
264
265 /* input was all buffered or compressed */
266 return put;
267}
268
269/* -- see zlib.h -- */
270int ZEXPORT gzwriteMOZ_Z_gzwrite(gzFile file, voidpc buf, unsigned len) {
271 gz_statep state;
272
273 /* get internal structure */
274 if (file == NULL((void*)0))
275 return 0;
276 state = (gz_statep)file;
277
278 /* check that we're writing and that there's no (serious) error */
279 if (state->mode != GZ_WRITE31153 || (state->err != Z_OK0 && !state->again))
280 return 0;
281 gz_errorMOZ_Z_gz_error(state, Z_OK0, NULL((void*)0));
282
283 /* since an int is returned, make sure len fits in one, otherwise return
284 with an error (this avoids a flaw in the interface) */
285 if ((int)len < 0) {
286 gz_errorMOZ_Z_gz_error(state, Z_DATA_ERROR(-3), "requested length does not fit in int");
287 return 0;
288 }
289
290 /* write len bytes from buf (the return value will fit in an int) */
291 return (int)gz_writeMOZ_Z_gz_write(state, buf, len);
292}
293
294/* -- see zlib.h -- */
295z_size_t ZEXPORT gzfwriteMOZ_Z_gzfwrite(voidpc buf, z_size_t size, z_size_t nitems,
296 gzFile file) {
297 z_size_t len;
298 gz_statep state;
299
300 /* get internal structure */
301 if (file == NULL((void*)0))
302 return 0;
303 state = (gz_statep)file;
304
305 /* check that we're writing and that there's no (serious) error */
306 if (state->mode != GZ_WRITE31153 || (state->err != Z_OK0 && !state->again))
307 return 0;
308 gz_errorMOZ_Z_gz_error(state, Z_OK0, NULL((void*)0));
309
310 /* compute bytes to read -- error on overflow */
311 len = nitems * size;
312 if (size && len / size != nitems) {
313 gz_errorMOZ_Z_gz_error(state, Z_STREAM_ERROR(-2), "request does not fit in a size_t");
314 return 0;
315 }
316
317 /* write len bytes to buf, return the number of full items written */
318 return len ? gz_writeMOZ_Z_gz_write(state, buf, len) / size : 0;
319}
320
321/* -- see zlib.h -- */
322int ZEXPORT gzputcMOZ_Z_gzputc(gzFile file, int c) {
323 unsigned have;
324 unsigned char buf[1];
325 gz_statep state;
326 z_streamp strm;
327
328 /* get internal structure */
329 if (file == NULL((void*)0))
330 return -1;
331 state = (gz_statep)file;
332 strm = &(state->strm);
333
334 /* check that we're writing and that there's no (serious) error */
335 if (state->mode != GZ_WRITE31153 || (state->err != Z_OK0 && !state->again))
336 return -1;
337 gz_errorMOZ_Z_gz_error(state, Z_OK0, NULL((void*)0));
338
339 /* check for seek request */
340 if (state->skip && gz_zeroMOZ_Z_gz_zero(state) == -1)
341 return -1;
342
343 /* try writing to input buffer for speed (state->size == 0 if buffer not
344 initialized) */
345 if (state->size) {
346 if (strm->avail_in == 0)
347 strm->next_in = state->in;
348 have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
349 if (have < state->size) {
350 state->in[have] = (unsigned char)c;
351 strm->avail_in++;
352 state->x.pos++;
353 return c & 0xff;
354 }
355 }
356
357 /* no room in buffer or not initialized, use gz_write() */
358 buf[0] = (unsigned char)c;
359 if (gz_writeMOZ_Z_gz_write(state, buf, 1) != 1)
360 return -1;
361 return c & 0xff;
362}
363
364/* -- see zlib.h -- */
365int ZEXPORT gzputsMOZ_Z_gzputs(gzFile file, const char *s) {
366 z_size_t len, put;
367 gz_statep state;
368
369 /* get internal structure */
370 if (file == NULL((void*)0))
371 return -1;
372 state = (gz_statep)file;
373
374 /* check that we're writing and that there's no (serious) error */
375 if (state->mode != GZ_WRITE31153 || (state->err != Z_OK0 && !state->again))
376 return -1;
377 gz_errorMOZ_Z_gz_error(state, Z_OK0, NULL((void*)0));
378
379 /* write string */
380 len = strlen(s);
381 if ((int)len < 0 || (unsigned)len != len) {
382 gz_errorMOZ_Z_gz_error(state, Z_STREAM_ERROR(-2), "string length does not fit in int");
383 return -1;
384 }
385 put = gz_writeMOZ_Z_gz_write(state, s, len);
386 return len && put == 0 ? -1 : (int)put;
387}
388
389#if (((!defined(STDC) && !defined(Z_HAVE_STDARG_H)) || \
390 !defined(NO_vsnprintf)) && \
391 (defined(STDC) || defined(Z_HAVE_STDARG_H) || \
392 !defined(NO_snprintf))) || defined(ZLIB_INSECURE)
393/* If the second half of the input buffer is occupied, write out the contents.
394 If there is any input remaining due to a non-blocking stall on write, move
395 it to the start of the buffer. Return true if this did not open up the
396 second half of the buffer. state->err should be checked after this to
397 handle a gz_comp() error. */
398localstatic int gz_vacate(gz_statep state) {
399 z_streamp strm;
400
401 strm = &(state->strm);
402 if (strm->next_in
18.1
Field 'next_in' is equal to NULL
== NULL((void*)0) ||
403 strm->next_in + strm->avail_in <= state->in + state->size)
404 return 0;
19
Returning without writing to 'state->err', which participates in a condition later
20
Returning without writing to 'state->strm.next_in'
405 (void)gz_compMOZ_Z_gz_comp(state, Z_NO_FLUSH0);
406 if (strm->avail_in == 0) {
407 strm->next_in = state->in;
408 return 0;
409 }
410 memmove(state->in, strm->next_in, strm->avail_in);
411 strm->next_in = state->in;
412 return strm->avail_in > state->size;
413}
414#endif
415
416#if defined(STDC) || defined(Z_HAVE_STDARG_H)
417#include <stdarg.h>
418
419/* -- see zlib.h -- */
420int ZEXPORTVA gzvprintfMOZ_Z_gzvprintf(gzFile file, const char *format, va_list va) {
421#if defined(NO_vsnprintf) && !defined(ZLIB_INSECURE)
422#warning "vsnprintf() not available -- gzprintf() stub returns Z_STREAM_ERROR"
423#warning "you can recompile with ZLIB_INSECURE defined to use vsprintf()"
424 /* prevent use of insecure vsprintf(), unless purposefully requested */
425 (void)file, (void)format, (void)va;
426 return Z_STREAM_ERROR(-2);
427#else
428 int len, ret;
429 char *next;
430 gz_statep state;
431 z_streamp strm;
432
433 /* get internal structure */
434 if (file == NULL((void*)0))
2
Assuming 'file' is not equal to NULL
3
Taking false branch
435 return Z_STREAM_ERROR(-2);
436 state = (gz_statep)file;
437 strm = &(state->strm);
438
439 /* check that we're writing and that there's no (serious) error */
440 if (state->mode != GZ_WRITE31153 || (state->err != Z_OK0 && !state->again))
4
Assuming field 'mode' is equal to GZ_WRITE
5
Assuming field 'err' is equal to Z_OK
441 return Z_STREAM_ERROR(-2);
442 gz_errorMOZ_Z_gz_error(state, Z_OK0, NULL((void*)0));
443
444 /* make sure we have some buffer space */
445 if (state->size == 0 && gz_initMOZ_Z_gz_init(state) == -1)
6
Assuming field 'size' is equal to 0
7
Calling 'MOZ_Z_gz_init'
16
Returning from 'MOZ_Z_gz_init'
446 return state->err;
447
448 /* check for seek request */
449 if (state->skip && gz_zeroMOZ_Z_gz_zero(state) == -1)
17
Assuming field 'skip' is 0
450 return state->err;
451
452 /* do the printf() into the input buffer, put length in len -- the input
453 buffer is double-sized just for this function, so there should be
454 state->size bytes available after the current contents */
455 ret = gz_vacate(state);
18
Calling 'gz_vacate'
21
Returning from 'gz_vacate'
456 if (state->err) {
22
Assuming field 'err' is 0
23
Taking false branch
457 if (ret && state->again) {
458 /* There was a non-blocking stall on write, resulting in the part
459 of the second half of the output buffer being occupied. Return
460 a Z_BUF_ERROR to let the application know that this gzprintf()
461 needs to be retried. */
462 gz_errorMOZ_Z_gz_error(state, Z_BUF_ERROR(-5), "stalled write on gzprintf");
463 return state->err;
464 }
465 if (!state->again)
466 return state->err;
467 }
468 if (strm->avail_in == 0)
24
Assuming field 'avail_in' is not equal to 0
25
Taking false branch
469 strm->next_in = state->in;
470 next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in);
26
Subtraction of a null pointer (via field 'next_in') and a non-null pointer (via field 'in') results in undefined behavior
471 next[state->size - 1] = 0;
472#ifdef NO_vsnprintf
473# ifdef HAS_vsprintf_void
474 (void)vsprintf(next, format, va);
475 for (len = 0; len < state->size; len++)
476 if (next[len] == 0) break;
477# else
478 len = vsprintf(next, format, va);
479# endif
480#else
481# ifdef HAS_vsnprintf_void
482 (void)vsnprintf(next, state->size, format, va);
483 len = strlen(next);
484# else
485 len = vsnprintf(next, state->size, format, va);
486# endif
487#endif
488
489 /* check that printf() results fit in buffer */
490 if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0)
491 return 0;
492
493 /* update buffer and position */
494 strm->avail_in += (unsigned)len;
495 state->x.pos += len;
496
497 /* write out buffer if more than half is occupied */
498 ret = gz_vacate(state);
499 if (ret) {
500 /* discard unwritten formatted output */
501 strm->avail_in -= (unsigned)len;
502 state->x.pos -= len;
503 if (state->again)
504 gz_errorMOZ_Z_gz_error(state, Z_BUF_ERROR(-5), "stalled write on gzprintf");
505 return state->err;
506 }
507 if (state->err && !state->again)
508 return state->err;
509 return len;
510#endif
511}
512
513int ZEXPORTVA gzprintfMOZ_Z_gzprintf(gzFile file, const char *format, ...) {
514 va_list va;
515 int ret;
516
517 va_start(va, format)__builtin_va_start(va, format);
518 ret = gzvprintfMOZ_Z_gzvprintf(file, format, va);
1
Calling 'MOZ_Z_gzvprintf'
519 va_end(va)__builtin_va_end(va);
520 return ret;
521}
522
523#else /* !STDC && !Z_HAVE_STDARG_H */
524
525/* -- see zlib.h -- */
526int ZEXPORTVA gzprintfMOZ_Z_gzprintf(gzFile file, const char *format, int a1, int a2, int a3,
527 int a4, int a5, int a6, int a7, int a8, int a9, int a10,
528 int a11, int a12, int a13, int a14, int a15, int a16,
529 int a17, int a18, int a19, int a20) {
530#if defined(NO_snprintf) && !defined(ZLIB_INSECURE)
531#warning "snprintf() not available -- gzprintf() stub returns Z_STREAM_ERROR"
532#warning "you can recompile with ZLIB_INSECURE defined to use sprintf()"
533 /* prevent use of insecure sprintf(), unless purposefully requested */
534 (void)file, (void)format, (void)a1, (void)a2, (void)a3, (void)a4, (void)a5,
535 (void)a6, (void)a7, (void)a8, (void)a9, (void)a10, (void)a11, (void)a12,
536 (void)a13, (void)a14, (void)a15, (void)a16, (void)a17, (void)a18,
537 (void)a19, (void)a20;
538 return Z_STREAM_ERROR(-2);
539#else
540 int ret;
541 unsigned len, left;
542 char *next;
543 gz_statep state;
544 z_streamp strm;
545
546 /* get internal structure */
547 if (file == NULL((void*)0))
548 return Z_STREAM_ERROR(-2);
549 state = (gz_statep)file;
550 strm = &(state->strm);
551
552 /* check that can really pass pointer in ints */
553 if (sizeof(int) != sizeof(void *))
554 return Z_STREAM_ERROR(-2);
555
556 /* check that we're writing and that there's no (serious) error */
557 if (state->mode != GZ_WRITE31153 || (state->err != Z_OK0 && !state->again))
558 return Z_STREAM_ERROR(-2);
559 gz_errorMOZ_Z_gz_error(state, Z_OK0, NULL((void*)0));
560
561 /* make sure we have some buffer space */
562 if (state->size == 0 && gz_initMOZ_Z_gz_init(state) == -1)
563 return state->err;
564
565 /* check for seek request */
566 if (state->skip && gz_zeroMOZ_Z_gz_zero(state) == -1)
567 return state->err;
568
569 /* do the printf() into the input buffer, put length in len -- the input
570 buffer is double-sized just for this function, so there is guaranteed to
571 be state->size bytes available after the current contents */
572 ret = gz_vacate(state);
573 if (state->err) {
574 if (ret && state->again) {
575 /* There was a non-blocking stall on write, resulting in the part
576 of the second half of the output buffer being occupied. Return
577 a Z_BUF_ERROR to let the application know that this gzprintf()
578 needs to be retried. */
579 gz_errorMOZ_Z_gz_error(state, Z_BUF_ERROR(-5), "stalled write on gzprintf");
580 return state->err;
581 }
582 if (!state->again)
583 return state->err;
584 }
585 if (strm->avail_in == 0)
586 strm->next_in = state->in;
587 next = (char *)(strm->next_in + strm->avail_in);
588 next[state->size - 1] = 0;
589#ifdef NO_snprintf
590# ifdef HAS_sprintf_void
591 sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12,
592 a13, a14, a15, a16, a17, a18, a19, a20);
593 for (len = 0; len < size; len++)
594 if (next[len] == 0)
595 break;
596# else
597 len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
598 a12, a13, a14, a15, a16, a17, a18, a19, a20);
599# endif
600#else
601# ifdef HAS_snprintf_void
602 snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9,
603 a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
604 len = strlen(next);
605# else
606 len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8,
607 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
608# endif
609#endif
610
611 /* check that printf() results fit in buffer */
612 if (len == 0 || len >= state->size || next[state->size - 1] != 0)
613 return 0;
614
615 /* update buffer and position, compress first half if past that */
616 strm->avail_in += len;
617 state->x.pos += len;
618
619 /* write out buffer if more than half is occupied */
620 ret = gz_vacate(state);
621 if (ret) {
622 /* discard unwritten formatted output */
623 strm->avail_in -= (unsigned)len;
624 state->x.pos -= len;
625 if (state->again)
626 gz_errorMOZ_Z_gz_error(state, Z_BUF_ERROR(-5), "stalled write on gzprintf");
627 return state->err;
628 }
629 if (state->err && !state->again)
630 return state->err;
631 return (int)len;
632#endif
633}
634
635#endif
636
637/* -- see zlib.h -- */
638int ZEXPORT gzflushMOZ_Z_gzflush(gzFile file, int flush) {
639 gz_statep state;
640
641 /* get internal structure */
642 if (file == NULL((void*)0))
643 return Z_STREAM_ERROR(-2);
644 state = (gz_statep)file;
645
646 /* check that we're writing and that there's no (serious) error */
647 if (state->mode != GZ_WRITE31153 || (state->err != Z_OK0 && !state->again))
648 return Z_STREAM_ERROR(-2);
649 gz_errorMOZ_Z_gz_error(state, Z_OK0, NULL((void*)0));
650
651 /* check flush parameter */
652 if (flush < 0 || flush > Z_FINISH4)
653 return Z_STREAM_ERROR(-2);
654
655 /* check for seek request */
656 if (state->skip && gz_zeroMOZ_Z_gz_zero(state) == -1)
657 return state->err;
658
659 /* compress remaining data with requested flush */
660 (void)gz_compMOZ_Z_gz_comp(state, flush);
661 return state->err;
662}
663
664/* -- see zlib.h -- */
665int ZEXPORT gzsetparamsMOZ_Z_gzsetparams(gzFile file, int level, int strategy) {
666 gz_statep state;
667 z_streamp strm;
668
669 /* get internal structure */
670 if (file == NULL((void*)0))
671 return Z_STREAM_ERROR(-2);
672 state = (gz_statep)file;
673 strm = &(state->strm);
674
675 /* check that we're compressing and that there's no (serious) error */
676 if (state->mode != GZ_WRITE31153 || (state->err != Z_OK0 && !state->again) ||
677 state->direct)
678 return Z_STREAM_ERROR(-2);
679 gz_errorMOZ_Z_gz_error(state, Z_OK0, NULL((void*)0));
680
681 /* if no change is requested, then do nothing */
682 if (level == state->level && strategy == state->strategy)
683 return Z_OK0;
684
685 /* check for seek request */
686 if (state->skip && gz_zeroMOZ_Z_gz_zero(state) == -1)
687 return state->err;
688
689 /* change compression parameters for subsequent input */
690 if (state->size) {
691 /* flush previous input with previous parameters before changing */
692 if (strm->avail_in && gz_compMOZ_Z_gz_comp(state, Z_BLOCK5) == -1)
693 return state->err;
694 deflateParamsMOZ_Z_deflateParams(strm, level, strategy);
695 }
696 state->level = level;
697 state->strategy = strategy;
698 return Z_OK0;
699}
700
701/* -- see zlib.h -- */
702int ZEXPORT gzclose_wMOZ_Z_gzclose_w(gzFile file) {
703 int ret = Z_OK0;
704 gz_statep state;
705
706 /* get internal structure */
707 if (file == NULL((void*)0))
708 return Z_STREAM_ERROR(-2);
709 state = (gz_statep)file;
710
711 /* check that we're writing */
712 if (state->mode != GZ_WRITE31153)
713 return Z_STREAM_ERROR(-2);
714
715 /* check for seek request */
716 if (state->skip && gz_zeroMOZ_Z_gz_zero(state) == -1)
717 ret = state->err;
718
719 /* flush, free memory, and close file */
720 if (gz_compMOZ_Z_gz_comp(state, Z_FINISH4) == -1)
721 ret = state->err;
722 if (state->size) {
723 if (!state->direct) {
724 (void)deflateEndMOZ_Z_deflateEnd(&(state->strm));
725 free(state->out);
726 }
727 free(state->in);
728 }
729 gz_errorMOZ_Z_gz_error(state, Z_OK0, NULL((void*)0));
730 free(state->path);
731 if (close(state->fd) == -1)
732 ret = Z_ERRNO(-1);
733 free(state);
734 return ret;
735}