From: Alexander Bluhm Subject: Re: zlib 1.3.2 To: Theo Buehler Cc: tech@openbsd.org Date: Sat, 14 Mar 2026 15:52:18 +0100 On Wed, Mar 11, 2026 at 07:14:56AM +0100, Theo Buehler wrote: > This is a minor library bump since it adds six *_z functions that take > size_t instead of uLong (this only really matters for Windows). > > This is mostly a straightforward update minus the things I have already > cherry picked. compress.3 is updated by tweaking the docs in zlib.h. > > Additionally, there are two new diffs to upstream in sys/: > > 1. Remove the new '#warning zlib not thread-safe': amd64 boot blocks > are compiled with -Werror and this warning breaks the build. Since > there are no threads in the boot blocks this warning (for ZLB-01-004) > is irrelevant to OpenBSD. > > 2. In the kernel, compress.c is compiled without NULL in scope which > breaks due to newly added NULL checks in compress2_z(), so I > added an #include under the existing #ifdef _KERNEL > in zutil.h. Not sure if sys/param.h or something else is preferred. > > I tested this in an amd64 bulk and built releases on amd64, sparc64 and > arm64, which are the architectures I have readily available for this. > > The non-blocking device support added quite a bit of churn and so did > the deck chair shuffling for ZLB-01-004, in particular moving the > BUILDFIXED tables around. > > See the additions to the ChangeLog in the diff for more details. OK bluhm@ > Index: distrib/sets/lists/base/mi > =================================================================== > RCS file: /cvs/src/distrib/sets/lists/base/mi,v > diff -u -p -r1.1180 mi > --- distrib/sets/lists/base/mi 29 Jan 2026 16:05:43 -0000 1.1180 > +++ distrib/sets/lists/base/mi 11 Mar 2026 05:41:08 -0000 > @@ -795,7 +795,7 @@ > ./usr/lib/libtls.so.33.2 > ./usr/lib/libusbhid.so.7.1 > ./usr/lib/libutil.so.21.0 > -./usr/lib/libz.so.7.1 > +./usr/lib/libz.so.7.2 > ./usr/lib/locate > ./usr/lib/locate/src.db > ./usr/lib/pkgconfig > Index: lib/libz/ChangeLog > =================================================================== > RCS file: /cvs/src/lib/libz/ChangeLog,v > diff -u -p -r1.11 ChangeLog > --- lib/libz/ChangeLog 23 Jan 2024 14:46:27 -0000 1.11 > +++ lib/libz/ChangeLog 10 Mar 2026 06:44:12 -0000 > @@ -1,8 +1,56 @@ > > ChangeLog file for zlib > > -Changes in 1.3.1.1 (xx Jan 2024) > -- > +Changes in 1.3.2 (17 Feb 2026) > +- Continued rewrite of CMake build [Vollstrecker] > +- Various portability improvements > +- Various github workflow additions and improvements > +- Check for negative lengths in crc32_combine functions > +- Copy only the initialized window contents in inflateCopy > +- Prevent the use of insecure functions without an explicit request > +- Add compressBound_z and deflateBound_z functions for large values > +- Use atomics to build inflate fixed tables once > +- Add definition of ZLIB_INSECURE to build tests with c89 and c94 > +- Add --undefined option to ./configure for UBSan checker > +- Copy only the initialized deflate state in deflateCopy > +- Zero inflate state on allocation > +- Remove untgz from contrib > +- Add _z versions of the compress and uncompress functions > +- Vectorize the CRC-32 calculation on the s390x > +- Set bit 11 of the zip header flags in minizip if UTF-8 > +- Update OS/400 support > +- Add a test to configure to check for a working compiler > +- Check for invalid NULL pointer inputs to zlib operations > +- Add --mandir to ./configure to specify manual directory > +- Add LICENSE.Info-Zip to contrib/minizip > +- Remove vstudio projects in lieu of cmake-generated projects > +- Replace strcpy() with memcpy() in contrib/minizip > + > +Changes in 1.3.1.2 (8 Dec 2025) > +- Improve portability to RISC OS > +- Permit compiling contrib/minizip/unzip.c with decryption > +- Enable build of shared library on AIX > +- Make deflateBound() more conservative and handle Z_STREAM_END > +- Add zipAlreadyThere() to minizip zip.c to help avoid duplicates > +- Make z_off_t 64 bits by default > +- Add deflateUsed() function to get the used bits in the last byte > +- Avoid out-of-bounds pointer arithmetic in inflateCopy() > +- Add Haiku to configure for proper LDSHARED settings > +- Add Bazel targets > +- Complete rewrite of CMake build [Vollstrecker] > +- Clarify the use of errnum in gzerror() > +- Note that gzseek() requests are deferred until the next operation > +- Note the use of gzungetc() to run a deferred seek while reading > +- Fix bug in inflatePrime() for 16-bit ints > +- Add a "G" option to force gzip, disabling transparency in gzread() > +- Improve the discrimination between trailing garbage and bad gzip > +- Allow gzflush() to write empty gzip members > +- Remove redundant frees of point list on error in examples/zran.c > +- Clarify the use of inflateGetHeader() > +- Update links to the RFCs > +- Return all available uncompressed data on error in gzread.c > +- Support non-blocking devices in the gz* routines > +- Various other small improvements > > Changes in 1.3.1 (22 Jan 2024) > - Reject overflows of zip header fields in minizip > @@ -1365,7 +1413,7 @@ Changes in 1.0.6 (19 Jan 1998) > - use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) > - added makelcc.bat for lcc-win32 (Tom St Denis) > - in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) > -- Avoid expanded $Id. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. > +- Avoid expanded $Id. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion > - check for unistd.h in configure (for off_t) > - remove useless check parameter in inflate_blocks_free > - avoid useless assignment of s->check to itself in inflate_blocks_new > Index: lib/libz/README > =================================================================== > RCS file: /cvs/src/lib/libz/README,v > diff -u -p -r1.19 README > --- lib/libz/README 28 Jan 2024 16:10:51 -0000 1.19 > +++ lib/libz/README 10 Mar 2026 06:44:12 -0000 > @@ -1,10 +1,10 @@ > ZLIB DATA COMPRESSION LIBRARY > > -zlib 1.3.1.1 is a general purpose data compression library. All the code is > -thread safe. The data format used by the zlib library is described by RFCs > -(Request for Comments) 1950 to 1952 in the files > -http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and > -rfc1952 (gzip format). > +zlib 1.3.2 is a general purpose data compression library. All the code is > +thread safe (though see the FAQ for caveats). The data format used by the zlib > +library is described by RFCs (Request for Comments) 1950 to 1952 at > +https://datatracker.ietf.org/doc/html/rfc1950 (zlib format), rfc1951 (deflate > +format) and rfc1952 (gzip format). > > All functions of the compression library are documented in the file zlib.h > (volunteer to write man pages welcome, contact zlib@gzip.org). A usage example > @@ -21,17 +21,17 @@ make_vms.com. > > Questions about zlib should be sent to , or to Gilles Vollant > for the Windows DLL version. The zlib home page is > -http://zlib.net/ . Before reporting a problem, please check this site to > +https://zlib.net/ . Before reporting a problem, please check this site to > verify that you have the latest version of zlib; otherwise get the latest > version and check whether the problem still exists or not. > > -PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help. > +PLEASE read the zlib FAQ https://zlib.net/zlib_faq.html before asking for help. > > Mark Nelson wrote an article about zlib for the Jan. 1997 > issue of Dr. Dobb's Journal; a copy of the article is available at > -https://marknelson.us/posts/1997/01/01/zlib-engine.html . > +https://zlib.net/nelson/ . > > -The changes made in version 1.3.1.1 are documented in the file ChangeLog. > +The changes made in version 1.3.2 are documented in the file ChangeLog. > > Unsupported third party contributions are provided in directory contrib/ . > > @@ -43,9 +43,9 @@ can be found at https://github.com/pmqs/ > > A Python interface to zlib written by A.M. Kuchling is > available in Python 1.5 and later versions, see > -http://docs.python.org/library/zlib.html . > +https://docs.python.org/3/library/zlib.html . > > -zlib is built into tcl: http://wiki.tcl.tk/4610 . > +zlib is built into tcl: https://wiki.tcl-lang.org/page/zlib . > > An experimental package to read and write files in .zip format, written on top > of zlib by Gilles Vollant , is available in the > @@ -69,7 +69,7 @@ Notes for some targets: > - zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with > other compilers. Use "make test" to check your compiler. > > -- For PalmOs, see http://palmzlib.sourceforge.net/ > +- For PalmOs, see https://palmzlib.sourceforge.net/ > > > Acknowledgments: > @@ -81,7 +81,7 @@ Acknowledgments: > > Copyright notice: > > - (C) 1995-2024 Jean-loup Gailly and Mark Adler > + (C) 1995-2026 Jean-loup Gailly and Mark Adler > > This software is provided 'as-is', without any express or implied > warranty. In no event will the authors be held liable for any damages > Index: lib/libz/Symbols.list > =================================================================== > RCS file: /cvs/src/lib/libz/Symbols.list,v > diff -u -p -r1.1 Symbols.list > --- lib/libz/Symbols.list 2 Aug 2024 04:59:23 -0000 1.1 > +++ lib/libz/Symbols.list 11 Mar 2026 05:40:30 -0000 > @@ -4,7 +4,10 @@ adler32_combine64 > adler32_z > compress > compress2 > +compress2_z > compressBound > +compressBound_z > +compress_z > crc32 > crc32_combine > crc32_combine64 > @@ -14,6 +17,7 @@ crc32_combine_op > crc32_z > deflate > deflateBound > +deflateBound_z > deflateCopy > deflateEnd > deflateGetDictionary > @@ -84,6 +88,8 @@ inflateUndermine > inflateValidate > uncompress > uncompress2 > +uncompress2_z > +uncompress_z > zError > z_errmsg > zlibCompileFlags > Index: lib/libz/compress.3 > =================================================================== > RCS file: /cvs/src/lib/libz/compress.3,v > diff -u -p -r1.33 compress.3 > --- lib/libz/compress.3 4 Mar 2026 05:44:14 -0000 1.33 > +++ lib/libz/compress.3 10 Mar 2026 06:44:12 -0000 > @@ -26,6 +26,7 @@ > .Os > .Sh NAME > .Nm compress , > +.Nm compress_z , > .Nm zlibVersion , > .Nm deflateInit , > .Nm deflate , > @@ -41,6 +42,7 @@ > .Nm deflateParams , > .Nm deflateTune , > .Nm deflateBound , > +.Nm deflateBound_z , > .Nm deflatePending , > .Nm deflateUsed , > .Nm deflatePrime , > @@ -60,9 +62,13 @@ > .Nm inflateBackEnd , > .Nm zlibCompileFlags , > .Nm compress2 , > +.Nm compress2_z , > .Nm compressBound , > +.Nm compressBound_z , > .Nm uncompress , > +.Nm uncompress_z , > .Nm uncompress2 , > +.Nm uncompress2_z , > .Nm gzopen , > .Nm gzdopen , > .Nm gzbuffer , > @@ -137,6 +143,8 @@ Advanced functions > .Fn deflateTune "z_streamp strm" "int good_length" "int max_lazy" "int nice_length" "int max_chain" > .Ft uLong > .Fn deflateBound "z_streamp strm" "uLong sourceLen" > +.Ft z_size_t > +.Fn deflateBound_z "z_streamp strm" "z_size_t sourceLen" > .Ft int > .Fn deflatePending "z_streamp strm" "unsigned *pending" "int *bits" > .Ft int > @@ -181,13 +189,23 @@ Utility functions > .Ft int > .Fn compress "Bytef *dest" "uLongf *destLen" "const Bytef *source" "uLong sourceLen" > .Ft int > +.Fn compress_z "Bytef *dest" "z_size_t *destLen" "const Bytef *source" "z_size_t sourceLen" > +.Ft int > .Fn compress2 "Bytef *dest" "uLongf *destLen" "const Bytef *source" "uLong sourceLen" "int level" > +.Ft int > +.Fn compress2_z "Bytef *dest" "z_size_t *destLen" "const Bytef *source" "z_size_t sourceLen" "int level" > .Ft uLong > .Fn compressBound "uLong sourceLen" > +.Ft z_size_t > +.Fn compressBound_z "z_size_t sourceLen" > .Ft int > .Fn uncompress "Bytef *dest" "uLongf *destLen" "const Bytef *source" "uLong sourceLen" > .Ft int > +.Fn uncompress_z "Bytef *dest" "z_size_t *destLen" "const Bytef *source" "z_size_t sourceLen" > +.Ft int > .Fn uncompress2 "Bytef *dest" "uLongf *destLen" "const Bytef *source" "uLong *sourceLen" > +.Ft int > +.Fn uncompress2_z "Bytef *dest" "z_size_t *destLen" "const Bytef *source" "z_size_t *sourceLen" > .Ft gzFile > .Fn gzopen "const char *path" "const char *mode" > .Ft gzFile > @@ -844,7 +862,7 @@ option assists in appending to or combin > To assist in this, on return > .Fn inflate > always sets strm->data_type to the number of unused bits > -in the last byte taken from strm->next_in, plus 64 if > +in the input taken from strm->next_in, plus 64 if > .Fn inflate > is currently decoding the last block in the deflate stream, plus 128 if > .Fn inflate > @@ -1493,6 +1511,20 @@ or > .Dv Z_NO_FLUSH > are used. > .It Xo > +.Fa z_size_t > +.Fn deflateBound_z "z_streamp strm" "z_size_t sourceLen" ; > +.Xc > +.Pp > +.Fn deflateBound_z > +is the same as > +.Fn deflateBound , > +but takes and returns a > +.Vt z_size_t > +length. > +Note that a > +.Vt long > +is 32 bits on Windows. > +.It Xo > .Fa int > .Fn deflatePending "z_streamp strm" "unsigned *pending" "int *bits" ; > .Xc > @@ -1934,21 +1966,31 @@ parameter is invalid. > .Xc > .Pp > This function inserts bits in the inflate input stream. > -The intent is that this function is used > +The intent is to use > +.Fn inflatePrime > to start inflating at a bit position in the middle of a byte. > The provided bits will be used before any bytes are used from > .Fa next_in . > -This function should only be used with raw inflate, > +This function should be used with raw inflate, > and should be used before the first > .Fn inflate > call after > .Fn inflateInit2 > or > .Fn inflateReset . > +It can also be used after an > +.Fn inflate > +return indicates the end of a > +.Fa deflate > +block or header when using > +.Dv Z_BLOCK . > .Fa bits > must be less than or equal to 16, > and that many of the least significant bits of value > will be inserted in the input. > +The other bits in > +.Va value > +can be non-zero, and will be ignored. > .Pp > If > .Fa bits > @@ -1965,7 +2007,24 @@ returns > .Dv Z_OK > if successful, or > .Dv Z_STREAM_ERROR > -if the source stream state was inconsistent. > +if the source stream state was inconsistent, > +or if bits is out of range. > +If > +.Fn inflate > +was in the middle of processing a header, trailer, or stored block lengths, then > +it is possible for there to be only eight bits available in the bit buffer. > +In that case, bits > 8 is considered out of range. > +However, when used as outlined above, there will always be 16 bits available in > +the buffer for insertion. > +As noted in its documentation above, > +.Fn inflate > +records the number of bits in the bit buffer on return in > +.Fa data_type . > +32 minus that is the number of bits available for insertion. > +Fn inflatePrime > +does not update > +.Fa data_type > +with the new number of bits in buffer. > .It Xo > .Fa long > .Fn inflateMark "z_streamp strm" ; > @@ -2046,7 +2105,17 @@ The text, time, xflags, and os fields ar > contents. > hcrc is set to true if there is a header CRC. > (The header CRC was valid if done is set to one.) > -If extra is not > +The > +.Fa extra , > +.Fa name , > +and > +.Fa comment > +pointers much each be either > +.Dv NULL , > +or point to space to store that information from the header. > +If > +.Fa extra > +is not > .Dv NULL , > then > .Fa extra_max > @@ -2060,7 +2129,9 @@ contains the extra field, or that field > .Fa extra_max > is less than > .Fa extra_len . > -If name is not > +If > +.Fa name > +is not > .Dv NULL , > then up to > .Fa name_max > @@ -2465,13 +2536,13 @@ The > function compresses the source buffer into the destination buffer. > .Fa sourceLen > is the byte length of the source buffer. > -Upon entry, > -.Fa destLen > +On entry, > +.Pf * Fa destLen > is the total size of the destination buffer, > which must be at least the value returned by > .Fn compressBound sourcelen . > -Upon exit, > -.Fa destLen > +On exit, > +.Pf * Fa destLen > is the actual size of the compressed data. > .Fn compress > is equivalent to > @@ -2489,6 +2560,20 @@ if there was not enough memory, or > if there was not enough room in the output buffer. > .It Xo > .Fa int > +.Fn compress_z "Bytef *dest" "z_size_t *destLen" "const Bytef *source" "z_size_t sourceLen" ; > +.Xc > +.Pp > +.Fn compress_z > +is the same as > +.Fn compress , > +but takes > +.Vt z_size_t > +lengths. > +Note that a > +.Vt long > +is 32 bits on Windows. > +.It Xo > +.Fa int > .Fn compress2 "Bytef *dest" "uLongf *destLen" "const Bytef *source" "uLong sourceLen" "int level" ; > .Xc > .Pp > @@ -2501,13 +2586,13 @@ parameter has the same meaning as in > .Fn deflateInit . > .Fa sourceLen > is the byte length of the source buffer. > -Upon entry, > -.Fa destLen > +On entry, > +.Pf * Fa destLen > is the total size of the destination buffer, > which must be at least the value returned by > .Fn compressBound sourceLen . > -Upon exit, > -.Fa destLen > +On exit, > +.Pf * Fa destLen > is the actual size of the compressed buffer. > .Pp > .Fn compress2 > @@ -2521,6 +2606,20 @@ if there was not enough room in the outp > .Dv Z_STREAM_ERROR > if the level parameter is invalid. > .It Xo > +.Fa int > +.Fn compress2_z "Bytef *dest" "z_size_t *destLen" "const Bytef *source" "z_size_t sourceLen" "int level" ; > +.Xc > +.Pp > +.Fn compress2_z > +is the same as > +.Fn compress2 > +but takes > +.Vt z_size_t > +lengths. > +Note that a > +.Vt long > +is 32 bits on Windows. > +.It Xo > .Fa uLong > .Fn compressBound "uLong sourceLen" ; > .Xc > @@ -2539,6 +2638,20 @@ or > .Fn compress2 > call to allocate the destination buffer. > .It Xo > +.Fa z_size_t > +.Fn compressBound_z "z_size_t sourceLen" ; > +.Xc > +.Pp > +.Fn compressBound_z > +is the same as > +.Fn compressBound > +but takes and returns a > +.Vt z_size_t > +length. > +Note that a > +.Vt long > +is 32 bits on Windows. > +.It Xo > .Fa int > .Fn uncompress "Bytef *dest" "uLongf *destLen" "const Bytef *source" "uLong sourceLen" ; > .Xc > @@ -2548,15 +2661,15 @@ The > function decompresses the source buffer into the destination buffer. > .Fa sourceLen > is the byte length of the source buffer. > -Upon entry, > -.Fa destLen > +On entry, > +.Pf * Fa destLen > is the total size of the destination buffer, > which must be large enough to hold the entire uncompressed data. > (The size of the uncompressed data must have been saved previously > by the compressor and transmitted to the decompressor > by some mechanism outside the scope of this compression library.) > -Upon exit, > -.Fa destLen > +On exit, > +.Pf * Fa destLen > is the actual size of the uncompressed data. > This function can be used to decompress a whole file at once if the > input file is mmap'ed. > @@ -2576,6 +2689,20 @@ In the case where there is not enough ro > will fill the output buffer with the uncompressed data up to that point. > .It Xo > .Fa int > +.Fn uncompress_z "Bytef *dest" "z_size_t *destLen" "const Bytef *source" "z_size_t sourceLen" ; > +.Xc > +.Pp > +.Fn uncompress_z > +is the same as > +.Fn uncompress > +but takes > +.Vt z_size_t > +lengths. > +Note that a > +.Vt long > +is 32 bits on Windows. > +.It Xo > +.Fa int > .Fn uncompress2 "Bytef *dest" "uLongf *destLen" "const Bytef *source" "uLong *sourceLen" ; > .Xc > .Pp > @@ -2589,6 +2716,20 @@ On return, > .Fa *sourceLen > is the number of source bytes consumed. > .It Xo > +.Fa int > +.Fn uncompress2_z "Bytef *dest" "z_size_t *destLen" "const Bytef *source" "z_size_t *sourceLen" ; > +.Xc > +.Pp > +.Fn uncompress2_z > +is the same as > +.Fn uncompress > +but takes > +.Vt z_size_t > +lengths. > +Note that a > +.Vt long > +is 32 bits on Windows. > +.It Xo > .Fa gzFile > .Fn gzopen "const char *path" "const char *mode" ; > .Xc > @@ -2633,6 +2774,15 @@ for more information about the strategy > .Sq T > will request transparent writing or appending with no compression and not using > the gzip format. > +.Sq T > +cannot be used to force transparent reading. > +Transparent reading is automatically performed > +if there is no gzip reader at the start. > +Transparent reading can be disabled with the > +.Sq G > +option, which will instead return an error if there is no gzip header. > +.Sq N > +will open the file in non-blocking mode. > .Pp > .Sq a > can be used instead of > @@ -2692,6 +2842,25 @@ was provided). > can be checked to determine if the reason > .Fn gzopen > failed was that the file could not be opened. > +Note that if > +.Sq N > +is in mode for non-blocking, the > +.Xr open 2 > +call itself can fail in order to not block. > +In that case > +.Fn gzopen > +return > +.Dv NULL > +and errno will be > +.Dv EAGAIN > +or > +.Dv ENONBLOCK . > +The call to > +.Fn gzopen > +with the resulting file descriptor and > +.Sq N > +in the mode, > +which will set it to non-blocking. > .It Xo > .Fa gzFile > .Fn gzdopen "int fd" "const char *mode" ; > @@ -2715,6 +2884,22 @@ The > parameter is as in > .Fn gzopen . > .Pp > +An > +.Sq e > +in > +.Fa mode > +will set > +.Fa fd Ns No 's > +flag to close the file on an > +.Xr execve 2 > +call. > +An > +.Sq N > +in > +.Fa mode > +will set > +.Fa fd Ns No 's > +non-blocking flag. > The next call to > .Fn gzclose > on the returned gzFile will also close the file descriptor fd, > @@ -2798,7 +2983,7 @@ if there is a memory allocation error. > Reads the given number of uncompressed bytes from the compressed file. > If the input file is not in gzip format, > .Fn gzread > -copies the given number ofbytes into the buffer directly from the file. > +copies the given number of bytes into the buffer directly from the file. > .Pp > After reaching the end of a gzip stream in the input, > .Fn gzread > @@ -2847,6 +3032,17 @@ can be used before > to detect this case. > .Pp > .Fn gzread > +can be used to read a gzip file on a non-blocking device. > +If the input stalls and there is no uncompressed data to return, then > +.Fn gzread > +will return \-1, and errno will be > +.Dv EAGAIN > +or > +.Dv EWOULDBLOCK . > +.Fn gzread > +can then be called again. > +.Pp > +.Fn gzread > returns the number of uncompressed bytes actually read, > less than > .Fa len > @@ -2856,6 +3052,9 @@ If > is too large to fit in an int, > then nothing is read, -1 is returned, and the error state is set to > .Dv Z_STREAM_ERROR . > +If some data was read before an error, > +then that data is returned until exhausted, > +after which the next call will signal the error. > .It Xo > .Fa z_size_t > .Fn gzfread "voidp buf" "z_size_t size" "z_size_t nitems" "gzFile file" ; > @@ -2896,19 +3095,21 @@ zero is returned, and the error state is > .Pp > In the event that the end of file is reached and only a partial item is > available at the end, i.e. the remaining uncompressed data length is not a > -multiple of size, then the final partial item is nevetheless read into > +multiple of size, then the final partial item is nevertheless read into > .Fa buf > and the end-of-file flag is set. > The length of the partial item read is not provided, > but could be inferred from the result of > .Fn gztell . > -This behavior is the same as the behavior of > +This behavior is the same as that of > .Xr fread 3 > -implementations in common libraries, > -but it prevents the direct use of > -.Fn gzfread > -to read a concurrently written file, resetting and retrying on end-of-file, > -when size is not 1. > +implementations in common libraries. > +This could result in data loss if used with size != 1 > +when reading a concurrently written file or > +a non-blocking file. > +In that case, use size == 1 or > +.Fn gzread > +instead. > .It Xo > .Fa int > .Fn gzwrite "gzFile file" "voidpc buf" "unsigned len" ; > @@ -2918,7 +3119,17 @@ The > .Fn gzwrite > function writes the given number of uncompressed bytes into the compressed file. > .Fn gzwrite > -returns the number of uncompressed bytes written or 0 in case of error. > +returns the number of uncompressed bytes written or 0 in case of error or > +if > +.Fa len > +is 0. > +If the write destination is non-blocking, then > +.Fn gzwrite > +may return a number of bytes written that is not 0 and less than > +.Fa len . > +If > +.Fa len > +does not fit in an int, then 0 is returned and nothing is written. > .It Xo > .Fa z_size_t > .Fn gzfwrite "voidpc buf" "z_size_t size" "z_size_t nitems" "gzFile file" ; > @@ -2951,6 +3162,13 @@ overflows, > i.e. the product does not fit in a z_size_t, then nothing is written, > zero is returned, and the error state is set to > .Dv Z_STREAM_ERROR . > +.Pp > +If writing a concurrently read file or a non-blocking file with size != 1, > +a partial item could be written, with no way of knowing > +how much of it was not written, resulting in data loss. > +In that case, use size == 1 or > +.Fn gzwrite > +instead. > .It Xo > .Fa int > .Fn gzprintf "gzFile file" "const char *format" "..." ; > @@ -3021,16 +3239,19 @@ returns > which is a NUL-terminated string, or it returns > .Dv NULL > for end-of-file or in case of error. > -If there was an error, the contents at > -.Fa buf > -are indeterminate. > +If some data was read before an error, > +then that data is returned until exhausted, after which the next call > +will return > +.Dv NULL > +to signal the error. > .Pp > .Fn gzgets > -returns > -.Fa buf , > -or > -.Dv NULL > -in case of error. > +can be used on a file being concurrently written, > +and on a non-blocking device, both as for > +.Fn gzread . > +However lines may be broken in the middle, > +leaving it up to the application > +to reassemble them as needed. > .It Xo > .Fa int > .Fn gzputc "gzFile file" "int c" ; > @@ -3053,6 +3274,10 @@ The > function reads one byte from the compressed file. > .Fn gzgetc > returns this byte or -1 in case of end of file or error. > +If some data was read before an error, > +then that data is returned until exhausted, > +after which the next call will return \-1 to signal the error. > +.Pp > This is implemented as a macro for speed. > As such, it does not do all of the checking the other functions do. > That is, it does not check to see if file is > @@ -3060,6 +3285,17 @@ That is, it does not check to see if fil > nor whether the structure > .Fa file > points to has been clobbered or not. > +.Pp > +.Fn gzgetc > +can be used to read a gzip file on a non-blocking device. > +If the input stalls and there is no uncompressed data to return, then > +.Fn gzgetc > +will return \-1, and errno will be > +.Dv EAGAIN > +or > +.Dv EWOULDBLOCK . > +.Fn gzread > +can then be called again. > .It Xo > .Fa int > .Fn gzungetc "int c" "gzFile file" ; > @@ -3087,6 +3323,13 @@ The pushed character will be discarded i > .Fn gzseek > or > .Fn gzrewind . > +.Pp > +gzungetc(\-1, file) will force any pending seek to execute. > +Then > +.Fn gztell > +will report the position, even if the requested seek reached end of file. > +This can be used to determine the number of uncompressed bytes > +in a gzip file without having to read it into a buffer. > .It Xo > .Fa int > .Fn gzflush "gzFile file" "int flush" ; > @@ -3142,6 +3385,8 @@ extremely slow. > If the file is opened for writing, only forward seeks are supported; > .Fn gzseek > then compresses a sequence of zeroes up to the new starting position. > +For reading or writing, any actual seeking is deferred until > +the next read or write operation, or close operation when writing. > .Pp > .Fn gzseek > returns the resulting offset location as measured in bytes from > @@ -3180,7 +3425,7 @@ even if appending or reading a gzip stre > gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR). > .It Xo > .Fa int > -.Fn gzeoffset "gzFile file" ; > +.Fn gzoffset "gzFile file" ; > .Xc > .Pp > Returns the current offset in the file being read or written. > @@ -3244,6 +3489,14 @@ Therefore if > .Fn gzbuffer > is used, it should be called before > .Fn gzdirect . > +If the input is being written concurrently > +or the device is non-blocking, then > +.Fn gzdirect > +may give a different answer once four bytes of input have been accumulated, > +which is what is needed to confirm or deny a gzip reader. > +Before this, > +.Fa gzdirect > +will return true (1). > .Pp > When writing, > .Fn gzdirect > @@ -3327,7 +3580,11 @@ The > function returns the error message for the last error which occurred on the > given compressed > .Fa file . > +If > .Fa errnum > +is not > +.Dv NULL , > +.Pf * Fa errnum > is set to the > .Nm zlib > error number. > Index: lib/libz/compress.c > =================================================================== > RCS file: /cvs/src/lib/libz/compress.c,v > diff -u -p -r1.10 compress.c > --- lib/libz/compress.c 25 Apr 2023 16:59:10 -0000 1.10 > +++ lib/libz/compress.c 10 Mar 2026 06:44:12 -0000 > @@ -1,5 +1,5 @@ > /* compress.c -- compress a memory buffer > - * Copyright (C) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler > + * Copyright (C) 1995-2026 Jean-loup Gailly, Mark Adler > * For conditions of distribution and use, see copyright notice in zlib.h > */ > > @@ -16,13 +16,19 @@ > compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough > memory, Z_BUF_ERROR if there was not enough room in the output buffer, > Z_STREAM_ERROR if the level parameter is invalid. > + > + The _z versions of the functions take size_t length arguments. > */ > -int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source, > - uLong sourceLen, int level) { > +int ZEXPORT compress2_z(Bytef *dest, z_size_t *destLen, const Bytef *source, > + z_size_t sourceLen, int level) { > z_stream stream; > int err; > const uInt max = (uInt)-1; > - uLong left; > + z_size_t left; > + > + if ((sourceLen > 0 && source == NULL) || > + destLen == NULL || (*destLen > 0 && dest == NULL)) > + return Z_STREAM_ERROR; > > left = *destLen; > *destLen = 0; > @@ -41,23 +47,36 @@ int ZEXPORT compress2(Bytef *dest, uLong > > do { > if (stream.avail_out == 0) { > - stream.avail_out = left > (uLong)max ? max : (uInt)left; > + stream.avail_out = left > (z_size_t)max ? max : (uInt)left; > left -= stream.avail_out; > } > if (stream.avail_in == 0) { > - stream.avail_in = sourceLen > (uLong)max ? max : (uInt)sourceLen; > + stream.avail_in = sourceLen > (z_size_t)max ? max : > + (uInt)sourceLen; > sourceLen -= stream.avail_in; > } > err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH); > } while (err == Z_OK); > > - *destLen = stream.total_out; > + *destLen = (z_size_t)(stream.next_out - dest); > deflateEnd(&stream); > return err == Z_STREAM_END ? Z_OK : err; > } > - > +int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source, > + uLong sourceLen, int level) { > + int ret; > + z_size_t got = *destLen; > + ret = compress2_z(dest, &got, source, sourceLen, level); > + *destLen = (uLong)got; > + return ret; > +} > /* =========================================================================== > */ > +int ZEXPORT compress_z(Bytef *dest, z_size_t *destLen, const Bytef *source, > + z_size_t sourceLen) { > + return compress2_z(dest, destLen, source, sourceLen, > + Z_DEFAULT_COMPRESSION); > +} > int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source, > uLong sourceLen) { > return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); > @@ -67,7 +86,12 @@ int ZEXPORT compress(Bytef *dest, uLongf > If the default memLevel or windowBits for deflateInit() is changed, then > this function needs to be updated. > */ > +z_size_t ZEXPORT compressBound_z(z_size_t sourceLen) { > + z_size_t bound = sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + > + (sourceLen >> 25) + 13; > + return bound < sourceLen ? (z_size_t)-1 : bound; > +} > uLong ZEXPORT compressBound(uLong sourceLen) { > - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + > - (sourceLen >> 25) + 13; > + z_size_t bound = compressBound_z(sourceLen); > + return (uLong)bound != bound ? (uLong)-1 : (uLong)bound; > } > Index: lib/libz/crc32.c > =================================================================== > RCS file: /cvs/src/lib/libz/crc32.c,v > diff -u -p -r1.18 crc32.c > --- lib/libz/crc32.c 4 Mar 2026 05:44:14 -0000 1.18 > +++ lib/libz/crc32.c 10 Mar 2026 06:44:12 -0000 > @@ -1,5 +1,5 @@ > /* crc32.c -- compute the CRC-32 of a data stream > - * Copyright (C) 1995-2022 Mark Adler > + * Copyright (C) 1995-2026 Mark Adler > * For conditions of distribution and use, see copyright notice in zlib.h > * > * This interleaved implementation of a CRC makes use of pipelined multiple > @@ -22,11 +22,18 @@ > # include > # ifndef DYNAMIC_CRC_TABLE > # define DYNAMIC_CRC_TABLE > -# endif /* !DYNAMIC_CRC_TABLE */ > -#endif /* MAKECRCH */ > +# endif > +#endif > +#ifdef DYNAMIC_CRC_TABLE > +# define Z_ONCE > +#endif > > #include "zutil.h" /* for Z_U4, Z_U8, z_crc_t, and FAR definitions */ > > +#ifdef HAVE_S390X_VX > +# include "contrib/crc32vx/crc32_vx_hooks.h" > +#endif > + > /* > A CRC of a message is computed on N braids of words in the message, where > each word consists of W bytes (4 or 8). If N is 3, for example, then three > @@ -97,7 +104,8 @@ > #endif > > /* If available, use the ARM processor CRC32 instruction. */ > -#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8 > +#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && \ > + defined(W) && W == 8 > # define ARMCRC32 > #endif > > @@ -150,10 +158,10 @@ local z_word_t byte_swap(z_word_t word) > Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial, > reflected. For speed, this requires that a not be zero. > */ > -local z_crc_t multmodp(z_crc_t a, z_crc_t b) { > - z_crc_t m, p; > +local uLong multmodp(uLong a, uLong b) { > + uLong m, p; > > - m = (z_crc_t)1 << 31; > + m = (uLong)1 << 31; > p = 0; > for (;;) { > if (a & m) { > @@ -169,12 +177,12 @@ local z_crc_t multmodp(z_crc_t a, z_crc_ > > /* > Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been > - initialized. > + initialized. n must not be negative. > */ > -local z_crc_t x2nmodp(z_off64_t n, unsigned k) { > - z_crc_t p; > +local uLong x2nmodp(z_off64_t n, unsigned k) { > + uLong p; > > - p = (z_crc_t)1 << 31; /* x^0 == 1 */ > + p = (uLong)1 << 31; /* x^0 == 1 */ > while (n) { > if (n & 1) > p = multmodp(x2n_table[k & 31], p); > @@ -202,83 +210,8 @@ local z_crc_t FAR crc_table[256]; > local void write_table64(FILE *, const z_word_t FAR *, int); > #endif /* MAKECRCH */ > > -/* > - Define a once() function depending on the availability of atomics. If this is > - compiled with DYNAMIC_CRC_TABLE defined, and if CRCs will be computed in > - multiple threads, and if atomics are not available, then get_crc_table() must > - be called to initialize the tables and must return before any threads are > - allowed to compute or combine CRCs. > - */ > - > -/* Definition of once functionality. */ > -typedef struct once_s once_t; > - > -/* Check for the availability of atomics. */ > -#if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \ > - !defined(__STDC_NO_ATOMICS__) && !defined(SMALL) > - > -#include > - > -/* Structure for once(), which must be initialized with ONCE_INIT. */ > -struct once_s { > - atomic_flag begun; > - atomic_int done; > -}; > -#define ONCE_INIT {ATOMIC_FLAG_INIT, 0} > - > -/* > - Run the provided init() function exactly once, even if multiple threads > - invoke once() at the same time. The state must be a once_t initialized with > - ONCE_INIT. > - */ > -local void once(once_t *state, void (*init)(void)) { > - if (!atomic_load(&state->done)) { > - if (atomic_flag_test_and_set(&state->begun)) > - while (!atomic_load(&state->done)) > - ; > - else { > - init(); > - atomic_store(&state->done, 1); > - } > - } > -} > - > -#else /* no atomics */ > - > -/* Structure for once(), which must be initialized with ONCE_INIT. */ > -struct once_s { > - volatile int begun; > - volatile int done; > -}; > -#define ONCE_INIT {0, 0} > - > -/* Test and set. Alas, not atomic, but tries to minimize the period of > - vulnerability. */ > -local int test_and_set(int volatile *flag) { > - int was; > - > - was = *flag; > - *flag = 1; > - return was; > -} > - > -/* Run the provided init() function once. This is not thread-safe. */ > -local void once(once_t *state, void (*init)(void)) { > - if (!state->done) { > - if (test_and_set(&state->begun)) > - while (!state->done) > - ; > - else { > - init(); > - state->done = 1; > - } > - } > -} > - > -#endif > - > /* State for once(). */ > -local once_t made = ONCE_INIT; > +local z_once_t made = Z_ONCE_INIT; > > /* > Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: > @@ -324,7 +257,7 @@ local void make_crc_table(void) { > p = (z_crc_t)1 << 30; /* x^1 */ > x2n_table[0] = p; > for (n = 1; n < 32; n++) > - x2n_table[n] = p = multmodp(p, p); > + x2n_table[n] = p = (z_crc_t)multmodp(p, p); > > #ifdef W > /* initialize the braiding tables -- needs x2n_table[] */ > @@ -527,11 +460,11 @@ local void braid(z_crc_t ltl[][256], z_w > int k; > z_crc_t i, p, q; > for (k = 0; k < w; k++) { > - p = x2nmodp((n * w + 3 - k) << 3, 0); > + p = (z_crc_t)x2nmodp((n * w + 3 - k) << 3, 0); > ltl[k][0] = 0; > big[w - 1 - k][0] = 0; > for (i = 1; i < 256; i++) { > - ltl[k][i] = q = multmodp(i << 24, p); > + ltl[k][i] = q = (z_crc_t)multmodp(i << 24, p); > big[w - 1 - k][i] = byte_swap(q); > } > } > @@ -546,7 +479,7 @@ local void braid(z_crc_t ltl[][256], z_w > */ > const z_crc_t FAR * ZEXPORT get_crc_table(void) { > #ifdef DYNAMIC_CRC_TABLE > - once(&made, make_crc_table); > + z_once(&made, make_crc_table); > #endif /* DYNAMIC_CRC_TABLE */ > return (const z_crc_t FAR *)crc_table; > } > @@ -570,9 +503,8 @@ const z_crc_t FAR * ZEXPORT get_crc_tabl > #define Z_BATCH_ZEROS 0xa10d3d0c /* computed from Z_BATCH = 3990 */ > #define Z_BATCH_MIN 800 /* fewest words in a final batch */ > > -unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, > - z_size_t len) { > - z_crc_t val; > +uLong ZEXPORT crc32_z(uLong crc, const unsigned char FAR *buf, z_size_t len) { > + uLong val; > z_word_t crc1, crc2; > const z_word_t *word; > z_word_t val0, val1, val2; > @@ -583,7 +515,7 @@ unsigned long ZEXPORT crc32_z(unsigned l > if (buf == Z_NULL) return 0; > > #ifdef DYNAMIC_CRC_TABLE > - once(&made, make_crc_table); > + z_once(&made, make_crc_table); > #endif /* DYNAMIC_CRC_TABLE */ > > /* Pre-condition the CRC */ > @@ -638,7 +570,7 @@ unsigned long ZEXPORT crc32_z(unsigned l > } > word += 3 * last; > num -= 3 * last; > - val = x2nmodp(last, 6); > + val = x2nmodp((int)last, 6); > crc = multmodp(val, crc) ^ crc1; > crc = multmodp(val, crc) ^ crc2; > } > @@ -689,13 +621,12 @@ local z_word_t crc_word_big(z_word_t dat > #endif > > /* ========================================================================= */ > -unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, > - z_size_t len) { > +uLong ZEXPORT crc32_z(uLong crc, const unsigned char FAR *buf, z_size_t len) { > /* Return initial CRC, if requested. */ > if (buf == Z_NULL) return 0; > > #ifdef DYNAMIC_CRC_TABLE > - once(&made, make_crc_table); > + z_once(&made, make_crc_table); > #endif /* DYNAMIC_CRC_TABLE */ > > /* Pre-condition the CRC */ > @@ -1010,42 +941,41 @@ unsigned long ZEXPORT crc32_z(unsigned l > #endif > > /* ========================================================================= */ > -unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, > - uInt len) { > +uLong ZEXPORT crc32(uLong crc, const unsigned char FAR *buf, uInt len) { > + #ifdef HAVE_S390X_VX > + return crc32_z_hook(crc, buf, len); > + #endif > return crc32_z(crc, buf, len); > } > > /* ========================================================================= */ > -uLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2) { > +uLong ZEXPORT crc32_combine_gen64(z_off64_t len2) { > if (len2 < 0) > return 0; > #ifdef DYNAMIC_CRC_TABLE > - once(&made, make_crc_table); > + z_once(&made, make_crc_table); > #endif /* DYNAMIC_CRC_TABLE */ > - return multmodp(x2nmodp(len2, 3), crc1) ^ (crc2 & 0xffffffff); > + return x2nmodp(len2, 3); > } > > /* ========================================================================= */ > -uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2) { > - return crc32_combine64(crc1, crc2, (z_off64_t)len2); > +uLong ZEXPORT crc32_combine_gen(z_off_t len2) { > + return crc32_combine_gen64((z_off64_t)len2); > } > > /* ========================================================================= */ > -uLong ZEXPORT crc32_combine_gen64(z_off64_t len2) { > - if (len2 < 0) > +uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op) { > + if (op == 0) > return 0; > -#ifdef DYNAMIC_CRC_TABLE > - once(&made, make_crc_table); > -#endif /* DYNAMIC_CRC_TABLE */ > - return x2nmodp(len2, 3); > + return multmodp(op, crc1 & 0xffffffff) ^ (crc2 & 0xffffffff); > } > > /* ========================================================================= */ > -uLong ZEXPORT crc32_combine_gen(z_off_t len2) { > - return crc32_combine_gen64((z_off64_t)len2); > +uLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2) { > + return crc32_combine_op(crc1, crc2, crc32_combine_gen64(len2)); > } > > /* ========================================================================= */ > -uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op) { > - return multmodp(op, crc1) ^ (crc2 & 0xffffffff); > +uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2) { > + return crc32_combine64(crc1, crc2, (z_off64_t)len2); > } > Index: lib/libz/deflate.c > =================================================================== > RCS file: /cvs/src/lib/libz/deflate.c,v > diff -u -p -r1.30 deflate.c > --- lib/libz/deflate.c 7 Mar 2026 07:27:51 -0000 1.30 > +++ lib/libz/deflate.c 10 Mar 2026 06:44:12 -0000 > @@ -1,5 +1,5 @@ > /* deflate.c -- compress data using the deflation algorithm > - * Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler > + * Copyright (C) 1995-2026 Jean-loup Gailly and Mark Adler > * For conditions of distribution and use, see copyright notice in zlib.h > */ > > @@ -37,7 +37,7 @@ > * REFERENCES > * > * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". > - * Available in http://tools.ietf.org/html/rfc1951 > + * Available at https://datatracker.ietf.org/doc/html/rfc1951 > * > * A description of the Rabin and Karp algorithm is given in the book > * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. > @@ -166,8 +166,7 @@ local const config configuration_table[1 > #define CLEAR_HASH(s) \ > do { \ > s->head[s->hash_size - 1] = NIL; \ > - zmemzero((Bytef *)s->head, \ > - (unsigned)(s->hash_size - 1)*sizeof(*s->head)); \ > + zmemzero(s->head, (unsigned)(s->hash_size - 1)*sizeof(*s->head)); \ > s->slid = 0; \ > } while (0) > > @@ -257,7 +256,14 @@ local void fill_window(deflate_state *s) > more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); > > /* Deal with !@#$% 64K limit: */ > +#ifdef _MSC_VER > +#pragma warning(push) > +#pragma warning(disable: 4127) > +#endif > if (sizeof(int) <= 2) { > +#ifdef _MSC_VER > +#pragma warning(pop) > +#endif > if (more == 0 && s->strstart == 0 && s->lookahead == 0) { > more = wsize; > > @@ -711,10 +717,15 @@ int ZEXPORT deflateSetHeader(z_streamp s > /* ========================================================================= */ > int ZEXPORT deflatePending(z_streamp strm, unsigned *pending, int *bits) { > if (deflateStateCheck(strm)) return Z_STREAM_ERROR; > - if (pending != Z_NULL) > - *pending = strm->state->pending; > if (bits != Z_NULL) > *bits = strm->state->bi_valid; > + if (pending != Z_NULL) { > + *pending = (unsigned)strm->state->pending; > + if (*pending != strm->state->pending) { > + *pending = (unsigned)-1; > + return Z_BUF_ERROR; > + } > + } > return Z_OK; > } > > @@ -838,24 +849,30 @@ int ZEXPORT deflateTune(z_streamp strm, > * > * Shifts are used to approximate divisions, for speed. > */ > -uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) { > +z_size_t ZEXPORT deflateBound_z(z_streamp strm, z_size_t sourceLen) { > deflate_state *s; > - uLong fixedlen, storelen, wraplen; > + z_size_t fixedlen, storelen, wraplen, bound; > > /* upper bound for fixed blocks with 9-bit literals and length 255 > (memLevel == 2, which is the lowest that may not use stored blocks) -- > ~13% overhead plus a small constant */ > fixedlen = sourceLen + (sourceLen >> 3) + (sourceLen >> 8) + > (sourceLen >> 9) + 4; > + if (fixedlen < sourceLen) > + fixedlen = (z_size_t)-1; > > /* upper bound for stored blocks with length 127 (memLevel == 1) -- > ~4% overhead plus a small constant */ > storelen = sourceLen + (sourceLen >> 5) + (sourceLen >> 7) + > (sourceLen >> 11) + 7; > + if (storelen < sourceLen) > + storelen = (z_size_t)-1; > > /* if can't get parameters, return larger bound plus a wrapper */ > - if (deflateStateCheck(strm)) > - return (fixedlen > storelen ? fixedlen : storelen) + 18; > + if (deflateStateCheck(strm)) { > + bound = fixedlen > storelen ? fixedlen : storelen; > + return bound + 18 < bound ? (z_size_t)-1 : bound + 18; > + } > > /* compute wrapper length */ > s = strm->state; > @@ -893,14 +910,21 @@ uLong ZEXPORT deflateBound(z_streamp str > } > > /* if not default parameters, return one of the conservative bounds */ > - if (s->w_bits != 15 || s->hash_bits != 8 + 7) > - return (s->w_bits <= s->hash_bits && s->level ? fixedlen : storelen) + > - wraplen; > + if (s->w_bits != 15 || s->hash_bits != 8 + 7) { > + bound = s->w_bits <= s->hash_bits && s->level ? fixedlen : > + storelen; > + return bound + wraplen < bound ? (z_size_t)-1 : bound + wraplen; > + } > > /* default settings: return tight bound for that case -- ~0.03% overhead > plus a small constant */ > - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + > - (sourceLen >> 25) + 13 - 6 + wraplen; > + bound = sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + > + (sourceLen >> 25) + 13 - 6 + wraplen; > + return bound < sourceLen ? (z_size_t)-1 : bound; > +} > +uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) { > + z_size_t bound = deflateBound_z(strm, sourceLen); > + return (uLong)bound != bound ? (uLong)-1 : (uLong)bound; > } > > /* ========================================================================= > @@ -924,8 +948,8 @@ local void flush_pending(z_streamp strm) > deflate_state *s = strm->state; > > _tr_flush_bits(s); > - len = s->pending; > - if (len > strm->avail_out) len = strm->avail_out; > + len = s->pending > strm->avail_out ? strm->avail_out : > + (unsigned)s->pending; > if (len == 0) return; > > zmemcpy(strm->next_out, s->pending_out, len); > @@ -945,8 +969,8 @@ local void flush_pending(z_streamp strm) > #define HCRC_UPDATE(beg) \ > do { \ > if (s->gzhead->hcrc && s->pending > (beg)) \ > - strm->adler = crc32(strm->adler, s->pending_buf + (beg), \ > - s->pending - (beg)); \ > + strm->adler = crc32_z(strm->adler, s->pending_buf + (beg), \ > + s->pending - (beg)); \ > } while (0) > > /* ========================================================================= */ > @@ -1080,8 +1104,8 @@ int ZEXPORT deflate(z_streamp strm, int > put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); > } > if (s->gzhead->hcrc) > - strm->adler = crc32(strm->adler, s->pending_buf, > - s->pending); > + strm->adler = crc32_z(strm->adler, s->pending_buf, > + s->pending); > s->gzindex = 0; > s->status = EXTRA_STATE; > } > @@ -1089,9 +1113,9 @@ int ZEXPORT deflate(z_streamp strm, int > if (s->status == EXTRA_STATE) { > if (s->gzhead->extra != Z_NULL) { > ulg beg = s->pending; /* start of bytes to update crc */ > - uInt left = (s->gzhead->extra_len & 0xffff) - s->gzindex; > + ulg left = (s->gzhead->extra_len & 0xffff) - s->gzindex; > while (s->pending + left > s->pending_buf_size) { > - uInt copy = s->pending_buf_size - s->pending; > + ulg copy = s->pending_buf_size - s->pending; > zmemcpy(s->pending_buf + s->pending, > s->gzhead->extra + s->gzindex, copy); > s->pending = s->pending_buf_size; > @@ -1302,13 +1326,13 @@ int ZEXPORT deflateCopy(z_streamp dest, > > ss = source->state; > > - zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); > + zmemcpy(dest, source, sizeof(z_stream)); > > ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); > if (ds == Z_NULL) return Z_MEM_ERROR; > zmemzero(ds, sizeof(deflate_state)); > dest->state = (struct internal_state FAR *) ds; > - zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); > + zmemcpy(ds, ss, sizeof(deflate_state)); > ds->strm = dest; > > ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); > @@ -1323,10 +1347,10 @@ int ZEXPORT deflateCopy(z_streamp dest, > } > /* following zmemcpy's do not work for 16-bit MSDOS */ > zmemcpy(ds->window, ss->window, ss->high_water); > - zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, > + zmemcpy(ds->prev, ss->prev, > (ss->slid || ss->strstart - ss->insert > ds->w_size ? ds->w_size : > ss->strstart - ss->insert) * sizeof(Pos)); > - zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); > + zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); > > ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); > zmemcpy(ds->pending_out, ss->pending_out, ss->pending); > @@ -1360,9 +1384,9 @@ int ZEXPORT deflateCopy(z_streamp dest, > */ > local uInt longest_match(deflate_state *s, IPos cur_match) { > unsigned chain_length = s->max_chain_length;/* max hash chain length */ > - register Bytef *scan = s->window + s->strstart; /* current string */ > - register Bytef *match; /* matched string */ > - register int len; /* length of current match */ > + Bytef *scan = s->window + s->strstart; /* current string */ > + Bytef *match; /* matched string */ > + int len; /* length of current match */ > int best_len = (int)s->prev_length; /* best match length so far */ > int nice_match = s->nice_match; /* stop if match long enough */ > IPos limit = s->strstart > (IPos)MAX_DIST(s) ? > @@ -1377,13 +1401,13 @@ local uInt longest_match(deflate_state * > /* Compare two bytes at a time. Note: this is not always beneficial. > * Try with and without -DUNALIGNED_OK to check. > */ > - register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; > - register ush scan_start = *(ushf*)scan; > - register ush scan_end = *(ushf*)(scan + best_len - 1); > + Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; > + ush scan_start = *(ushf*)scan; > + ush scan_end = *(ushf*)(scan + best_len - 1); > #else > - register Bytef *strend = s->window + s->strstart + MAX_MATCH; > - register Byte scan_end1 = scan[best_len - 1]; > - register Byte scan_end = scan[best_len]; > + Bytef *strend = s->window + s->strstart + MAX_MATCH; > + Byte scan_end1 = scan[best_len - 1]; > + Byte scan_end = scan[best_len]; > #endif > > /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. > @@ -1507,10 +1531,10 @@ local uInt longest_match(deflate_state * > * Optimized version for FASTEST only > */ > local uInt longest_match(deflate_state *s, IPos cur_match) { > - register Bytef *scan = s->window + s->strstart; /* current string */ > - register Bytef *match; /* matched string */ > - register int len; /* length of current match */ > - register Bytef *strend = s->window + s->strstart + MAX_MATCH; > + Bytef *scan = s->window + s->strstart; /* current string */ > + Bytef *match; /* matched string */ > + int len; /* length of current match */ > + Bytef *strend = s->window + s->strstart + MAX_MATCH; > > /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. > * It is easy to get rid of this optimization if necessary. > @@ -1570,7 +1594,7 @@ local uInt longest_match(deflate_state * > local void check_match(deflate_state *s, IPos start, IPos match, int length) { > /* check that the match is indeed a match */ > Bytef *back = s->window + (int)match, *here = s->window + start; > - IPos len = length; > + IPos len = (IPos)length; > if (match == (IPos)-1) { > /* match starts one byte before the current window -- just compare the > subsequent length-1 bytes */ > @@ -1642,7 +1666,7 @@ local block_state deflate_stored(deflate > * this is 32K. This can be as small as 507 bytes for memLevel == 1. For > * large input and output buffers, the stored block size will be larger. > */ > - unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size); > + unsigned min_block = (unsigned)(MIN(s->pending_buf_size - 5, s->w_size)); > > /* Copy as many min_block or larger stored blocks directly to next_out as > * possible. If flushing, copy the remaining available input to next_out as > @@ -1657,12 +1681,12 @@ local block_state deflate_stored(deflate > * would be copied from what's left in the window. > */ > len = MAX_STORED; /* maximum deflate stored block length */ > - have = (s->bi_valid + 42) >> 3; /* number of header bytes */ > + have = ((unsigned)s->bi_valid + 42) >> 3; /* bytes in header */ > if (s->strm->avail_out < have) /* need room for header */ > break; > /* maximum stored block length that will fit in avail_out: */ > have = s->strm->avail_out - have; > - left = s->strstart - s->block_start; /* bytes left in window */ > + left = (unsigned)(s->strstart - s->block_start); /* window bytes */ > if (len > (ulg)left + s->strm->avail_in) > len = left + s->strm->avail_in; /* limit len to the input */ > if (len > have) > @@ -1770,7 +1794,7 @@ local block_state deflate_stored(deflate > return block_done; > > /* Fill the window with any remaining input. */ > - have = s->window_size - s->strstart; > + have = (unsigned)(s->window_size - s->strstart); > if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) { > /* Slide the window down. */ > s->block_start -= s->w_size; > @@ -1797,11 +1821,11 @@ local block_state deflate_stored(deflate > * have enough input for a worthy block, or if flushing and there is enough > * room for the remaining input as a stored block in the pending buffer. > */ > - have = (s->bi_valid + 42) >> 3; /* number of header bytes */ > + have = ((unsigned)s->bi_valid + 42) >> 3; /* bytes in header */ > /* maximum stored block length that will fit in pending: */ > - have = MIN(s->pending_buf_size - have, MAX_STORED); > + have = (unsigned)MIN(s->pending_buf_size - have, MAX_STORED); > min_block = MIN(have, s->w_size); > - left = s->strstart - s->block_start; > + left = (unsigned)(s->strstart - s->block_start); > if (left >= min_block || > ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH && > s->strm->avail_in == 0 && left <= have)) { > @@ -1864,7 +1888,7 @@ local block_state deflate_fast(deflate_s > /* longest_match() sets match_start */ > } > if (s->match_length >= MIN_MATCH) { > - check_match(s, s->strstart, s->match_start, s->match_length); > + check_match(s, s->strstart, s->match_start, (int)s->match_length); > > _tr_tally_dist(s, s->strstart - s->match_start, > s->match_length - MIN_MATCH, bflush); > @@ -1986,7 +2010,7 @@ local block_state deflate_slow(deflate_s > uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; > /* Do not insert strings in hash table beyond this. */ > > - check_match(s, s->strstart - 1, s->prev_match, s->prev_length); > + check_match(s, s->strstart - 1, s->prev_match, (int)s->prev_length); > > _tr_tally_dist(s, s->strstart - 1 - s->prev_match, > s->prev_length - MIN_MATCH, bflush); > @@ -2094,7 +2118,7 @@ local block_state deflate_rle(deflate_st > > /* Emit match if have run of MIN_MATCH or longer, else emit literal */ > if (s->match_length >= MIN_MATCH) { > - check_match(s, s->strstart, s->strstart - 1, s->match_length); > + check_match(s, s->strstart, s->strstart - 1, (int)s->match_length); > > _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); > > Index: lib/libz/deflate.h > =================================================================== > RCS file: /cvs/src/lib/libz/deflate.h,v > diff -u -p -r1.20 deflate.h > --- lib/libz/deflate.h 7 Mar 2026 07:27:51 -0000 1.20 > +++ lib/libz/deflate.h 10 Mar 2026 06:44:12 -0000 > @@ -1,5 +1,5 @@ > /* deflate.h -- internal compression state > - * Copyright (C) 1995-2024 Jean-loup Gailly > + * Copyright (C) 1995-2026 Jean-loup Gailly > * For conditions of distribution and use, see copyright notice in zlib.h > */ > > Index: lib/libz/gzguts.h > =================================================================== > RCS file: /cvs/src/lib/libz/gzguts.h,v > diff -u -p -r1.13 gzguts.h > --- lib/libz/gzguts.h 15 Mar 2024 21:32:21 -0000 1.13 > +++ lib/libz/gzguts.h 10 Mar 2026 06:44:12 -0000 > @@ -1,5 +1,5 @@ > /* gzguts.h -- zlib internal header definitions for gz* operations > - * Copyright (C) 2004-2024 Mark Adler > + * Copyright (C) 2004-2026 Mark Adler > * For conditions of distribution and use, see copyright notice in zlib.h > */ > > @@ -183,7 +183,9 @@ typedef struct { > unsigned char *out; /* output buffer (double-sized when reading) */ > int direct; /* 0 if processing gzip, 1 if transparent */ > /* just for reading */ > + int junk; /* -1 = start, 1 = junk candidate, 0 = in gzip */ > int how; /* 0: get header, 1: copy, 2: decompress */ > + int again; /* true if EAGAIN or EWOULDBLOCK on last i/o */ > z_off64_t start; /* where the gzip data started, for rewinding */ > int eof; /* true if end of input file reached */ > int past; /* true if read requested past end */ > @@ -193,7 +195,6 @@ typedef struct { > int reset; /* true if a reset is pending after a Z_FINISH */ > /* seek request */ > z_off64_t skip; /* amount to skip (already rewound if backwards) */ > - int seek; /* true if seek request pending */ > /* error information */ > int err; /* error code */ > char *msg; /* error message */ > Index: lib/libz/gzlib.c > =================================================================== > RCS file: /cvs/src/lib/libz/gzlib.c,v > diff -u -p -r1.11 gzlib.c > --- lib/libz/gzlib.c 15 Mar 2024 21:32:21 -0000 1.11 > +++ lib/libz/gzlib.c 10 Mar 2026 06:44:12 -0000 > @@ -1,5 +1,5 @@ > /* gzlib.c -- zlib functions common to reading and writing gzip files > - * Copyright (C) 2004-2024 Mark Adler > + * Copyright (C) 2004-2026 Mark Adler > * For conditions of distribution and use, see copyright notice in zlib.h > */ > > @@ -52,7 +52,7 @@ char ZLIB_INTERNAL *gz_strwinerror(DWORD > msgbuf[chars] = 0; > } > > - wcstombs(buf, msgbuf, chars + 1); // assumes buf is big enough > + wcstombs(buf, msgbuf, chars + 1); /* assumes buf is big enough */ > LocalFree(msgbuf); > } > else { > @@ -72,10 +72,12 @@ local void gz_reset(gz_statep state) { > state->eof = 0; /* not at end of file */ > state->past = 0; /* have not read past end yet */ > state->how = LOOK; /* look for gzip header */ > + state->junk = -1; /* mark first member */ > } > else /* for writing ... */ > state->reset = 0; /* no deflateReset pending */ > - state->seek = 0; /* no seek request pending */ > + state->again = 0; /* no stalled i/o yet */ > + state->skip = 0; /* no seek request pending */ > gz_error(state, Z_OK, NULL); /* clear error */ > state->x.pos = 0; /* no uncompressed data yet */ > state->strm.avail_in = 0; /* no input data yet */ > @@ -85,16 +87,13 @@ local void gz_reset(gz_statep state) { > local gzFile gz_open(const void *path, int fd, const char *mode) { > gz_statep state; > z_size_t len; > - int oflag; > -#ifdef O_CLOEXEC > - int cloexec = 0; > -#endif > + int oflag = 0; > #ifdef O_EXCL > int exclusive = 0; > #endif > > /* check input */ > - if (path == NULL) > + if (path == NULL || mode == NULL) > return NULL; > > /* allocate gzFile structure to return */ > @@ -103,6 +102,7 @@ local gzFile gz_open(const void *path, i > return NULL; > state->size = 0; /* no buffers allocated yet */ > state->want = GZBUFSIZE; /* requested buffer size */ > + state->err = Z_OK; /* no error yet */ > state->msg = NULL; /* no error message yet */ > > /* interpret mode */ > @@ -133,7 +133,7 @@ local gzFile gz_open(const void *path, i > break; > #ifdef O_CLOEXEC > case 'e': > - cloexec = 1; > + oflag |= O_CLOEXEC; > break; > #endif > #ifdef O_EXCL > @@ -153,6 +153,14 @@ local gzFile gz_open(const void *path, i > case 'F': > state->strategy = Z_FIXED; > break; > + case 'G': > + state->direct = -1; > + break; > +#ifdef O_NONBLOCK > + case 'N': > + oflag |= O_NONBLOCK; > + break; > +#endif > case 'T': > state->direct = 1; > break; > @@ -168,14 +176,25 @@ local gzFile gz_open(const void *path, i > return NULL; > } > > - /* can't force transparent read */ > + /* direct is 0, 1 if "T", or -1 if "G" (last "G" or "T" wins) */ > if (state->mode == GZ_READ) { > - if (state->direct) { > + if (state->direct == 1) { > + /* can't force a transparent read */ > free(state); > return NULL; > } > - state->direct = 1; /* for empty file */ > + if (state->direct == 0) > + /* default when reading is auto-detect of gzip vs. transparent -- > + start with a transparent assumption in case of an empty file */ > + state->direct = 1; > } > + else if (state->direct == -1) { > + /* "G" has no meaning when writing -- disallow it */ > + free(state); > + return NULL; > + } > + /* if reading, direct == 1 for auto-detect, -1 for gzip only; if writing or > + appending, direct == 0 for gzip, 1 for transparent (copy in to out) */ > > /* save the path name for error messages */ > #ifdef WIDECHAR > @@ -207,16 +226,13 @@ local gzFile gz_open(const void *path, i > } > > /* compute the flags for open() */ > - oflag = > + oflag |= > #ifdef O_LARGEFILE > O_LARGEFILE | > #endif > #ifdef O_BINARY > O_BINARY | > #endif > -#ifdef O_CLOEXEC > - (cloexec ? O_CLOEXEC : 0) | > -#endif > (state->mode == GZ_READ ? > O_RDONLY : > (O_WRONLY | O_CREAT | > @@ -234,8 +250,17 @@ local gzFile gz_open(const void *path, i > else if (fd == -2) > state->fd = _wopen(path, oflag, _S_IREAD | _S_IWRITE); > #endif > - else > + else { > +#ifdef O_NONBLOCK > + if (oflag & O_NONBLOCK) > + fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); > +#endif > +#ifdef O_CLOEXEC > + if (oflag & O_CLOEXEC) > + fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | O_CLOEXEC); > +#endif > state->fd = fd; > + } > if (state->fd == -1) { > free(state->path); > free(state); > @@ -362,9 +387,10 @@ z_off64_t ZEXPORT gzseek64(gzFile file, > /* normalize offset to a SEEK_CUR specification */ > if (whence == SEEK_SET) > offset -= state->x.pos; > - else if (state->seek) > - offset += state->skip; > - state->seek = 0; > + else { > + offset += state->past ? 0 : state->skip; > + state->skip = 0; > + } > > /* if within raw area while reading, just go there */ > if (state->mode == GZ_READ && state->how == COPY && > @@ -375,7 +401,7 @@ z_off64_t ZEXPORT gzseek64(gzFile file, > state->x.have = 0; > state->eof = 0; > state->past = 0; > - state->seek = 0; > + state->skip = 0; > gz_error(state, Z_OK, NULL); > state->strm.avail_in = 0; > state->x.pos += offset; > @@ -404,10 +430,7 @@ z_off64_t ZEXPORT gzseek64(gzFile file, > } > > /* request skip (if not zero) */ > - if (offset) { > - state->seek = 1; > - state->skip = offset; > - } > + state->skip = offset; > return state->x.pos + offset; > } > > @@ -431,7 +454,7 @@ z_off64_t ZEXPORT gztell64(gzFile file) > return -1; > > /* return position */ > - return state->x.pos + (state->seek ? state->skip : 0); > + return state->x.pos + (state->past ? 0 : state->skip); > } > > /* -- see zlib.h -- */ > @@ -538,7 +561,7 @@ void ZLIB_INTERNAL gz_error(gz_statep st > } > > /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ > - if (err != Z_OK && err != Z_BUF_ERROR) > + if (err != Z_OK && err != Z_BUF_ERROR && !state->again) > state->x.have = 0; > > /* set error code, and if no message, then done */ > @@ -575,6 +598,7 @@ unsigned ZLIB_INTERNAL gz_intmax(void) { > return INT_MAX; > #else > unsigned p = 1, q; > + > do { > q = p; > p <<= 1; > Index: lib/libz/gzread.c > =================================================================== > RCS file: /cvs/src/lib/libz/gzread.c,v > diff -u -p -r1.7 gzread.c > --- lib/libz/gzread.c 10 Feb 2024 06:10:04 -0000 1.7 > +++ lib/libz/gzread.c 10 Mar 2026 06:44:12 -0000 > @@ -1,5 +1,5 @@ > /* gzread.c -- zlib functions for reading gzip files > - * Copyright (C) 2004-2017 Mark Adler > + * Copyright (C) 2004-2026 Mark Adler > * For conditions of distribution and use, see copyright notice in zlib.h > */ > > @@ -8,23 +8,36 @@ > /* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from > state->fd, and update state->eof, state->err, and state->msg as appropriate. > This function needs to loop on read(), since read() is not guaranteed to > - read the number of bytes requested, depending on the type of descriptor. */ > + read the number of bytes requested, depending on the type of descriptor. It > + also needs to loop to manage the fact that read() returns an int. If the > + descriptor is non-blocking and read() returns with no data in order to avoid > + blocking, then gz_load() will return 0 if some data has been read, or -1 if > + no data has been read. Either way, state->again is set true to indicate a > + non-blocking event. If errno is non-zero on return, then there was an error > + signaled from read(). *have is set to the number of bytes read. */ > local int gz_load(gz_statep state, unsigned char *buf, unsigned len, > unsigned *have) { > int ret; > unsigned get, max = ((unsigned)-1 >> 2) + 1; > > + state->again = 0; > + errno = 0; > *have = 0; > do { > get = len - *have; > if (get > max) > get = max; > - ret = read(state->fd, buf + *have, get); > + ret = (int)read(state->fd, buf + *have, get); > if (ret <= 0) > break; > *have += (unsigned)ret; > } while (*have < len); > if (ret < 0) { > + if (errno == EAGAIN || errno == EWOULDBLOCK) { > + state->again = 1; > + if (*have != 0) > + return 0; > + } > gz_error(state, Z_ERRNO, zstrerror()); > return -1; > } > @@ -50,10 +63,14 @@ local int gz_avail(gz_statep state) { > if (strm->avail_in) { /* copy what's there to the start */ > unsigned char *p = state->in; > unsigned const char *q = strm->next_in; > - unsigned n = strm->avail_in; > - do { > - *p++ = *q++; > - } while (--n); > + > + if (q != p) { > + unsigned n = strm->avail_in; > + > + do { > + *p++ = *q++; > + } while (--n); > + } > } > if (gz_load(state, state->in + strm->avail_in, > state->size - strm->avail_in, &got) == -1) > @@ -104,39 +121,44 @@ local int gz_look(gz_statep state) { > } > } > > - /* get at least the magic bytes in the input buffer */ > - if (strm->avail_in < 2) { > - if (gz_avail(state) == -1) > - return -1; > - if (strm->avail_in == 0) > - return 0; > - } > - > - /* look for gzip magic bytes -- if there, do gzip decoding (note: there is > - a logical dilemma here when considering the case of a partially written > - gzip file, to wit, if a single 31 byte is written, then we cannot tell > - whether this is a single-byte file, or just a partially written gzip > - file -- for here we assume that if a gzip file is being written, then > - the header will be written in a single operation, so that reading a > - single byte is sufficient indication that it is not a gzip file) */ > - if (strm->avail_in > 1 && > - strm->next_in[0] == 31 && strm->next_in[1] == 139) { > + /* if transparent reading is disabled, which would only be at the start, or > + if we're looking for a gzip member after the first one, which is not at > + the start, then proceed directly to look for a gzip member next */ > + if (state->direct == -1 || state->junk == 0) { > inflateReset(strm); > state->how = GZIP; > + state->junk = state->junk != -1; > state->direct = 0; > return 0; > } > > - /* no gzip header -- if we were decoding gzip before, then this is trailing > - garbage. Ignore the trailing garbage and finish. */ > - if (state->direct == 0) { > - strm->avail_in = 0; > - state->eof = 1; > - state->x.have = 0; > + /* otherwise we're at the start with auto-detect -- we check to see if the > + first four bytes could be gzip header in order to decide whether or not > + this will be a transparent read */ > + > + /* load any header bytes into the input buffer -- if the input is empty, > + then it's not an error as this is a transparent read of zero bytes */ > + if (gz_avail(state) == -1) > + return -1; > + if (strm->avail_in == 0 || (state->again && strm->avail_in < 4)) > + /* if non-blocking input stalled before getting four bytes, then > + return and wait until a later call has accumulated enough */ > + return 0; > + > + /* see if this is (likely) gzip input -- if the first four bytes are > + consistent with a gzip header, then go look for the first gzip member, > + otherwise proceed to copy the input transparently */ > + if (strm->avail_in > 3 && > + strm->next_in[0] == 31 && strm->next_in[1] == 139 && > + strm->next_in[2] == 8 && strm->next_in[3] < 32) { > + inflateReset(strm); > + state->how = GZIP; > + state->junk = 1; > + state->direct = 0; > return 0; > } > > - /* doing raw i/o, copy any leftover input to output -- this assumes that > + /* doing raw i/o: copy any leftover input to output -- this assumes that > the output buffer is larger than the input buffer, which also assures > space for gzungetc() */ > state->x.next = state->out; > @@ -144,15 +166,17 @@ local int gz_look(gz_statep state) { > state->x.have = strm->avail_in; > strm->avail_in = 0; > state->how = COPY; > - state->direct = 1; > return 0; > } > > /* Decompress from input to the provided next_out and avail_out in the state. > On return, state->x.have and state->x.next point to the just decompressed > - data. If the gzip stream completes, state->how is reset to LOOK to look for > - the next gzip stream or raw data, once state->x.have is depleted. Returns 0 > - on success, -1 on failure. */ > + data. If the gzip stream completes, state->how is reset to LOOK to look for > + the next gzip stream or raw data, once state->x.have is depleted. Returns 0 > + on success, -1 on failure. If EOF is reached when looking for more input to > + complete the gzip member, then an unexpected end of file error is raised. > + If there is no more input, but state->again is true, then EOF has not been > + reached, and no error is raised. */ > local int gz_decomp(gz_statep state) { > int ret = Z_OK; > unsigned had; > @@ -162,28 +186,41 @@ local int gz_decomp(gz_statep state) { > had = strm->avail_out; > do { > /* get more input for inflate() */ > - if (strm->avail_in == 0 && gz_avail(state) == -1) > - return -1; > + if (strm->avail_in == 0 && gz_avail(state) == -1) { > + ret = state->err; > + break; > + } > if (strm->avail_in == 0) { > - gz_error(state, Z_BUF_ERROR, "unexpected end of file"); > + if (!state->again) > + gz_error(state, Z_BUF_ERROR, "unexpected end of file"); > break; > } > > /* decompress and handle errors */ > ret = inflate(strm, Z_NO_FLUSH); > + if (strm->avail_out < had) > + /* any decompressed data marks this as a real gzip stream */ > + state->junk = 0; > if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { > gz_error(state, Z_STREAM_ERROR, > "internal error: inflate stream corrupt"); > - return -1; > + break; > } > if (ret == Z_MEM_ERROR) { > gz_error(state, Z_MEM_ERROR, "out of memory"); > - return -1; > + break; > } > if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ > + if (state->junk == 1) { /* trailing garbage is ok */ > + strm->avail_in = 0; > + state->eof = 1; > + state->how = LOOK; > + ret = Z_OK; > + break; > + } > gz_error(state, Z_DATA_ERROR, > strm->msg == NULL ? "compressed data error" : strm->msg); > - return -1; > + break; > } > } while (strm->avail_out && ret != Z_STREAM_END); > > @@ -192,11 +229,14 @@ local int gz_decomp(gz_statep state) { > state->x.next = strm->next_out - state->x.have; > > /* if the gzip stream completed successfully, look for another */ > - if (ret == Z_STREAM_END) > + if (ret == Z_STREAM_END) { > + state->junk = 0; > state->how = LOOK; > + return 0; > + } > > - /* good decompression */ > - return 0; > + /* return decompression status */ > + return ret != Z_OK ? -1 : 0; > } > > /* Fetch data and put it in the output buffer. Assumes state->x.have is 0. > @@ -227,25 +267,31 @@ local int gz_fetch(gz_statep state) { > strm->next_out = state->out; > if (gz_decomp(state) == -1) > return -1; > + break; > + default: > + gz_error(state, Z_STREAM_ERROR, "state corrupt"); > + return -1; > } > } while (state->x.have == 0 && (!state->eof || strm->avail_in)); > return 0; > } > > -/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ > -local int gz_skip(gz_statep state, z_off64_t len) { > +/* Skip state->skip (> 0) uncompressed bytes of output. Return -1 on error, 0 > + on success. */ > +local int gz_skip(gz_statep state) { > unsigned n; > > /* skip over len bytes or reach end-of-file, whichever comes first */ > - while (len) > + do { > /* skip over whatever is in output buffer */ > if (state->x.have) { > - n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? > - (unsigned)len : state->x.have; > + n = GT_OFF(state->x.have) || > + (z_off64_t)state->x.have > state->skip ? > + (unsigned)state->skip : state->x.have; > state->x.have -= n; > state->x.next += n; > state->x.pos += n; > - len -= n; > + state->skip -= n; > } > > /* output buffer empty -- return if we're at the end of the input */ > @@ -258,30 +304,32 @@ local int gz_skip(gz_statep state, z_off > if (gz_fetch(state) == -1) > return -1; > } > + } while (state->skip); > return 0; > } > > /* Read len bytes into buf from file, or less than len up to the end of the > - input. Return the number of bytes read. If zero is returned, either the > - end of file was reached, or there was an error. state->err must be > - consulted in that case to determine which. */ > + input. Return the number of bytes read. If zero is returned, either the end > + of file was reached, or there was an error. state->err must be consulted in > + that case to determine which. If there was an error, but some uncompressed > + bytes were read before the error, then that count is returned. The error is > + still recorded, and so is deferred until the next call. */ > local z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) { > z_size_t got; > unsigned n; > + int err; > > /* if len is zero, avoid unnecessary operations */ > if (len == 0) > return 0; > > /* process a skip request */ > - if (state->seek) { > - state->seek = 0; > - if (gz_skip(state, state->skip) == -1) > - return 0; > - } > + if (state->skip && gz_skip(state) == -1) > + return 0; > > /* get len bytes to buf, or less than len if at the end */ > got = 0; > + err = 0; > do { > /* set n to the maximum amount of len that fits in an unsigned int */ > n = (unsigned)-1; > @@ -295,37 +343,36 @@ local z_size_t gz_read(gz_statep state, > memcpy(buf, state->x.next, n); > state->x.next += n; > state->x.have -= n; > + if (state->err != Z_OK) > + /* caught deferred error from gz_fetch() */ > + err = -1; > } > > /* output buffer empty -- return if we're at the end of the input */ > - else if (state->eof && state->strm.avail_in == 0) { > - state->past = 1; /* tried to read past end */ > + else if (state->eof && state->strm.avail_in == 0) > break; > - } > > /* need output data -- for small len or new stream load up our output > - buffer */ > + buffer, so that gzgetc() can be fast */ > else if (state->how == LOOK || n < (state->size << 1)) { > /* get more output, looking for header if required */ > - if (gz_fetch(state) == -1) > - return 0; > + if (gz_fetch(state) == -1 && state->x.have == 0) > + /* if state->x.have != 0, error will be caught after copy */ > + err = -1; > continue; /* no progress yet -- go back to copy above */ > /* the copy above assures that we will leave with space in the > output buffer, allowing at least one gzungetc() to succeed */ > } > > /* large len -- read directly into user buffer */ > - else if (state->how == COPY) { /* read directly */ > - if (gz_load(state, (unsigned char *)buf, n, &n) == -1) > - return 0; > - } > + else if (state->how == COPY) /* read directly */ > + err = gz_load(state, (unsigned char *)buf, n, &n); > > /* large len -- decompress directly into user buffer */ > else { /* state->how == GZIP */ > state->strm.avail_out = n; > state->strm.next_out = (unsigned char *)buf; > - if (gz_decomp(state) == -1) > - return 0; > + err = gz_decomp(state); > n = state->x.have; > state->x.have = 0; > } > @@ -335,7 +382,11 @@ local z_size_t gz_read(gz_statep state, > buf = (char *)buf + n; > got += n; > state->x.pos += n; > - } while (len); > + } while (len && !err); > + > + /* note read past eof */ > + if (len && state->eof) > + state->past = 1; > > /* return number of bytes read into user buffer */ > return got; > @@ -345,15 +396,17 @@ local z_size_t gz_read(gz_statep state, > int ZEXPORT gzread(gzFile file, voidp buf, unsigned len) { > gz_statep state; > > - /* get internal structure */ > + /* get internal structure and check that it's for reading */ > if (file == NULL) > return -1; > state = (gz_statep)file; > + if (state->mode != GZ_READ) > + return -1; > > - /* check that we're reading and that there's no (serious) error */ > - if (state->mode != GZ_READ || > - (state->err != Z_OK && state->err != Z_BUF_ERROR)) > + /* check that there was no (serious) error */ > + if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again) > return -1; > + gz_error(state, Z_OK, NULL); > > /* since an int is returned, make sure len fits in one, otherwise return > with an error (this avoids a flaw in the interface) */ > @@ -366,10 +419,19 @@ int ZEXPORT gzread(gzFile file, voidp bu > len = (unsigned)gz_read(state, buf, len); > > /* check for an error */ > - if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR) > - return -1; > + if (len == 0) { > + if (state->err != Z_OK && state->err != Z_BUF_ERROR) > + return -1; > + if (state->again) { > + /* non-blocking input stalled after some input was read, but no > + uncompressed bytes were produced -- let the application know > + this isn't EOF */ > + gz_error(state, Z_ERRNO, zstrerror()); > + return -1; > + } > + } > > - /* return the number of bytes read (this is assured to fit in an int) */ > + /* return the number of bytes read */ > return (int)len; > } > > @@ -379,15 +441,17 @@ z_size_t ZEXPORT gzfread(voidp buf, z_si > z_size_t len; > gz_statep state; > > - /* get internal structure */ > + /* get internal structure and check that it's for reading */ > if (file == NULL) > return 0; > state = (gz_statep)file; > + if (state->mode != GZ_READ) > + return 0; > > - /* check that we're reading and that there's no (serious) error */ > - if (state->mode != GZ_READ || > - (state->err != Z_OK && state->err != Z_BUF_ERROR)) > + /* check that there was no (serious) error */ > + if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again) > return 0; > + gz_error(state, Z_OK, NULL); > > /* compute bytes to read -- error on overflow */ > len = nitems * size; > @@ -410,15 +474,17 @@ int ZEXPORT gzgetc(gzFile file) { > unsigned char buf[1]; > gz_statep state; > > - /* get internal structure */ > + /* get internal structure and check that it's for reading */ > if (file == NULL) > return -1; > state = (gz_statep)file; > + if (state->mode != GZ_READ) > + return -1; > > - /* check that we're reading and that there's no (serious) error */ > - if (state->mode != GZ_READ || > - (state->err != Z_OK && state->err != Z_BUF_ERROR)) > + /* check that there was no (serious) error */ > + if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again) > return -1; > + gz_error(state, Z_OK, NULL); > > /* try output buffer (no need to check for skip request) */ > if (state->x.have) { > @@ -439,26 +505,25 @@ int ZEXPORT gzgetc_(gzFile file) { > int ZEXPORT gzungetc(int c, gzFile file) { > gz_statep state; > > - /* get internal structure */ > + /* get internal structure and check that it's for reading */ > if (file == NULL) > return -1; > state = (gz_statep)file; > + if (state->mode != GZ_READ) > + return -1; > > /* in case this was just opened, set up the input buffer */ > - if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) > + if (state->how == LOOK && state->x.have == 0) > (void)gz_look(state); > > - /* check that we're reading and that there's no (serious) error */ > - if (state->mode != GZ_READ || > - (state->err != Z_OK && state->err != Z_BUF_ERROR)) > + /* check that there was no (serious) error */ > + if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again) > return -1; > + gz_error(state, Z_OK, NULL); > > /* process a skip request */ > - if (state->seek) { > - state->seek = 0; > - if (gz_skip(state, state->skip) == -1) > - return -1; > - } > + if (state->skip && gz_skip(state) == -1) > + return -1; > > /* can't push EOF */ > if (c < 0) > @@ -484,6 +549,7 @@ int ZEXPORT gzungetc(int c, gzFile file) > if (state->x.next == state->out) { > unsigned char *src = state->out + state->x.have; > unsigned char *dest = state->out + (state->size << 1); > + > while (src > state->out) > *--dest = *--src; > state->x.next = dest; > @@ -503,32 +569,31 @@ char * ZEXPORT gzgets(gzFile file, char > unsigned char *eol; > gz_statep state; > > - /* check parameters and get internal structure */ > + /* check parameters, get internal structure, and check that it's for > + reading */ > if (file == NULL || buf == NULL || len < 1) > return NULL; > state = (gz_statep)file; > + if (state->mode != GZ_READ) > + return NULL; > > - /* check that we're reading and that there's no (serious) error */ > - if (state->mode != GZ_READ || > - (state->err != Z_OK && state->err != Z_BUF_ERROR)) > + /* check that there was no (serious) error */ > + if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again) > return NULL; > + gz_error(state, Z_OK, NULL); > > /* process a skip request */ > - if (state->seek) { > - state->seek = 0; > - if (gz_skip(state, state->skip) == -1) > - return NULL; > - } > + if (state->skip && gz_skip(state) == -1) > + return NULL; > > - /* copy output bytes up to new line or len - 1, whichever comes first -- > - append a terminating zero to the string (we don't check for a zero in > - the contents, let the user worry about that) */ > + /* copy output up to a new line, len-1 bytes, or there is no more output, > + whichever comes first */ > str = buf; > left = (unsigned)len - 1; > if (left) do { > /* assure that something is in the output buffer */ > if (state->x.have == 0 && gz_fetch(state) == -1) > - return NULL; /* error */ > + break; /* error */ > if (state->x.have == 0) { /* end of file */ > state->past = 1; /* read past end */ > break; /* return what we have */ > @@ -549,7 +614,9 @@ char * ZEXPORT gzgets(gzFile file, char > buf += n; > } while (left && eol == NULL); > > - /* return terminated string, or if nothing, end of file */ > + /* append a terminating zero to the string (we don't check for a zero in > + the contents, let the user worry about that) -- return the terminated > + string, or if nothing was read, NULL */ > if (buf == str) > return NULL; > buf[0] = 0; > @@ -571,7 +638,7 @@ int ZEXPORT gzdirect(gzFile file) { > (void)gz_look(state); > > /* return 1 if transparent, 0 if processing a gzip stream */ > - return state->direct; > + return state->direct == 1; > } > > /* -- see zlib.h -- */ > @@ -579,12 +646,10 @@ int ZEXPORT gzclose_r(gzFile file) { > int ret, err; > gz_statep state; > > - /* get internal structure */ > + /* get internal structure and check that it's for reading */ > if (file == NULL) > return Z_STREAM_ERROR; > state = (gz_statep)file; > - > - /* check that we're reading */ > if (state->mode != GZ_READ) > return Z_STREAM_ERROR; > > Index: lib/libz/gzwrite.c > =================================================================== > RCS file: /cvs/src/lib/libz/gzwrite.c,v > diff -u -p -r1.5 gzwrite.c > --- lib/libz/gzwrite.c 25 Apr 2023 16:59:10 -0000 1.5 > +++ lib/libz/gzwrite.c 10 Mar 2026 06:44:12 -0000 > @@ -1,5 +1,5 @@ > /* gzwrite.c -- zlib functions for writing gzip files > - * Copyright (C) 2004-2019 Mark Adler > + * Copyright (C) 2004-2026 Mark Adler > * For conditions of distribution and use, see copyright notice in zlib.h > */ > > @@ -74,9 +74,13 @@ local int gz_comp(gz_statep state, int f > /* write directly if requested */ > if (state->direct) { > while (strm->avail_in) { > + errno = 0; > + state->again = 0; > put = strm->avail_in > max ? max : strm->avail_in; > - writ = write(state->fd, strm->next_in, put); > + writ = (int)write(state->fd, strm->next_in, put); > if (writ < 0) { > + if (errno == EAGAIN || errno == EWOULDBLOCK) > + state->again = 1; > gz_error(state, Z_ERRNO, zstrerror()); > return -1; > } > @@ -88,8 +92,9 @@ local int gz_comp(gz_statep state, int f > > /* check for a pending reset */ > if (state->reset) { > - /* don't start a new gzip member unless there is data to write */ > - if (strm->avail_in == 0) > + /* don't start a new gzip member unless there is data to write and > + we're not flushing */ > + if (strm->avail_in == 0 && flush == Z_NO_FLUSH) > return 0; > deflateReset(strm); > state->reset = 0; > @@ -103,10 +108,14 @@ local int gz_comp(gz_statep state, int f > if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && > (flush != Z_FINISH || ret == Z_STREAM_END))) { > while (strm->next_out > state->x.next) { > + errno = 0; > + state->again = 0; > put = strm->next_out - state->x.next > (int)max ? max : > (unsigned)(strm->next_out - state->x.next); > - writ = write(state->fd, state->x.next, put); > + writ = (int)write(state->fd, state->x.next, put); > if (writ < 0) { > + if (errno == EAGAIN || errno == EWOULDBLOCK) > + state->again = 1; > gz_error(state, Z_ERRNO, zstrerror()); > return -1; > } > @@ -138,10 +147,12 @@ local int gz_comp(gz_statep state, int f > return 0; > } > > -/* Compress len zeros to output. Return -1 on a write error or memory > - allocation failure by gz_comp(), or 0 on success. */ > -local int gz_zero(gz_statep state, z_off64_t len) { > - int first; > +/* Compress state->skip (> 0) zeros to output. Return -1 on a write error or > + memory allocation failure by gz_comp(), or 0 on success. state->skip is > + updated with the number of successfully written zeros, in case there is a > + stall on a non-blocking write destination. */ > +local int gz_zero(gz_statep state) { > + int first, ret; > unsigned n; > z_streamp strm = &(state->strm); > > @@ -149,29 +160,34 @@ local int gz_zero(gz_statep state, z_off > if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) > return -1; > > - /* compress len zeros (len guaranteed > 0) */ > + /* compress state->skip zeros */ > first = 1; > - while (len) { > - n = GT_OFF(state->size) || (z_off64_t)state->size > len ? > - (unsigned)len : state->size; > + do { > + n = GT_OFF(state->size) || (z_off64_t)state->size > state->skip ? > + (unsigned)state->skip : state->size; > if (first) { > memset(state->in, 0, n); > first = 0; > } > strm->avail_in = n; > strm->next_in = state->in; > + ret = gz_comp(state, Z_NO_FLUSH); > + n -= strm->avail_in; > state->x.pos += n; > - if (gz_comp(state, Z_NO_FLUSH) == -1) > + state->skip -= n; > + if (ret == -1) > return -1; > - len -= n; > - } > + } while (state->skip); > return 0; > } > > /* Write len bytes from buf to file. Return the number of bytes written. If > - the returned value is less than len, then there was an error. */ > + the returned value is less than len, then there was an error. If the error > + was a non-blocking stall, then the number of bytes consumed is returned. > + For any other error, 0 is returned. */ > local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) { > z_size_t put = len; > + int ret; > > /* if len is zero, avoid unnecessary operations */ > if (len == 0) > @@ -182,16 +198,13 @@ local z_size_t gz_write(gz_statep state, > return 0; > > /* check for seek request */ > - if (state->seek) { > - state->seek = 0; > - if (gz_zero(state, state->skip) == -1) > - return 0; > - } > + if (state->skip && gz_zero(state) == -1) > + return 0; > > /* for small len, copy to input buffer, otherwise compress directly */ > if (len < state->size) { > /* copy to input buffer, compress when full */ > - do { > + for (;;) { > unsigned have, copy; > > if (state->strm.avail_in == 0) > @@ -206,9 +219,11 @@ local z_size_t gz_write(gz_statep state, > state->x.pos += copy; > buf = (const char *)buf + copy; > len -= copy; > - if (len && gz_comp(state, Z_NO_FLUSH) == -1) > - return 0; > - } while (len); > + if (len == 0) > + break; > + if (gz_comp(state, Z_NO_FLUSH) == -1) > + return state->again ? put - len : 0; > + } > } > else { > /* consume whatever's left in the input buffer */ > @@ -219,13 +234,16 @@ local z_size_t gz_write(gz_statep state, > state->strm.next_in = (z_const Bytef *)buf; > do { > unsigned n = (unsigned)-1; > + > if (n > len) > n = (unsigned)len; > state->strm.avail_in = n; > + ret = gz_comp(state, Z_NO_FLUSH); > + n -= state->strm.avail_in; > state->x.pos += n; > - if (gz_comp(state, Z_NO_FLUSH) == -1) > - return 0; > len -= n; > + if (ret == -1) > + return state->again ? put - len : 0; > } while (len); > } > > @@ -242,9 +260,10 @@ int ZEXPORT gzwrite(gzFile file, voidpc > return 0; > state = (gz_statep)file; > > - /* check that we're writing and that there's no error */ > - if (state->mode != GZ_WRITE || state->err != Z_OK) > + /* check that we're writing and that there's no (serious) error */ > + if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again)) > return 0; > + gz_error(state, Z_OK, NULL); > > /* since an int is returned, make sure len fits in one, otherwise return > with an error (this avoids a flaw in the interface) */ > @@ -268,9 +287,10 @@ z_size_t ZEXPORT gzfwrite(voidpc buf, z_ > return 0; > state = (gz_statep)file; > > - /* check that we're writing and that there's no error */ > - if (state->mode != GZ_WRITE || state->err != Z_OK) > + /* check that we're writing and that there's no (serious) error */ > + if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again)) > return 0; > + gz_error(state, Z_OK, NULL); > > /* compute bytes to read -- error on overflow */ > len = nitems * size; > @@ -296,16 +316,14 @@ int ZEXPORT gzputc(gzFile file, int c) { > state = (gz_statep)file; > strm = &(state->strm); > > - /* check that we're writing and that there's no error */ > - if (state->mode != GZ_WRITE || state->err != Z_OK) > + /* check that we're writing and that there's no (serious) error */ > + if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again)) > return -1; > + gz_error(state, Z_OK, NULL); > > /* check for seek request */ > - if (state->seek) { > - state->seek = 0; > - if (gz_zero(state, state->skip) == -1) > - return -1; > - } > + if (state->skip && gz_zero(state) == -1) > + return -1; > > /* try writing to input buffer for speed (state->size == 0 if buffer not > initialized) */ > @@ -338,9 +356,10 @@ int ZEXPORT gzputs(gzFile file, const ch > return -1; > state = (gz_statep)file; > > - /* check that we're writing and that there's no error */ > - if (state->mode != GZ_WRITE || state->err != Z_OK) > + /* check that we're writing and that there's no (serious) error */ > + if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again)) > return -1; > + gz_error(state, Z_OK, NULL); > > /* write string */ > len = strlen(s); > @@ -349,16 +368,47 @@ int ZEXPORT gzputs(gzFile file, const ch > return -1; > } > put = gz_write(state, s, len); > - return put < len ? -1 : (int)len; > + return len && put == 0 ? -1 : (int)put; > } > > +#if (((!defined(STDC) && !defined(Z_HAVE_STDARG_H)) || !defined(NO_vsnprintf)) && \ > + (defined(STDC) || defined(Z_HAVE_STDARG_H) || !defined(NO_snprintf))) || \ > + defined(ZLIB_INSECURE) > +/* If the second half of the input buffer is occupied, write out the contents. > + If there is any input remaining due to a non-blocking stall on write, move > + it to the start of the buffer. Return true if this did not open up the > + second half of the buffer. state->err should be checked after this to > + handle a gz_comp() error. */ > +local int gz_vacate(gz_statep state) { > + z_streamp strm; > + > + strm = &(state->strm); > + if (strm->next_in + strm->avail_in <= state->in + state->size) > + return 0; > + (void)gz_comp(state, Z_NO_FLUSH); > + if (strm->avail_in == 0) { > + strm->next_in = state->in; > + return 0; > + } > + memmove(state->in, strm->next_in, strm->avail_in); > + strm->next_in = state->in; > + return strm->avail_in > state->size; > +} > +#endif > + > #if defined(STDC) || defined(Z_HAVE_STDARG_H) > #include > > /* -- see zlib.h -- */ > int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) { > - int len; > - unsigned left; > +#if defined(NO_vsnprintf) && !defined(ZLIB_INSECURE) > +#warning "vsnprintf() not available -- gzprintf() stub returns Z_STREAM_ERROR" > +#warning "you can recompile with ZLIB_INSECURE defined to use vsprintf()" > + /* prevent use of insecure vsprintf(), unless purposefully requested */ > + (void)file, (void)format, (void)va; > + return Z_STREAM_ERROR; > +#else > + int len, ret; > char *next; > gz_statep state; > z_streamp strm; > @@ -369,24 +419,34 @@ int ZEXPORTVA gzvprintf(gzFile file, con > state = (gz_statep)file; > strm = &(state->strm); > > - /* check that we're writing and that there's no error */ > - if (state->mode != GZ_WRITE || state->err != Z_OK) > + /* check that we're writing and that there's no (serious) error */ > + if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again)) > return Z_STREAM_ERROR; > + gz_error(state, Z_OK, NULL); > > /* make sure we have some buffer space */ > if (state->size == 0 && gz_init(state) == -1) > return state->err; > > /* check for seek request */ > - if (state->seek) { > - state->seek = 0; > - if (gz_zero(state, state->skip) == -1) > - return state->err; > - } > + if (state->skip && gz_zero(state) == -1) > + return state->err; > > /* do the printf() into the input buffer, put length in len -- the input > - buffer is double-sized just for this function, so there is guaranteed to > - be state->size bytes available after the current contents */ > + buffer is double-sized just for this function, so there should be > + state->size bytes available after the current contents */ > + ret = gz_vacate(state); > + if (state->err) { > + if (ret && state->again) { > + /* There was a non-blocking stall on write, resulting in the part > + of the second half of the output buffer being occupied. Return > + a Z_BUF_ERROR to let the application know that this gzprintf() > + needs to be retried. */ > + gz_error(state, Z_BUF_ERROR, "stalled write on gzprintf"); > + } > + if (!state->again) > + return state->err; > + } > if (strm->avail_in == 0) > strm->next_in = state->in; > next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in); > @@ -412,19 +472,16 @@ int ZEXPORTVA gzvprintf(gzFile file, con > if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0) > return 0; > > - /* update buffer and position, compress first half if past that */ > + /* update buffer and position */ > strm->avail_in += (unsigned)len; > state->x.pos += len; > - if (strm->avail_in >= state->size) { > - left = strm->avail_in - state->size; > - strm->avail_in = state->size; > - if (gz_comp(state, Z_NO_FLUSH) == -1) > - return state->err; > - memmove(state->in, state->in + state->size, left); > - strm->next_in = state->in; > - strm->avail_in = left; > - } > + > + /* write out buffer if more than half is occupied */ > + ret = gz_vacate(state); > + if (state->err && !state->again) > + return state->err; > return len; > +#endif > } > > int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) { > @@ -444,6 +501,17 @@ int ZEXPORTVA gzprintf(gzFile file, cons > int a4, int a5, int a6, int a7, int a8, int a9, int a10, > int a11, int a12, int a13, int a14, int a15, int a16, > int a17, int a18, int a19, int a20) { > +#if defined(NO_snprintf) && !defined(ZLIB_INSECURE) > +#warning "snprintf() not available -- gzprintf() stub returns Z_STREAM_ERROR" > +#warning "you can recompile with ZLIB_INSECURE defined to use sprintf()" > + /* prevent use of insecure sprintf(), unless purposefully requested */ > + (void)file, (void)format, (void)a1, (void)a2, (void)a3, (void)a4, (void)a5, > + (void)a6, (void)a7, (void)a8, (void)a9, (void)a10, (void)a11, (void)a12, > + (void)a13, (void)a14, (void)a15, (void)a16, (void)a17, (void)a18, > + (void)a19, (void)a20; > + return Z_STREAM_ERROR; > +#else > + int ret; > unsigned len, left; > char *next; > gz_statep state; > @@ -459,24 +527,34 @@ int ZEXPORTVA gzprintf(gzFile file, cons > if (sizeof(int) != sizeof(void *)) > return Z_STREAM_ERROR; > > - /* check that we're writing and that there's no error */ > - if (state->mode != GZ_WRITE || state->err != Z_OK) > + /* check that we're writing and that there's no (serious) error */ > + if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again)) > return Z_STREAM_ERROR; > + gz_error(state, Z_OK, NULL); > > /* make sure we have some buffer space */ > if (state->size == 0 && gz_init(state) == -1) > - return state->error; > + return state->err; > > /* check for seek request */ > - if (state->seek) { > - state->seek = 0; > - if (gz_zero(state, state->skip) == -1) > - return state->error; > - } > + if (state->skip && gz_zero(state) == -1) > + return state->err; > > /* do the printf() into the input buffer, put length in len -- the input > buffer is double-sized just for this function, so there is guaranteed to > be state->size bytes available after the current contents */ > + ret = gz_vacate(state); > + if (state->err) { > + if (ret && state->again) { > + /* There was a non-blocking stall on write, resulting in the part > + of the second half of the output buffer being occupied. Return > + a Z_BUF_ERROR to let the application know that this gzprintf() > + needs to be retried. */ > + gz_error(state, Z_BUF_ERROR, "stalled write on gzprintf"); > + } > + if (!state->again) > + return state->err; > + } > if (strm->avail_in == 0) > strm->next_in = state->in; > next = (char *)(strm->next_in + strm->avail_in); > @@ -510,16 +588,13 @@ int ZEXPORTVA gzprintf(gzFile file, cons > /* update buffer and position, compress first half if past that */ > strm->avail_in += len; > state->x.pos += len; > - if (strm->avail_in >= state->size) { > - left = strm->avail_in - state->size; > - strm->avail_in = state->size; > - if (gz_comp(state, Z_NO_FLUSH) == -1) > - return state->err; > - memmove(state->in, state->in + state->size, left); > - strm->next_in = state->in; > - strm->avail_in = left; > - } > + > + /* write out buffer if more than half is occupied */ > + ret = gz_vacate(state); > + if (state->err && !state->again) > + return state->err; > return (int)len; > +#endif > } > > #endif > @@ -533,20 +608,18 @@ int ZEXPORT gzflush(gzFile file, int flu > return Z_STREAM_ERROR; > state = (gz_statep)file; > > - /* check that we're writing and that there's no error */ > - if (state->mode != GZ_WRITE || state->err != Z_OK) > + /* check that we're writing and that there's no (serious) error */ > + if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again)) > return Z_STREAM_ERROR; > + gz_error(state, Z_OK, NULL); > > /* check flush parameter */ > if (flush < 0 || flush > Z_FINISH) > return Z_STREAM_ERROR; > > /* check for seek request */ > - if (state->seek) { > - state->seek = 0; > - if (gz_zero(state, state->skip) == -1) > - return state->err; > - } > + if (state->skip && gz_zero(state) == -1) > + return state->err; > > /* compress remaining data with requested flush */ > (void)gz_comp(state, flush); > @@ -564,20 +637,19 @@ int ZEXPORT gzsetparams(gzFile file, int > state = (gz_statep)file; > strm = &(state->strm); > > - /* check that we're writing and that there's no error */ > - if (state->mode != GZ_WRITE || state->err != Z_OK || state->direct) > + /* check that we're compressing and that there's no (serious) error */ > + if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again) || > + state->direct) > return Z_STREAM_ERROR; > + gz_error(state, Z_OK, NULL); > > /* if no change is requested, then do nothing */ > if (level == state->level && strategy == state->strategy) > return Z_OK; > > /* check for seek request */ > - if (state->seek) { > - state->seek = 0; > - if (gz_zero(state, state->skip) == -1) > - return state->err; > - } > + if (state->skip && gz_zero(state) == -1) > + return state->err; > > /* change compression parameters for subsequent input */ > if (state->size) { > @@ -606,11 +678,8 @@ int ZEXPORT gzclose_w(gzFile file) { > return Z_STREAM_ERROR; > > /* check for seek request */ > - if (state->seek) { > - state->seek = 0; > - if (gz_zero(state, state->skip) == -1) > - ret = state->err; > - } > + if (state->skip && gz_zero(state) == -1) > + ret = state->err; > > /* flush, free memory, and close file */ > if (gz_comp(state, Z_FINISH) == -1) > Index: lib/libz/infback.c > =================================================================== > RCS file: /cvs/src/lib/libz/infback.c,v > diff -u -p -r1.13 infback.c > --- lib/libz/infback.c 3 Feb 2025 19:17:57 -0000 1.13 > +++ lib/libz/infback.c 10 Mar 2026 06:44:12 -0000 > @@ -1,5 +1,5 @@ > /* infback.c -- inflate using a call-back interface > - * Copyright (C) 1995-2022 Mark Adler > + * Copyright (C) 1995-2026 Mark Adler > * For conditions of distribution and use, see copyright notice in zlib.h > */ > > @@ -63,57 +63,6 @@ int ZEXPORT inflateBackInit_(z_streamp s > return Z_OK; > } > > -/* > - Return state with length and distance decoding tables and index sizes set to > - fixed code decoding. Normally this returns fixed tables from inffixed.h. > - If BUILDFIXED is defined, then instead this routine builds the tables the > - first time it's called, and returns those tables the first time and > - thereafter. This reduces the size of the code by about 2K bytes, in > - exchange for a little execution time. However, BUILDFIXED should not be > - used for threaded applications, since the rewriting of the tables and virgin > - may not be thread-safe. > - */ > -local void fixedtables(struct inflate_state FAR *state) { > -#ifdef BUILDFIXED > - static int virgin = 1; > - static code *lenfix, *distfix; > - static code fixed[544]; > - > - /* build fixed huffman tables if first call (may not be thread safe) */ > - if (virgin) { > - unsigned sym, bits; > - static code *next; > - > - /* literal/length table */ > - sym = 0; > - while (sym < 144) state->lens[sym++] = 8; > - while (sym < 256) state->lens[sym++] = 9; > - while (sym < 280) state->lens[sym++] = 7; > - while (sym < 288) state->lens[sym++] = 8; > - next = fixed; > - lenfix = next; > - bits = 9; > - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); > - > - /* distance table */ > - sym = 0; > - while (sym < 32) state->lens[sym++] = 5; > - distfix = next; > - bits = 5; > - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); > - > - /* do this just once */ > - virgin = 0; > - } > -#else /* !BUILDFIXED */ > -# include "inffixed.h" > -#endif /* BUILDFIXED */ > - state->lencode = lenfix; > - state->lenbits = 9; > - state->distcode = distfix; > - state->distbits = 5; > -} > - > /* Macros for inflateBack(): */ > > /* Load returned state from inflate_fast() */ > @@ -293,7 +242,7 @@ int ZEXPORT inflateBack(z_streamp strm, > state->mode = STORED; > break; > case 1: /* fixed block */ > - fixedtables(state); > + inflate_fixed(state); > Tracev((stderr, "inflate: fixed codes block%s\n", > state->last ? " (last)" : "")); > state->mode = LEN; /* decode codes */ > @@ -303,7 +252,7 @@ int ZEXPORT inflateBack(z_streamp strm, > state->last ? " (last)" : "")); > state->mode = TABLE; > break; > - case 3: > + default: > #ifdef SMALL > strm->msg = (z_const char *)"error"; > #else > @@ -364,7 +313,8 @@ int ZEXPORT inflateBack(z_streamp strm, > #ifdef SMALL > strm->msg = (z_const char *)"error"; > #else > - strm->msg = (z_const char *)"too many length or distance symbols"; > + strm->msg = (z_const char *) > + "too many length or distance symbols"; > #endif > state->mode = BAD; > break; > @@ -417,7 +367,8 @@ int ZEXPORT inflateBack(z_streamp strm, > #ifdef SMALL > strm->msg = (z_const char *)"error"; > #else > - strm->msg = (z_const char *)"invalid bit length repeat"; > + strm->msg = (z_const char *) > + "invalid bit length repeat"; > #endif > state->mode = BAD; > break; > @@ -444,7 +395,8 @@ int ZEXPORT inflateBack(z_streamp strm, > #ifdef SMALL > strm->msg = (z_const char *)"error"; > #else > - strm->msg = (z_const char *)"invalid bit length repeat"; > + strm->msg = (z_const char *) > + "invalid bit length repeat"; > #endif > state->mode = BAD; > break; > @@ -462,7 +414,8 @@ int ZEXPORT inflateBack(z_streamp strm, > #ifdef SMALL > strm->msg = (z_const char *)"error"; > #else > - strm->msg = (z_const char *)"invalid code -- missing end-of-block"; > + strm->msg = (z_const char *) > + "invalid code -- missing end-of-block"; > #endif > state->mode = BAD; > break; > Index: lib/libz/inffast.c > =================================================================== > RCS file: /cvs/src/lib/libz/inffast.c,v > diff -u -p -r1.13 inffast.c > --- lib/libz/inffast.c 30 Jun 2024 05:16:17 -0000 1.13 > +++ lib/libz/inffast.c 10 Mar 2026 06:44:12 -0000 > @@ -1,5 +1,5 @@ > /* inffast.c -- fast decoding > - * Copyright (C) 1995-2017 Mark Adler > + * Copyright (C) 1995-2026 Mark Adler > * For conditions of distribution and use, see copyright notice in zlib.h > */ > > @@ -155,7 +155,8 @@ void ZLIB_INTERNAL inflate_fast(z_stream > dist += (unsigned)hold & ((1U << op) - 1); > #ifdef INFLATE_STRICT > if (dist > dmax) { > - strm->msg = (z_const char *)"invalid distance too far back"; > + strm->msg = (z_const char *) > + "invalid distance too far back"; > state->mode = BAD; > break; > } > @@ -171,8 +172,8 @@ void ZLIB_INTERNAL inflate_fast(z_stream > #ifdef SMALL > strm->msg = (z_const char *)"error"; > #else > - strm->msg = > - (z_const char *)"invalid distance too far back"; > + strm->msg = (z_const char *) > + "invalid distance too far back"; > #endif > state->mode = BAD; > break; > Index: lib/libz/inffixed.h > =================================================================== > RCS file: /cvs/src/lib/libz/inffixed.h,v > diff -u -p -r1.6 inffixed.h > --- lib/libz/inffixed.h 23 Oct 2022 06:00:23 -0000 1.6 > +++ lib/libz/inffixed.h 10 Mar 2026 06:44:12 -0000 > @@ -1,94 +1,94 @@ > - /* inffixed.h -- table for decoding fixed codes > - * Generated automatically by makefixed(). > - */ > +/* inffixed.h -- table for decoding fixed codes > + * Generated automatically by makefixed(). > + */ > > - /* WARNING: this file should *not* be used by applications. > - It is part of the implementation of this library and is > - subject to change. Applications should only use zlib.h. > - */ > +/* WARNING: this file should *not* be used by applications. > + It is part of the implementation of this library and is > + subject to change. Applications should only use zlib.h. > + */ > > - static const code lenfix[512] = { > - {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, > - {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, > - {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, > - {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, > - {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, > - {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, > - {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, > - {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, > - {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, > - {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, > - {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, > - {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, > - {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, > - {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, > - {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, > - {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, > - {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, > - {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, > - {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, > - {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, > - {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, > - {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, > - {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, > - {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, > - {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, > - {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, > - {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, > - {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, > - {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, > - {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, > - {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, > - {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, > - {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, > - {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, > - {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, > - {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, > - {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, > - {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, > - {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, > - {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, > - {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, > - {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, > - {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, > - {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, > - {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, > - {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, > - {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, > - {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, > - {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, > - {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, > - {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, > - {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, > - {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, > - {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, > - {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, > - {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, > - {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, > - {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, > - {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, > - {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, > - {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, > - {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, > - {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, > - {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, > - {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, > - {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, > - {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, > - {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, > - {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, > - {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, > - {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, > - {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, > - {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, > - {0,9,255} > - }; > +static const code lenfix[512] = { > + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, > + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, > + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, > + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, > + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, > + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, > + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, > + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, > + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, > + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, > + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, > + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, > + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, > + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, > + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, > + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, > + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, > + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, > + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, > + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, > + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, > + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, > + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, > + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, > + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, > + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, > + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, > + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, > + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, > + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, > + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, > + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, > + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, > + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, > + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, > + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, > + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, > + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, > + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, > + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, > + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, > + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, > + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, > + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, > + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, > + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, > + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, > + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, > + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, > + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, > + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, > + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, > + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, > + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, > + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, > + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, > + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, > + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, > + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, > + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, > + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, > + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, > + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, > + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, > + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, > + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, > + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, > + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, > + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, > + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, > + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, > + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, > + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, > + {0,9,255} > +}; > > - static const code distfix[32] = { > - {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, > - {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, > - {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, > - {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, > - {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, > - {22,5,193},{64,5,0} > - }; > +static const code distfix[32] = { > + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, > + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, > + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, > + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, > + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, > + {22,5,193},{64,5,0} > +}; > Index: lib/libz/inflate.c > =================================================================== > RCS file: /cvs/src/lib/libz/inflate.c,v > diff -u -p -r1.24 inflate.c > --- lib/libz/inflate.c 7 Mar 2026 09:50:29 -0000 1.24 > +++ lib/libz/inflate.c 10 Mar 2026 06:44:12 -0000 > @@ -1,5 +1,5 @@ > /* inflate.c -- zlib decompression > - * Copyright (C) 1995-2022 Mark Adler > + * Copyright (C) 1995-2026 Mark Adler > * For conditions of distribution and use, see copyright notice in zlib.h > */ > > @@ -85,12 +85,6 @@ > #include "inflate.h" > #include "inffast.h" > > -#ifdef MAKEFIXED > -# ifndef BUILDFIXED > -# define BUILDFIXED > -# endif > -#endif > - > local int inflateStateCheck(z_streamp strm) { > struct inflate_state FAR *state; > if (strm == Z_NULL || > @@ -110,6 +104,7 @@ int ZEXPORT inflateResetKeep(z_streamp s > state = (struct inflate_state FAR *)strm->state; > strm->total_in = strm->total_out = state->total = 0; > strm->msg = Z_NULL; > + strm->data_type = 0; > if (state->wrap) /* to support ill-conceived Java test suite */ > strm->adler = state->wrap & 1; > state->mode = HEAD; > @@ -235,124 +230,12 @@ int ZEXPORT inflatePrime(z_streamp strm, > } > if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR; > value &= (1L << bits) - 1; > - state->hold += (unsigned)value << state->bits; > + state->hold += (unsigned long)value << state->bits; > state->bits += (uInt)bits; > return Z_OK; > } > > /* > - Return state with length and distance decoding tables and index sizes set to > - fixed code decoding. Normally this returns fixed tables from inffixed.h. > - If BUILDFIXED is defined, then instead this routine builds the tables the > - first time it's called, and returns those tables the first time and > - thereafter. This reduces the size of the code by about 2K bytes, in > - exchange for a little execution time. However, BUILDFIXED should not be > - used for threaded applications, since the rewriting of the tables and virgin > - may not be thread-safe. > - */ > -local void fixedtables(struct inflate_state FAR *state) { > -#ifdef BUILDFIXED > - static int virgin = 1; > - static code *lenfix, *distfix; > - static code fixed[544]; > - > - /* build fixed huffman tables if first call (may not be thread safe) */ > - if (virgin) { > - unsigned sym, bits; > - static code *next; > - > - /* literal/length table */ > - sym = 0; > - while (sym < 144) state->lens[sym++] = 8; > - while (sym < 256) state->lens[sym++] = 9; > - while (sym < 280) state->lens[sym++] = 7; > - while (sym < 288) state->lens[sym++] = 8; > - next = fixed; > - lenfix = next; > - bits = 9; > - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); > - > - /* distance table */ > - sym = 0; > - while (sym < 32) state->lens[sym++] = 5; > - distfix = next; > - bits = 5; > - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); > - > - /* do this just once */ > - virgin = 0; > - } > -#else /* !BUILDFIXED */ > -# include "inffixed.h" > -#endif /* BUILDFIXED */ > - state->lencode = lenfix; > - state->lenbits = 9; > - state->distcode = distfix; > - state->distbits = 5; > -} > - > -#ifdef MAKEFIXED > -#include > - > -/* > - Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also > - defines BUILDFIXED, so the tables are built on the fly. makefixed() writes > - those tables to stdout, which would be piped to inffixed.h. A small program > - can simply call makefixed to do this: > - > - void makefixed(void); > - > - int main(void) > - { > - makefixed(); > - return 0; > - } > - > - Then that can be linked with zlib built with MAKEFIXED defined and run: > - > - a.out > inffixed.h > - */ > -void makefixed(void) > -{ > - unsigned low, size; > - struct inflate_state state; > - > - fixedtables(&state); > - puts(" /* inffixed.h -- table for decoding fixed codes"); > - puts(" * Generated automatically by makefixed()."); > - puts(" */"); > - puts(""); > - puts(" /* WARNING: this file should *not* be used by applications."); > - puts(" It is part of the implementation of this library and is"); > - puts(" subject to change. Applications should only use zlib.h."); > - puts(" */"); > - puts(""); > - size = 1U << 9; > - printf(" static const code lenfix[%u] = {", size); > - low = 0; > - for (;;) { > - if ((low % 7) == 0) printf("\n "); > - printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, > - state.lencode[low].bits, state.lencode[low].val); > - if (++low == size) break; > - putchar(','); > - } > - puts("\n };"); > - size = 1U << 5; > - printf("\n static const code distfix[%u] = {", size); > - low = 0; > - for (;;) { > - if ((low % 6) == 0) printf("\n "); > - printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, > - state.distcode[low].val); > - if (++low == size) break; > - putchar(','); > - } > - puts("\n };"); > -} > -#endif /* MAKEFIXED */ > - > -/* > Update the window with the last wsize (normally 32K) bytes written before > returning. If window does not exist yet, create it. This is only called > when a window is already in use, or when output has been written during this > @@ -865,7 +748,7 @@ int ZEXPORT inflate(z_streamp strm, int > state->mode = STORED; > break; > case 1: /* fixed block */ > - fixedtables(state); > + inflate_fixed(state); > Tracev((stderr, "inflate: fixed codes block%s\n", > state->last ? " (last)" : "")); > state->mode = LEN_; /* decode codes */ > @@ -879,7 +762,7 @@ int ZEXPORT inflate(z_streamp strm, int > state->last ? " (last)" : "")); > state->mode = TABLE; > break; > - case 3: > + default: > #ifdef SMALL > strm->msg = (z_const char *)"error"; > #else > @@ -941,7 +824,8 @@ int ZEXPORT inflate(z_streamp strm, int > #ifdef SMALL > strm->msg = (z_const char *)"error"; > #else > - strm->msg = (z_const char *)"too many length or distance symbols"; > + strm->msg = (z_const char *) > + "too many length or distance symbols"; > #endif > state->mode = BAD; > break; > @@ -996,7 +880,8 @@ int ZEXPORT inflate(z_streamp strm, int > #ifdef SMALL > strm->msg = (z_const char *)"error"; > #else > - strm->msg = (z_const char *)"invalid bit length repeat"; > + strm->msg = (z_const char *) > + "invalid bit length repeat"; > #endif > state->mode = BAD; > break; > @@ -1023,7 +908,8 @@ int ZEXPORT inflate(z_streamp strm, int > #ifdef SMALL > strm->msg = (z_const char *)"error"; > #else > - strm->msg = (z_const char *)"invalid bit length repeat"; > + strm->msg = (z_const char *) > + "invalid bit length repeat"; > #endif > state->mode = BAD; > break; > @@ -1041,7 +927,8 @@ int ZEXPORT inflate(z_streamp strm, int > #ifdef SMALL > strm->msg = (z_const char *)"error"; > #else > - strm->msg = (z_const char *)"invalid code -- missing end-of-block"; > + strm->msg = (z_const char *) > + "invalid code -- missing end-of-block"; > #endif > state->mode = BAD; > break; > @@ -1214,7 +1101,8 @@ int ZEXPORT inflate(z_streamp strm, int > #ifdef SMALL > strm->msg = (z_const char *)"error"; > #else > - strm->msg = (z_const char *)"invalid distance too far back"; > + strm->msg = (z_const char *) > + "invalid distance too far back"; > #endif > state->mode = BAD; > break; > @@ -1549,8 +1437,8 @@ int ZEXPORT inflateCopy(z_streamp dest, > } > > /* copy state */ > - zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); > - zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); > + zmemcpy(dest, source, sizeof(z_stream)); > + zmemcpy(copy, state, sizeof(struct inflate_state)); > copy->strm = dest; > if (state->lencode >= state->codes && > state->lencode <= state->codes + ENOUGH - 1) { > Index: lib/libz/inftrees.c > =================================================================== > RCS file: /cvs/src/lib/libz/inftrees.c,v > diff -u -p -r1.17 inftrees.c > --- lib/libz/inftrees.c 23 Jan 2024 14:46:28 -0000 1.17 > +++ lib/libz/inftrees.c 10 Mar 2026 06:44:12 -0000 > @@ -1,10 +1,24 @@ > /* inftrees.c -- generate Huffman trees for efficient decoding > - * Copyright (C) 1995-2024 Mark Adler > + * Copyright (C) 1995-2026 Mark Adler > * For conditions of distribution and use, see copyright notice in zlib.h > */ > > +#ifdef MAKEFIXED > +# ifndef BUILDFIXED > +# define BUILDFIXED > +# endif > +#endif > +#ifdef BUILDFIXED > +# define Z_ONCE > +#endif > + > #include "zutil.h" > #include "inftrees.h" > +#include "inflate.h" > + > +#ifndef NULL > +# define NULL 0 > +#endif > > #define MAXBITS 15 > > @@ -45,9 +59,9 @@ int ZLIB_INTERNAL inflate_table(codetype > unsigned mask; /* mask for low root bits */ > code here; /* table entry for duplication */ > code FAR *next; /* next available space in table */ > - const unsigned short FAR *base; /* base value table to use */ > - const unsigned short FAR *extra; /* extra bits table to use */ > - unsigned match; /* use base and extra for symbol >= match */ > + const unsigned short FAR *base = NULL; /* base value table to use */ > + const unsigned short FAR *extra = NULL; /* extra bits table to use */ > + unsigned match = 0; /* use base and extra for symbol >= match */ > unsigned short count[MAXBITS+1]; /* number of codes of each length */ > unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ > static const unsigned short lbase[31] = { /* Length codes 257..285 base */ > @@ -55,7 +69,7 @@ int ZLIB_INTERNAL inflate_table(codetype > 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; > static const unsigned short lext[31] = { /* Length codes 257..285 extra */ > 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, > - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 73, 200}; > + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 199, 75}; > static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ > 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, > 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, > @@ -173,7 +187,6 @@ int ZLIB_INTERNAL inflate_table(codetype > /* set up for code type */ > switch (type) { > case CODES: > - base = extra = work; /* dummy value--not used */ > match = 20; > break; > case LENS: > @@ -181,10 +194,9 @@ int ZLIB_INTERNAL inflate_table(codetype > extra = lext; > match = 257; > break; > - default: /* DISTS */ > + case DISTS: > base = dbase; > extra = dext; > - match = 0; > } > > /* initialize state for loop */ > @@ -295,3 +307,116 @@ int ZLIB_INTERNAL inflate_table(codetype > *bits = root; > return 0; > } > + > +#ifdef BUILDFIXED > +/* > + If this is compiled with BUILDFIXED defined, and if inflate will be used in > + multiple threads, and if atomics are not available, then inflate() must be > + called with a fixed block (e.g. 0x03 0x00) to initialize the tables and must > + return before any other threads are allowed to call inflate. > + */ > + > +static code *lenfix, *distfix; > +static code fixed[544]; > + > +/* State for z_once(). */ > +local z_once_t built = Z_ONCE_INIT; > + > +local void buildtables(void) { > + unsigned sym, bits; > + static code *next; > + unsigned short lens[288], work[288]; > + > + /* literal/length table */ > + sym = 0; > + while (sym < 144) lens[sym++] = 8; > + while (sym < 256) lens[sym++] = 9; > + while (sym < 280) lens[sym++] = 7; > + while (sym < 288) lens[sym++] = 8; > + next = fixed; > + lenfix = next; > + bits = 9; > + inflate_table(LENS, lens, 288, &(next), &(bits), work); > + > + /* distance table */ > + sym = 0; > + while (sym < 32) lens[sym++] = 5; > + distfix = next; > + bits = 5; > + inflate_table(DISTS, lens, 32, &(next), &(bits), work); > +} > +#else /* !BUILDFIXED */ > +# include "inffixed.h" > +#endif /* BUILDFIXED */ > + > +/* > + Return state with length and distance decoding tables and index sizes set to > + fixed code decoding. Normally this returns fixed tables from inffixed.h. > + If BUILDFIXED is defined, then instead this routine builds the tables the > + first time it's called, and returns those tables the first time and > + thereafter. This reduces the size of the code by about 2K bytes, in > + exchange for a little execution time. However, BUILDFIXED should not be > + used for threaded applications if atomics are not available, as it will > + not be thread-safe. > + */ > +void inflate_fixed(struct inflate_state FAR *state) { > +#ifdef BUILDFIXED > + z_once(&built, buildtables); > +#endif /* BUILDFIXED */ > + state->lencode = lenfix; > + state->lenbits = 9; > + state->distcode = distfix; > + state->distbits = 5; > +} > + > +#ifdef MAKEFIXED > +#include > + > +/* > + Write out the inffixed.h that will be #include'd above. Defining MAKEFIXED > + also defines BUILDFIXED, so the tables are built on the fly. main() writes > + those tables to stdout, which would directed to inffixed.h. Compile this > + along with zutil.c: > + > + cc -DMAKEFIXED -o fix inftrees.c zutil.c > + ./fix > inffixed.h > + */ > +int main(void) { > + unsigned low, size; > + struct inflate_state state; > + > + inflate_fixed(&state); > + puts("/* inffixed.h -- table for decoding fixed codes"); > + puts(" * Generated automatically by makefixed()."); > + puts(" */"); > + puts(""); > + puts("/* WARNING: this file should *not* be used by applications."); > + puts(" It is part of the implementation of this library and is"); > + puts(" subject to change. Applications should only use zlib.h."); > + puts(" */"); > + puts(""); > + size = 1U << 9; > + printf("static const code lenfix[%u] = {", size); > + low = 0; > + for (;;) { > + if ((low % 7) == 0) printf("\n "); > + printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, > + state.lencode[low].bits, state.lencode[low].val); > + if (++low == size) break; > + putchar(','); > + } > + puts("\n};"); > + size = 1U << 5; > + printf("\nstatic const code distfix[%u] = {", size); > + low = 0; > + for (;;) { > + if ((low % 6) == 0) printf("\n "); > + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, > + state.distcode[low].val); > + if (++low == size) break; > + putchar(','); > + } > + puts("\n};"); > + return 0; > +} > +#endif /* MAKEFIXED */ > Index: lib/libz/inftrees.h > =================================================================== > RCS file: /cvs/src/lib/libz/inftrees.h,v > diff -u -p -r1.11 inftrees.h > --- lib/libz/inftrees.h 18 Nov 2023 22:43:25 -0000 1.11 > +++ lib/libz/inftrees.h 10 Mar 2026 06:44:12 -0000 > @@ -1,5 +1,5 @@ > /* inftrees.h -- header to use inftrees.c > - * Copyright (C) 1995-2005, 2010 Mark Adler > + * Copyright (C) 1995-2026 Mark Adler > * For conditions of distribution and use, see copyright notice in zlib.h > */ > > @@ -60,3 +60,5 @@ typedef enum { > int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, > unsigned codes, code FAR * FAR *table, > unsigned FAR *bits, unsigned short FAR *work); > +struct inflate_state; > +void ZLIB_INTERNAL inflate_fixed(struct inflate_state FAR *state); > Index: lib/libz/shlib_version > =================================================================== > RCS file: /cvs/src/lib/libz/shlib_version,v > diff -u -p -r1.14 shlib_version > --- lib/libz/shlib_version 2 Aug 2024 04:59:55 -0000 1.14 > +++ lib/libz/shlib_version 11 Mar 2026 05:40:45 -0000 > @@ -1,2 +1,2 @@ > major=7 > -minor=1 > +minor=2 > Index: lib/libz/trees.c > =================================================================== > RCS file: /cvs/src/lib/libz/trees.c,v > diff -u -p -r1.19 trees.c > --- lib/libz/trees.c 1 Aug 2024 04:02:26 -0000 1.19 > +++ lib/libz/trees.c 10 Mar 2026 06:44:13 -0000 > @@ -1,5 +1,5 @@ > /* trees.c -- output deflated data using Huffman coding > - * Copyright (C) 1995-2024 Jean-loup Gailly > + * Copyright (C) 1995-2026 Jean-loup Gailly > * detect_data_type() function provided freely by Cosmin Truta, 2006 > * For conditions of distribution and use, see copyright notice in zlib.h > */ > @@ -110,7 +110,7 @@ local int base_dist[D_CODES]; > > #else > # include "trees.h" > -#endif /* GEN_TREES_H */ > +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ > > struct static_tree_desc_s { > const ct_data *static_tree; /* static tree or NULL */ > @@ -150,7 +150,7 @@ local TCONST static_tree_desc static_bl_ > * IN assertion: 1 <= len <= 15 > */ > local unsigned bi_reverse(unsigned code, int len) { > - register unsigned res = 0; > + unsigned res = 0; > do { > res |= code & 1; > code >>= 1, res <<= 1; > @@ -186,7 +186,7 @@ local void bi_windup(deflate_state *s) { > s->bi_buf = 0; > s->bi_valid = 0; > #ifdef ZLIB_DEBUG > - s->bits_sent = (s->bits_sent + 7) & ~7; > + s->bits_sent = (s->bits_sent + 7) & ~(ulg)7; > #endif > } > > @@ -817,7 +817,7 @@ local int build_bl_tree(deflate_state *s > } > /* Update opt_len to include the bit length tree and counts */ > s->opt_len += 3*((ulg)max_blindex + 1) + 5 + 5 + 4; > - Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", > + Tracev((stderr, "\ndyn trees: dyn %lu, stat %lu", > s->opt_len, s->static_len)); > > return max_blindex; > @@ -843,13 +843,13 @@ local void send_all_trees(deflate_state > Tracev((stderr, "\nbl code %2d ", bl_order[rank])); > send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); > } > - Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); > + Tracev((stderr, "\nbl tree: sent %lu", s->bits_sent)); > > send_tree(s, (ct_data *)s->dyn_ltree, lcodes - 1); /* literal tree */ > - Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); > + Tracev((stderr, "\nlit tree: sent %lu", s->bits_sent)); > > send_tree(s, (ct_data *)s->dyn_dtree, dcodes - 1); /* distance tree */ > - Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); > + Tracev((stderr, "\ndist tree: sent %lu", s->bits_sent)); > } > > /* =========================================================================== > @@ -932,7 +932,7 @@ local void compress_block(deflate_state > extra = extra_dbits[code]; > if (extra != 0) { > dist -= (unsigned)base_dist[code]; > - send_bits(s, dist, extra); /* send the extra distance bits */ > + send_bits(s, (int)dist, extra); /* send the extra bits */ > } > } /* literal or match pair ? */ > > @@ -1006,11 +1006,11 @@ void ZLIB_INTERNAL _tr_flush_block(defla > > /* Construct the literal and distance trees */ > build_tree(s, (tree_desc *)(&(s->l_desc))); > - Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, > + Tracev((stderr, "\nlit data: dyn %lu, stat %lu", s->opt_len, > s->static_len)); > > build_tree(s, (tree_desc *)(&(s->d_desc))); > - Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, > + Tracev((stderr, "\ndist data: dyn %lu, stat %lu", s->opt_len, > s->static_len)); > /* At this point, opt_len and static_len are the total bit lengths of > * the compressed block data, excluding the tree representations. > @@ -1083,7 +1083,7 @@ void ZLIB_INTERNAL _tr_flush_block(defla > #endif > } > Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len >> 3, > - s->compressed_len - 7*last)); > + s->compressed_len - 7*(ulg)last)); > } > > /* =========================================================================== > Index: lib/libz/uncompr.c > =================================================================== > RCS file: /cvs/src/lib/libz/uncompr.c,v > diff -u -p -r1.9 uncompr.c > --- lib/libz/uncompr.c 25 Apr 2023 16:59:10 -0000 1.9 > +++ lib/libz/uncompr.c 10 Mar 2026 06:44:13 -0000 > @@ -1,5 +1,5 @@ > /* uncompr.c -- decompress a memory buffer > - * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler > + * Copyright (C) 1995-2026 Jean-loup Gailly, Mark Adler > * For conditions of distribution and use, see copyright notice in zlib.h > */ > > @@ -21,24 +21,24 @@ > memory, Z_BUF_ERROR if there was not enough room in the output buffer, or > Z_DATA_ERROR if the input data was corrupted, including if the input data is > an incomplete zlib stream. > + > + The _z versions of the functions take size_t length arguments. > */ > -int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source, > - uLong *sourceLen) { > +int ZEXPORT uncompress2_z(Bytef *dest, z_size_t *destLen, const Bytef *source, > + z_size_t *sourceLen) { > z_stream stream; > int err; > const uInt max = (uInt)-1; > - uLong len, left; > - Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */ > + z_size_t len, left; > + > + if (sourceLen == NULL || (*sourceLen > 0 && source == NULL) || > + destLen == NULL || (*destLen > 0 && dest == NULL)) > + return Z_STREAM_ERROR; > > len = *sourceLen; > - if (*destLen) { > - left = *destLen; > - *destLen = 0; > - } > - else { > - left = 1; > - dest = buf; > - } > + left = *destLen; > + if (left == 0 && dest == Z_NULL) > + dest = (Bytef *)&stream.reserved; /* next_out cannot be NULL */ > > stream.next_in = (z_const Bytef *)source; > stream.avail_in = 0; > @@ -54,30 +54,46 @@ int ZEXPORT uncompress2(Bytef *dest, uLo > > do { > if (stream.avail_out == 0) { > - stream.avail_out = left > (uLong)max ? max : (uInt)left; > + stream.avail_out = left > (z_size_t)max ? max : (uInt)left; > left -= stream.avail_out; > } > if (stream.avail_in == 0) { > - stream.avail_in = len > (uLong)max ? max : (uInt)len; > + stream.avail_in = len > (z_size_t)max ? max : (uInt)len; > len -= stream.avail_in; > } > err = inflate(&stream, Z_NO_FLUSH); > } while (err == Z_OK); > > - *sourceLen -= len + stream.avail_in; > - if (dest != buf) > - *destLen = stream.total_out; > - else if (stream.total_out && err == Z_BUF_ERROR) > - left = 1; > + /* Set len and left to the unused input data and unused output space. Set > + *sourceLen to the amount of input consumed. Set *destLen to the amount > + of data produced. */ > + len += stream.avail_in; > + left += stream.avail_out; > + *sourceLen -= len; > + *destLen -= left; > > inflateEnd(&stream); > return err == Z_STREAM_END ? Z_OK : > err == Z_NEED_DICT ? Z_DATA_ERROR : > - err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR : > + err == Z_BUF_ERROR && len == 0 ? Z_DATA_ERROR : > err; > } > - > +int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source, > + uLong *sourceLen) { > + int ret; > + z_size_t got = *destLen, used = *sourceLen; > + ret = uncompress2_z(dest, &got, source, &used); > + *sourceLen = (uLong)used; > + *destLen = (uLong)got; > + return ret; > +} > +int ZEXPORT uncompress_z(Bytef *dest, z_size_t *destLen, const Bytef *source, > + z_size_t sourceLen) { > + z_size_t used = sourceLen; > + return uncompress2_z(dest, destLen, source, &used); > +} > int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, > uLong sourceLen) { > - return uncompress2(dest, destLen, source, &sourceLen); > + uLong used = sourceLen; > + return uncompress2(dest, destLen, source, &used); > } > Index: lib/libz/zconf.h > =================================================================== > RCS file: /cvs/src/lib/libz/zconf.h,v > diff -u -p -r1.22 zconf.h > --- lib/libz/zconf.h 9 Nov 2024 21:51:37 -0000 1.22 > +++ lib/libz/zconf.h 10 Mar 2026 06:44:13 -0000 > @@ -1,5 +1,5 @@ > /* zconf.h -- configuration of the zlib compression library > - * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler > + * Copyright (C) 1995-2026 Jean-loup Gailly, Mark Adler > * For conditions of distribution and use, see copyright notice in zlib.h > */ > > @@ -31,7 +31,10 @@ > # ifndef Z_SOLO > # define compress z_compress > # define compress2 z_compress2 > +# define compress_z z_compress_z > +# define compress2_z z_compress2_z > # define compressBound z_compressBound > +# define compressBound_z z_compressBound_z > # endif > # define crc32 z_crc32 > # define crc32_combine z_crc32_combine > @@ -42,6 +45,7 @@ > # define crc32_z z_crc32_z > # define deflate z_deflate > # define deflateBound z_deflateBound > +# define deflateBound_z z_deflateBound_z > # define deflateCopy z_deflateCopy > # define deflateEnd z_deflateEnd > # define deflateGetDictionary z_deflateGetDictionary > @@ -127,9 +131,12 @@ > # define inflate_copyright z_inflate_copyright > # define inflate_fast z_inflate_fast > # define inflate_table z_inflate_table > +# define inflate_fixed z_inflate_fixed > # ifndef Z_SOLO > # define uncompress z_uncompress > # define uncompress2 z_uncompress2 > +# define uncompress_z z_uncompress_z > +# define uncompress2_z z_uncompress2_z > # endif > # define zError z_zError > # ifndef Z_SOLO > Index: lib/libz/zlib.h > =================================================================== > RCS file: /cvs/src/lib/libz/zlib.h,v > diff -u -p -r1.31 zlib.h > --- lib/libz/zlib.h 4 Mar 2026 05:44:14 -0000 1.31 > +++ lib/libz/zlib.h 10 Mar 2026 06:44:13 -0000 > @@ -1,7 +1,7 @@ > /* zlib.h -- interface of the 'zlib' general purpose compression library > - version 1.3.1.1, January xxth, 2024 > + version 1.3.2, February 17th, 2026 > > - Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler > + Copyright (C) 1995-2026 Jean-loup Gailly and Mark Adler > > This software is provided 'as-is', without any express or implied > warranty. In no event will the authors be held liable for any damages > @@ -24,7 +24,7 @@ > > > The data format used by the zlib library is described by RFCs (Request for > - Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 > + Comments) 1950 to 1952 at https://datatracker.ietf.org/doc/html/rfc1950 > (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). > */ > > @@ -41,12 +41,12 @@ > extern "C" { > #endif > > -#define ZLIB_VERSION "1.3.1.1-motley" > -#define ZLIB_VERNUM 0x1311 > +#define ZLIB_VERSION "1.3.2" > +#define ZLIB_VERNUM 0x1320 > #define ZLIB_VER_MAJOR 1 > #define ZLIB_VER_MINOR 3 > -#define ZLIB_VER_REVISION 1 > -#define ZLIB_VER_SUBREVISION 1 > +#define ZLIB_VER_REVISION 2 > +#define ZLIB_VER_SUBREVISION 0 > > /* > The 'zlib' compression library provides in-memory compression and > @@ -445,7 +445,7 @@ ZEXTERN int ZEXPORT inflate(z_streamp st > > The Z_BLOCK option assists in appending to or combining deflate streams. > To assist in this, on return inflate() always sets strm->data_type to the > - number of unused bits in the last byte taken from strm->next_in, plus 64 if > + number of unused bits in the input taken from strm->next_in, plus 64 if > inflate() is currently decoding the last block in the deflate stream, plus > 128 if inflate() returned immediately after decoding an end-of-block code or > decoding the complete header up to just before the first byte of the deflate > @@ -765,8 +765,8 @@ ZEXTERN int ZEXPORT deflateTune(z_stream > returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. > */ > > -ZEXTERN uLong ZEXPORT deflateBound(z_streamp strm, > - uLong sourceLen); > +ZEXTERN uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen); > +ZEXTERN z_size_t ZEXPORT deflateBound_z(z_streamp strm, z_size_t sourceLen); > /* > deflateBound() returns an upper bound on the compressed size after > deflation of sourceLen bytes. It must be called after deflateInit() or > @@ -778,6 +778,9 @@ ZEXTERN uLong ZEXPORT deflateBound(z_str > to return Z_STREAM_END. Note that it is possible for the compressed size to > be larger than the value returned by deflateBound() if flush options other > than Z_FINISH or Z_NO_FLUSH are used. > + > + delfateBound_z() is the same, but takes and returns a size_t length. Note > + that a long is 32 bits on Windows. > */ > > ZEXTERN int ZEXPORT deflatePending(z_streamp strm, > @@ -792,7 +795,10 @@ ZEXTERN int ZEXPORT deflatePending(z_str > or bits are Z_NULL, then those values are not set. > > deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source > - stream state was inconsistent. > + stream state was inconsistent. If an int is 16 bits and memLevel is 9, then > + it is possible for the number of pending bytes to not fit in an unsigned. In > + that case Z_BUF_ERROR is returned and *pending is set to the maximum value > + of an unsigned. > */ > > ZEXTERN int ZEXPORT deflateUsed(z_streamp strm, > @@ -1006,13 +1012,15 @@ ZEXTERN int ZEXPORT inflatePrime(z_strea > int bits, > int value); > /* > - This function inserts bits in the inflate input stream. The intent is > - that this function is used to start inflating at a bit position in the > - middle of a byte. The provided bits will be used before any bytes are used > - from next_in. This function should only be used with raw inflate, and > - should be used before the first inflate() call after inflateInit2() or > - inflateReset(). bits must be less than or equal to 16, and that many of the > - least significant bits of value will be inserted in the input. > + This function inserts bits in the inflate input stream. The intent is to > + use inflatePrime() to start inflating at a bit position in the middle of a > + byte. The provided bits will be used before any bytes are used from > + next_in. This function should be used with raw inflate, before the first > + inflate() call, after inflateInit2() or inflateReset(). It can also be used > + after an inflate() return indicates the end of a deflate block or header > + when using Z_BLOCK. bits must be less than or equal to 16, and that many of > + the least significant bits of value will be inserted in the input. The > + other bits in value can be non-zero, and will be ignored. > > If bits is negative, then the input stream bit buffer is emptied. Then > inflatePrime() can be called again to put bits in the buffer. This is used > @@ -1020,7 +1028,15 @@ ZEXTERN int ZEXPORT inflatePrime(z_strea > to feeding inflate codes. > > inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source > - stream state was inconsistent. > + stream state was inconsistent, or if bits is out of range. If inflate was > + in the middle of processing a header, trailer, or stored block lengths, then > + it is possible for there to be only eight bits available in the bit buffer. > + In that case, bits > 8 is considered out of range. However, when used as > + outlined above, there will always be 16 bits available in the buffer for > + insertion. As noted in its documentation above, inflate records the number > + of bits in the bit buffer on return in data_type. 32 minus that is the > + number of bits available for insertion. inflatePrime does not update > + data_type with the new number of bits in buffer. > */ > > ZEXTERN long ZEXPORT inflateMark(z_streamp strm); > @@ -1066,20 +1082,22 @@ ZEXTERN int ZEXPORT inflateGetHeader(z_s > > The text, time, xflags, and os fields are filled in with the gzip header > contents. hcrc is set to true if there is a header CRC. (The header CRC > - was valid if done is set to one.) If extra is not Z_NULL, then extra_max > - contains the maximum number of bytes to write to extra. Once done is true, > - extra_len contains the actual extra field length, and extra contains the > - extra field, or that field truncated if extra_max is less than extra_len. > - If name is not Z_NULL, then up to name_max characters are written there, > - terminated with a zero unless the length is greater than name_max. If > - comment is not Z_NULL, then up to comm_max characters are written there, > - terminated with a zero unless the length is greater than comm_max. When any > - of extra, name, or comment are not Z_NULL and the respective field is not > - present in the header, then that field is set to Z_NULL to signal its > - absence. This allows the use of deflateSetHeader() with the returned > - structure to duplicate the header. However if those fields are set to > - allocated memory, then the application will need to save those pointers > - elsewhere so that they can be eventually freed. > + was valid if done is set to one.) The extra, name, and comment pointers > + much each be either Z_NULL or point to space to store that information from > + the header. If extra is not Z_NULL, then extra_max contains the maximum > + number of bytes that can be written to extra. Once done is true, extra_len > + contains the actual extra field length, and extra contains the extra field, > + or that field truncated if extra_max is less than extra_len. If name is not > + Z_NULL, then up to name_max characters, including the terminating zero, are > + written there. If comment is not Z_NULL, then up to comm_max characters, > + including the terminating zero, are written there. The application can tell > + that the name or comment did not fit in the provided space by the absence of > + a terminating zero. If any of extra, name, or comment are not present in > + the header, then that field's pointer is set to Z_NULL. This allows the use > + of deflateSetHeader() with the returned structure to duplicate the header. > + Note that if those fields initially pointed to allocated memory, then the > + application will need to save them elsewhere so that they can be eventually > + freed. > > If inflateGetHeader is not used, then the header information is simply > discarded. The header is always checked for validity, including the header > @@ -1227,13 +1245,14 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags(v > 21: FASTEST -- deflate algorithm with only one, lowest compression level > 22,23: 0 (reserved) > > - The sprintf variant used by gzprintf (zero is best): > + The sprintf variant used by gzprintf (all zeros is best): > 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format > - 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! > + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() is not secure! > 26: 0 = returns value, 1 = void -- 1 means inferred string length returned > + 27: 0 = gzprintf() present, 1 = not -- 1 means gzprintf() returns an error > > Remainder: > - 27-31: 0 (reserved) > + 28-31: 0 (reserved) > */ > > #ifndef Z_SOLO > @@ -1245,11 +1264,14 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags(v > stream-oriented functions. To simplify the interface, some default options > are assumed (compression level and memory usage, standard memory allocation > functions). The source code of these utility functions can be modified if > - you need special options. > + you need special options. The _z versions of the functions use the size_t > + type for lengths. Note that a long is 32 bits on Windows. > */ > > -ZEXTERN int ZEXPORT compress(Bytef *dest, uLongf *destLen, > +ZEXTERN int ZEXPORT compress(Bytef *dest, uLongf *destLen, > const Bytef *source, uLong sourceLen); > +ZEXTERN int ZEXPORT compress_z(Bytef *dest, z_size_t *destLen, > + const Bytef *source, z_size_t sourceLen); > /* > Compresses the source buffer into the destination buffer. sourceLen is > the byte length of the source buffer. Upon entry, destLen is the total size > @@ -1263,9 +1285,12 @@ ZEXTERN int ZEXPORT compress(Bytef *dest > buffer. > */ > > -ZEXTERN int ZEXPORT compress2(Bytef *dest, uLongf *destLen, > +ZEXTERN int ZEXPORT compress2(Bytef *dest, uLongf *destLen, > const Bytef *source, uLong sourceLen, > int level); > +ZEXTERN int ZEXPORT compress2_z(Bytef *dest, z_size_t *destLen, > + const Bytef *source, z_size_t sourceLen, > + int level); > /* > Compresses the source buffer into the destination buffer. The level > parameter has the same meaning as in deflateInit. sourceLen is the byte > @@ -1280,21 +1305,24 @@ ZEXTERN int ZEXPORT compress2(Bytef *des > */ > > ZEXTERN uLong ZEXPORT compressBound(uLong sourceLen); > +ZEXTERN z_size_t ZEXPORT compressBound_z(z_size_t sourceLen); > /* > compressBound() returns an upper bound on the compressed size after > compress() or compress2() on sourceLen bytes. It would be used before a > compress() or compress2() call to allocate the destination buffer. > */ > > -ZEXTERN int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, > +ZEXTERN int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, > const Bytef *source, uLong sourceLen); > +ZEXTERN int ZEXPORT uncompress_z(Bytef *dest, z_size_t *destLen, > + const Bytef *source, z_size_t sourceLen); > /* > Decompresses the source buffer into the destination buffer. sourceLen is > - the byte length of the source buffer. Upon entry, destLen is the total size > + the byte length of the source buffer. On entry, *destLen is the total size > of the destination buffer, which must be large enough to hold the entire > uncompressed data. (The size of the uncompressed data must have been saved > previously by the compressor and transmitted to the decompressor by some > - mechanism outside the scope of this compression library.) Upon exit, destLen > + mechanism outside the scope of this compression library.) On exit, *destLen > is the actual size of the uncompressed data. > > uncompress returns Z_OK if success, Z_MEM_ERROR if there was not > @@ -1304,8 +1332,10 @@ ZEXTERN int ZEXPORT uncompress(Bytef *de > buffer with the uncompressed data up to that point. > */ > > -ZEXTERN int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, > +ZEXTERN int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, > const Bytef *source, uLong *sourceLen); > +ZEXTERN int ZEXPORT uncompress2_z(Bytef *dest, z_size_t *destLen, > + const Bytef *source, z_size_t *sourceLen); > /* > Same as uncompress, except that sourceLen is a pointer, where the > length of the source is *sourceLen. On return, *sourceLen is the number of > @@ -1333,13 +1363,17 @@ ZEXTERN gzFile ZEXPORT gzopen(const char > 'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression > as in "wb9F". (See the description of deflateInit2 for more information > about the strategy parameter.) 'T' will request transparent writing or > - appending with no compression and not using the gzip format. > + appending with no compression and not using the gzip format. 'T' cannot be > + used to force transparent reading. Transparent reading is automatically > + performed if there is no gzip header at the start. Transparent reading can > + be disabled with the 'G' option, which will instead return an error if there > + is no gzip header. 'N' will open the file in non-blocking mode. > > - "a" can be used instead of "w" to request that the gzip stream that will > - be written be appended to the file. "+" will result in an error, since > + 'a' can be used instead of 'w' to request that the gzip stream that will > + be written be appended to the file. '+' will result in an error, since > reading and writing to the same gzip file is not supported. The addition of > - "x" when writing will create the file exclusively, which fails if the file > - already exists. On systems that support it, the addition of "e" when > + 'x' when writing will create the file exclusively, which fails if the file > + already exists. On systems that support it, the addition of 'e' when > reading or writing will set the flag to close the file on an execve() call. > > These functions, as well as gzip, will read and decode a sequence of gzip > @@ -1358,14 +1392,22 @@ ZEXTERN gzFile ZEXPORT gzopen(const char > insufficient memory to allocate the gzFile state, or if an invalid mode was > specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). > errno can be checked to determine if the reason gzopen failed was that the > - file could not be opened. > + file could not be opened. Note that if 'N' is in mode for non-blocking, the > + open() itself can fail in order to not block. In that case gzopen() will > + return NULL and errno will be EAGAIN or ENONBLOCK. The call to gzopen() can > + then be re-tried. If the application would like to block on opening the > + file, then it can use open() without O_NONBLOCK, and then gzdopen() with the > + resulting file descriptor and 'N' in the mode, which will set it to non- > + blocking. > */ > > ZEXTERN gzFile ZEXPORT gzdopen(int fd, const char *mode); > /* > Associate a gzFile with the file descriptor fd. File descriptors are > obtained from calls like open, dup, creat, pipe or fileno (if the file has > - been previously opened with fopen). The mode parameter is as in gzopen. > + been previously opened with fopen). The mode parameter is as in gzopen. An > + 'e' in mode will set fd's flag to close the file on an execve() call. An 'N' > + in mode will set fd's non-blocking flag. > > The next call of gzclose on the returned gzFile will also close the file > descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor > @@ -1435,10 +1477,16 @@ ZEXTERN int ZEXPORT gzread(gzFile file, > stream. Alternatively, gzerror can be used before gzclose to detect this > case. > > + gzread can be used to read a gzip file on a non-blocking device. If the > + input stalls and there is no uncompressed data to return, then gzread() will > + return -1, and errno will be EAGAIN or EWOULDBLOCK. gzread() can then be > + called again. > + > gzread returns the number of uncompressed bytes actually read, less than > len for end of file, or -1 for error. If len is too large to fit in an int, > then nothing is read, -1 is returned, and the error state is set to > - Z_STREAM_ERROR. > + Z_STREAM_ERROR. If some data was read before an error, then that data is > + returned until exhausted, after which the next call will signal the error. > */ > > ZEXTERN z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, > @@ -1462,15 +1510,20 @@ ZEXTERN z_size_t ZEXPORT gzfread(voidp b > multiple of size, then the final partial item is nevertheless read into buf > and the end-of-file flag is set. The length of the partial item read is not > provided, but could be inferred from the result of gztell(). This behavior > - is the same as the behavior of fread() implementations in common libraries, > - but it prevents the direct use of gzfread() to read a concurrently written > - file, resetting and retrying on end-of-file, when size is not 1. > + is the same as that of fread() implementations in common libraries. This > + could result in data loss if used with size != 1 when reading a concurrently > + written file or a non-blocking file. In that case, use size == 1 or gzread() > + instead. > */ > > ZEXTERN int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len); > /* > Compress and write the len uncompressed bytes at buf to file. gzwrite > - returns the number of uncompressed bytes written or 0 in case of error. > + returns the number of uncompressed bytes written, or 0 in case of error or > + if len is 0. If the write destination is non-blocking, then gzwrite() may > + return a number of bytes written that is not 0 and less than len. > + > + If len does not fit in an int, then 0 is returned and nothing is written. > */ > > ZEXTERN z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, > @@ -1485,9 +1538,18 @@ ZEXTERN z_size_t ZEXPORT gzfwrite(voidpc > if there was an error. If the multiplication of size and nitems overflows, > i.e. the product does not fit in a z_size_t, then nothing is written, zero > is returned, and the error state is set to Z_STREAM_ERROR. > + > + If writing a concurrently read file or a non-blocking file with size != 1, > + a partial item could be written, with no way of knowing how much of it was > + not written, resulting in data loss. In that case, use size == 1 or > + gzwrite() instead. > */ > > +#if defined(STDC) || defined(Z_HAVE_STDARG_H) > ZEXTERN int ZEXPORTVA gzprintf(gzFile file, const char *format, ...); > +#else > +ZEXTERN int ZEXPORTVA gzprintf(); > +#endif > /* > Convert, format, compress, and write the arguments (...) to file under > control of the string format, as in fprintf. gzprintf returns the number of > @@ -1495,11 +1557,19 @@ ZEXTERN int ZEXPORTVA gzprintf(gzFile fi > of error. The number of uncompressed bytes written is limited to 8191, or > one less than the buffer size given to gzbuffer(). The caller should assure > that this limit is not exceeded. If it is exceeded, then gzprintf() will > - return an error (0) with nothing written. In this case, there may also be a > - buffer overflow with unpredictable consequences, which is possible only if > - zlib was compiled with the insecure functions sprintf() or vsprintf(), > - because the secure snprintf() or vsnprintf() functions were not available. > - This can be determined using zlibCompileFlags(). > + return an error (0) with nothing written. > + > + In that last case, there may also be a buffer overflow with unpredictable > + consequences, which is possible only if zlib was compiled with the insecure > + functions sprintf() or vsprintf(), because the secure snprintf() and > + vsnprintf() functions were not available. That would only be the case for > + a non-ANSI C compiler. zlib may have been built without gzprintf() because > + secure functions were not available and having gzprintf() be insecure was > + not an option, in which case, gzprintf() returns Z_STREAM_ERROR. All of > + these possibilities can be determined using zlibCompileFlags(). > + > + If a Z_BUF_ERROR is returned, then nothing was written due to a stall on > + the non-blocking write destination. > */ > > ZEXTERN int ZEXPORT gzputs(gzFile file, const char *s); > @@ -1508,6 +1578,11 @@ ZEXTERN int ZEXPORT gzputs(gzFile file, > the terminating null character. > > gzputs returns the number of characters written, or -1 in case of error. > + The number of characters written may be less than the length of the string > + if the write destination is non-blocking. > + > + If the length of the string does not fit in an int, then -1 is returned > + and nothing is written. > */ > > ZEXTERN char * ZEXPORT gzgets(gzFile file, char *buf, int len); > @@ -1520,8 +1595,13 @@ ZEXTERN char * ZEXPORT gzgets(gzFile fil > left untouched. > > gzgets returns buf which is a null-terminated string, or it returns NULL > - for end-of-file or in case of error. If there was an error, the contents at > - buf are indeterminate. > + for end-of-file or in case of error. If some data was read before an error, > + then that data is returned until exhausted, after which the next call will > + return NULL to signal the error. > + > + gzgets can be used on a file being concurrently written, and on a non- > + blocking device, both as for gzread(). However lines may be broken in the > + middle, leaving it up to the application to reassemble them as needed. > */ > > ZEXTERN int ZEXPORT gzputc(gzFile file, int c); > @@ -1532,11 +1612,19 @@ ZEXTERN int ZEXPORT gzputc(gzFile file, > > ZEXTERN int ZEXPORT gzgetc(gzFile file); > /* > - Read and decompress one byte from file. gzgetc returns this byte or -1 > - in case of end of file or error. This is implemented as a macro for speed. > - As such, it does not do all of the checking the other functions do. I.e. > - it does not check to see if file is NULL, nor whether the structure file > - points to has been clobbered or not. > + Read and decompress one byte from file. gzgetc returns this byte or -1 in > + case of end of file or error. If some data was read before an error, then > + that data is returned until exhausted, after which the next call will return > + -1 to signal the error. > + > + This is implemented as a macro for speed. As such, it does not do all of > + the checking the other functions do. I.e. it does not check to see if file > + is NULL, nor whether the structure file points to has been clobbered or not. > + > + gzgetc can be used to read a gzip file on a non-blocking device. If the > + input stalls and there is no uncompressed data to return, then gzgetc() will > + return -1, and errno will be EAGAIN or EWOULDBLOCK. gzread() can then be > + called again. > */ > > ZEXTERN int ZEXPORT gzungetc(int c, gzFile file); > @@ -1549,6 +1637,11 @@ ZEXTERN int ZEXPORT gzungetc(int c, gzFi > output buffer size of pushed characters is allowed. (See gzbuffer above.) > The pushed character will be discarded if the stream is repositioned with > gzseek() or gzrewind(). > + > + gzungetc(-1, file) will force any pending seek to execute. Then gztell() > + will report the position, even if the requested seek reached end of file. > + This can be used to determine the number of uncompressed bytes in a gzip > + file without having to read it into a buffer. > */ > > ZEXTERN int ZEXPORT gzflush(gzFile file, int flush); > @@ -1578,7 +1671,8 @@ ZEXTERN z_off_t ZEXPORT gzseek(gzFile fi > If the file is opened for reading, this function is emulated but can be > extremely slow. If the file is opened for writing, only forward seeks are > supported; gzseek then compresses a sequence of zeroes up to the new > - starting position. > + starting position. For reading or writing, any actual seeking is deferred > + until the next read or write operation, or close operation when writing. > > gzseek returns the resulting offset location as measured in bytes from > the beginning of the uncompressed stream, or -1 in case of error, in > @@ -1586,7 +1680,7 @@ ZEXTERN z_off_t ZEXPORT gzseek(gzFile fi > would be before the current position. > */ > > -ZEXTERN int ZEXPORT gzrewind(gzFile file); > +ZEXTERN int ZEXPORT gzrewind(gzFile file); > /* > Rewind file. This function is supported only for reading. > > @@ -1594,7 +1688,7 @@ ZEXTERN int ZEXPORT gzrewind(gzFile f > */ > > /* > -ZEXTERN z_off_t ZEXPORT gztell(gzFile file); > +ZEXTERN z_off_t ZEXPORT gztell(gzFile file); > > Return the starting position for the next gzread or gzwrite on file. > This position represents a number of bytes in the uncompressed data stream, > @@ -1639,8 +1733,11 @@ ZEXTERN int ZEXPORT gzdirect(gzFile file > > If gzdirect() is used immediately after gzopen() or gzdopen() it will > cause buffers to be allocated to allow reading the file to determine if it > - is a gzip file. Therefore if gzbuffer() is used, it should be called before > - gzdirect(). > + is a gzip file. Therefore if gzbuffer() is used, it should be called before > + gzdirect(). If the input is being written concurrently or the device is non- > + blocking, then gzdirect() may give a different answer once four bytes of > + input have been accumulated, which is what is needed to confirm or deny a > + gzip header. Before this, gzdirect() will return true (1). > > When writing, gzdirect() returns true (1) if transparent writing was > requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: > @@ -1650,7 +1747,7 @@ ZEXTERN int ZEXPORT gzdirect(gzFile file > gzip file reading and decompression, which may not be desired.) > */ > > -ZEXTERN int ZEXPORT gzclose(gzFile file); > +ZEXTERN int ZEXPORT gzclose(gzFile file); > /* > Flush all pending output for file, if necessary, close file and > deallocate the (de)compression state. Note that once file is closed, you > @@ -1678,9 +1775,10 @@ ZEXTERN int ZEXPORT gzclose_w(gzFile fil > ZEXTERN const char * ZEXPORT gzerror(gzFile file, int *errnum); > /* > Return the error message for the last error which occurred on file. > - errnum is set to zlib error number. If an error occurred in the file system > - and not in the compression library, errnum is set to Z_ERRNO and the > - application may consult errno to get the exact error code. > + If errnum is not NULL, *errnum is set to zlib error number. If an error > + occurred in the file system and not in the compression library, *errnum is > + set to Z_ERRNO and the application may consult errno to get the exact error > + code. > > The application must not modify the returned string. Future calls to > this function may invalidate the previously returned string. If file is > @@ -1731,7 +1829,8 @@ ZEXTERN uLong ZEXPORT adler32(uLong adle > ZEXTERN uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, > z_size_t len); > /* > - Same as adler32(), but with a size_t length. > + Same as adler32(), but with a size_t length. Note that a long is 32 bits > + on Windows. > */ > > /* > @@ -1767,7 +1866,8 @@ ZEXTERN uLong ZEXPORT crc32(uLong crc, c > ZEXTERN uLong ZEXPORT crc32_z(uLong crc, const Bytef *buf, > z_size_t len); > /* > - Same as crc32(), but with a size_t length. > + Same as crc32(), but with a size_t length. Note that a long is 32 bits on > + Windows. > */ > > /* > Index: lib/libz/zutil.c > =================================================================== > RCS file: /cvs/src/lib/libz/zutil.c,v > diff -u -p -r1.14 zutil.c > --- lib/libz/zutil.c 25 Apr 2023 16:59:10 -0000 1.14 > +++ lib/libz/zutil.c 10 Mar 2026 06:44:13 -0000 > @@ -1,5 +1,5 @@ > /* zutil.c -- target dependent utility functions for the compression library > - * Copyright (C) 1995-2017 Jean-loup Gailly > + * Copyright (C) 1995-2026 Jean-loup Gailly > * For conditions of distribution and use, see copyright notice in zlib.h > */ > > @@ -84,28 +84,36 @@ uLong ZEXPORT zlibCompileFlags(void) { > flags += 1L << 21; > #endif > #if defined(STDC) || defined(Z_HAVE_STDARG_H) > -# ifdef NO_vsnprintf > - flags += 1L << 25; > -# ifdef HAS_vsprintf_void > - flags += 1L << 26; > -# endif > -# else > -# ifdef HAS_vsnprintf_void > - flags += 1L << 26; > -# endif > -# endif > +# ifdef NO_vsnprintf > +# ifdef ZLIB_INSECURE > + flags += 1L << 25; > +# else > + flags += 1L << 27; > +# endif > +# ifdef HAS_vsprintf_void > + flags += 1L << 26; > +# endif > +# else > +# ifdef HAS_vsnprintf_void > + flags += 1L << 26; > +# endif > +# endif > #else > flags += 1L << 24; > -# ifdef NO_snprintf > - flags += 1L << 25; > -# ifdef HAS_sprintf_void > - flags += 1L << 26; > -# endif > -# else > -# ifdef HAS_snprintf_void > - flags += 1L << 26; > -# endif > -# endif > +# ifdef NO_snprintf > +# ifdef ZLIB_INSECURE > + flags += 1L << 25; > +# else > + flags += 1L << 27; > +# endif > +# ifdef HAS_sprintf_void > + flags += 1L << 26; > +# endif > +# else > +# ifdef HAS_snprintf_void > + flags += 1L << 26; > +# endif > +# endif > #endif > return flags; > } > @@ -140,28 +148,34 @@ const char * ZEXPORT zError(int err) { > > #ifndef HAVE_MEMCPY > > -void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len) { > - if (len == 0) return; > - do { > - *dest++ = *source++; /* ??? to be unrolled */ > - } while (--len != 0); > +void ZLIB_INTERNAL zmemcpy(void FAR *dst, const void FAR *src, z_size_t n) { > + uchf *p = dst; > + const uchf *q = src; > + while (n) { > + *p++ = *q++; > + n--; > + } > } > > -int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len) { > - uInt j; > - > - for (j = 0; j < len; j++) { > - if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; > +int ZLIB_INTERNAL zmemcmp(const void FAR *s1, const void FAR *s2, z_size_t n) { > + const uchf *p = s1, *q = s2; > + while (n) { > + if (*p++ != *q++) > + return (int)p[-1] - (int)q[-1]; > + n--; > } > return 0; > } > > -void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len) { > +void ZLIB_INTERNAL zmemzero(void FAR *b, z_size_t len) { > + uchf *p = b; > if (len == 0) return; > - do { > - *dest++ = 0; /* ??? to be unrolled */ > - } while (--len != 0); > + while (len) { > + *p++ = 0; > + len--; > + } > } > + > #endif > > #ifndef Z_SOLO > Index: lib/libz/zutil.h > =================================================================== > RCS file: /cvs/src/lib/libz/zutil.h,v > diff -u -p -r1.21 zutil.h > --- lib/libz/zutil.h 9 Nov 2024 21:51:37 -0000 1.21 > +++ lib/libz/zutil.h 10 Mar 2026 06:44:13 -0000 > @@ -1,5 +1,5 @@ > /* zutil.h -- internal interface and configuration of the compression library > - * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler > + * Copyright (C) 1995-2026 Jean-loup Gailly, Mark Adler > * For conditions of distribution and use, see copyright notice in zlib.h > */ > > @@ -38,6 +38,10 @@ > define "local" for the non-static meaning of "static", for readability > (compile with -Dlocal if your debugger can't find static symbols) */ > > +extern const char deflate_copyright[]; > +extern const char inflate_copyright[]; > +extern const char inflate9_copyright[]; > + > typedef unsigned char uch; > typedef uch FAR uchf; > typedef unsigned short ush; > @@ -216,9 +220,9 @@ extern z_const char * const z_errmsg[10] > # define zmemzero(dest, len) memset(dest, 0, len) > # endif > #else > - void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len); > - int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len); > - void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len); > + void ZLIB_INTERNAL zmemcpy(void FAR *, const void FAR *, z_size_t); > + int ZLIB_INTERNAL zmemcmp(const void FAR *, const void FAR *, z_size_t); > + void ZLIB_INTERNAL zmemzero(void FAR *, z_size_t); > #endif > > /* Diagnostic functions */ > @@ -255,5 +259,75 @@ extern z_const char * const z_errmsg[10] > /* Reverse the bytes in a 32-bit value */ > #define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ > (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) > + > +#ifdef Z_ONCE > +/* > + Create a local z_once() function depending on the availability of atomics. > + */ > + > +/* Check for the availability of atomics. */ > +#if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \ > + !defined(__STDC_NO_ATOMICS__) && !defined(SMALL) > + > +#include > +typedef struct { > + atomic_flag begun; > + atomic_int done; > +} z_once_t; > +#define Z_ONCE_INIT {ATOMIC_FLAG_INIT, 0} > + > +/* > + Run the provided init() function exactly once, even if multiple threads > + invoke once() at the same time. The state must be a once_t initialized with > + Z_ONCE_INIT. > + */ > +local void z_once(z_once_t *state, void (*init)(void)) { > + if (!atomic_load(&state->done)) { > + if (atomic_flag_test_and_set(&state->begun)) > + while (!atomic_load(&state->done)) > + ; > + else { > + init(); > + atomic_store(&state->done, 1); > + } > + } > +} > + > +#else /* no atomics */ > + > +#warning zlib not thread-safe > + > +typedef struct z_once_s { > + volatile int begun; > + volatile int done; > +} z_once_t; > +#define Z_ONCE_INIT {0, 0} > + > +/* Test and set. Alas, not atomic, but tries to limit the period of > + vulnerability. */ > +local int test_and_set(int volatile *flag) { > + int was; > + > + was = *flag; > + *flag = 1; > + return was; > +} > + > +/* Run the provided init() function once. This is not thread-safe. */ > +local void z_once(z_once_t *state, void (*init)(void)) { > + if (!state->done) { > + if (test_and_set(&state->begun)) > + while (!state->done) > + ; > + else { > + init(); > + state->done = 1; > + } > + } > +} > + > +#endif /* ?atomics */ > + > +#endif /* Z_ONCE */ > > #endif /* ZUTIL_H */ > Index: sys/lib/libz/compress.c > =================================================================== > RCS file: /cvs/src/sys/lib/libz/compress.c,v > diff -u -p -r1.5 compress.c > --- sys/lib/libz/compress.c 25 Apr 2023 16:59:57 -0000 1.5 > +++ sys/lib/libz/compress.c 10 Mar 2026 06:44:20 -0000 > @@ -1,5 +1,5 @@ > /* compress.c -- compress a memory buffer > - * Copyright (C) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler > + * Copyright (C) 1995-2026 Jean-loup Gailly, Mark Adler > * For conditions of distribution and use, see copyright notice in zlib.h > */ > > @@ -16,13 +16,19 @@ > compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough > memory, Z_BUF_ERROR if there was not enough room in the output buffer, > Z_STREAM_ERROR if the level parameter is invalid. > + > + The _z versions of the functions take size_t length arguments. > */ > -int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source, > - uLong sourceLen, int level) { > +int ZEXPORT compress2_z(Bytef *dest, z_size_t *destLen, const Bytef *source, > + z_size_t sourceLen, int level) { > z_stream stream; > int err; > const uInt max = (uInt)-1; > - uLong left; > + z_size_t left; > + > + if ((sourceLen > 0 && source == NULL) || > + destLen == NULL || (*destLen > 0 && dest == NULL)) > + return Z_STREAM_ERROR; > > left = *destLen; > *destLen = 0; > @@ -41,23 +47,36 @@ int ZEXPORT compress2(Bytef *dest, uLong > > do { > if (stream.avail_out == 0) { > - stream.avail_out = left > (uLong)max ? max : (uInt)left; > + stream.avail_out = left > (z_size_t)max ? max : (uInt)left; > left -= stream.avail_out; > } > if (stream.avail_in == 0) { > - stream.avail_in = sourceLen > (uLong)max ? max : (uInt)sourceLen; > + stream.avail_in = sourceLen > (z_size_t)max ? max : > + (uInt)sourceLen; > sourceLen -= stream.avail_in; > } > err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH); > } while (err == Z_OK); > > - *destLen = stream.total_out; > + *destLen = (z_size_t)(stream.next_out - dest); > deflateEnd(&stream); > return err == Z_STREAM_END ? Z_OK : err; > } > - > +int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source, > + uLong sourceLen, int level) { > + int ret; > + z_size_t got = *destLen; > + ret = compress2_z(dest, &got, source, sourceLen, level); > + *destLen = (uLong)got; > + return ret; > +} > /* =========================================================================== > */ > +int ZEXPORT compress_z(Bytef *dest, z_size_t *destLen, const Bytef *source, > + z_size_t sourceLen) { > + return compress2_z(dest, destLen, source, sourceLen, > + Z_DEFAULT_COMPRESSION); > +} > int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source, > uLong sourceLen) { > return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); > @@ -67,7 +86,12 @@ int ZEXPORT compress(Bytef *dest, uLongf > If the default memLevel or windowBits for deflateInit() is changed, then > this function needs to be updated. > */ > +z_size_t ZEXPORT compressBound_z(z_size_t sourceLen) { > + z_size_t bound = sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + > + (sourceLen >> 25) + 13; > + return bound < sourceLen ? (z_size_t)-1 : bound; > +} > uLong ZEXPORT compressBound(uLong sourceLen) { > - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + > - (sourceLen >> 25) + 13; > + z_size_t bound = compressBound_z(sourceLen); > + return (uLong)bound != bound ? (uLong)-1 : (uLong)bound; > } > Index: sys/lib/libz/crc32.c > =================================================================== > RCS file: /cvs/src/sys/lib/libz/crc32.c,v > diff -u -p -r1.20 crc32.c > --- sys/lib/libz/crc32.c 4 Mar 2026 05:44:56 -0000 1.20 > +++ sys/lib/libz/crc32.c 10 Mar 2026 06:44:20 -0000 > @@ -1,5 +1,5 @@ > /* crc32.c -- compute the CRC-32 of a data stream > - * Copyright (C) 1995-2022 Mark Adler > + * Copyright (C) 1995-2026 Mark Adler > * For conditions of distribution and use, see copyright notice in zlib.h > * > * This interleaved implementation of a CRC makes use of pipelined multiple > @@ -22,11 +22,18 @@ > # include > # ifndef DYNAMIC_CRC_TABLE > # define DYNAMIC_CRC_TABLE > -# endif /* !DYNAMIC_CRC_TABLE */ > -#endif /* MAKECRCH */ > +# endif > +#endif > +#ifdef DYNAMIC_CRC_TABLE > +# define Z_ONCE > +#endif > > #include "zutil.h" /* for Z_U4, Z_U8, z_crc_t, and FAR definitions */ > > +#ifdef HAVE_S390X_VX > +# include "contrib/crc32vx/crc32_vx_hooks.h" > +#endif > + > /* > A CRC of a message is computed on N braids of words in the message, where > each word consists of W bytes (4 or 8). If N is 3, for example, then three > @@ -97,7 +104,8 @@ > #endif > > /* If available, use the ARM processor CRC32 instruction. */ > -#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8 > +#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && \ > + defined(W) && W == 8 > # define ARMCRC32 > #endif > > @@ -150,10 +158,10 @@ local z_word_t byte_swap(z_word_t word) > Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial, > reflected. For speed, this requires that a not be zero. > */ > -local z_crc_t multmodp(z_crc_t a, z_crc_t b) { > - z_crc_t m, p; > +local uLong multmodp(uLong a, uLong b) { > + uLong m, p; > > - m = (z_crc_t)1 << 31; > + m = (uLong)1 << 31; > p = 0; > for (;;) { > if (a & m) { > @@ -169,12 +177,12 @@ local z_crc_t multmodp(z_crc_t a, z_crc_ > > /* > Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been > - initialized. > + initialized. n must not be negative. > */ > -local z_crc_t x2nmodp(z_off64_t n, unsigned k) { > - z_crc_t p; > +local uLong x2nmodp(z_off64_t n, unsigned k) { > + uLong p; > > - p = (z_crc_t)1 << 31; /* x^0 == 1 */ > + p = (uLong)1 << 31; /* x^0 == 1 */ > while (n) { > if (n & 1) > p = multmodp(x2n_table[k & 31], p); > @@ -202,83 +210,8 @@ local z_crc_t FAR crc_table[256]; > local void write_table64(FILE *, const z_word_t FAR *, int); > #endif /* MAKECRCH */ > > -/* > - Define a once() function depending on the availability of atomics. If this is > - compiled with DYNAMIC_CRC_TABLE defined, and if CRCs will be computed in > - multiple threads, and if atomics are not available, then get_crc_table() must > - be called to initialize the tables and must return before any threads are > - allowed to compute or combine CRCs. > - */ > - > -/* Definition of once functionality. */ > -typedef struct once_s once_t; > - > -/* Check for the availability of atomics. */ > -#if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \ > - !defined(__STDC_NO_ATOMICS__) && !defined(SMALL) > - > -#include > - > -/* Structure for once(), which must be initialized with ONCE_INIT. */ > -struct once_s { > - atomic_flag begun; > - atomic_int done; > -}; > -#define ONCE_INIT {ATOMIC_FLAG_INIT, 0} > - > -/* > - Run the provided init() function exactly once, even if multiple threads > - invoke once() at the same time. The state must be a once_t initialized with > - ONCE_INIT. > - */ > -local void once(once_t *state, void (*init)(void)) { > - if (!atomic_load(&state->done)) { > - if (atomic_flag_test_and_set(&state->begun)) > - while (!atomic_load(&state->done)) > - ; > - else { > - init(); > - atomic_store(&state->done, 1); > - } > - } > -} > - > -#else /* no atomics */ > - > -/* Structure for once(), which must be initialized with ONCE_INIT. */ > -struct once_s { > - volatile int begun; > - volatile int done; > -}; > -#define ONCE_INIT {0, 0} > - > -/* Test and set. Alas, not atomic, but tries to minimize the period of > - vulnerability. */ > -local int test_and_set(int volatile *flag) { > - int was; > - > - was = *flag; > - *flag = 1; > - return was; > -} > - > -/* Run the provided init() function once. This is not thread-safe. */ > -local void once(once_t *state, void (*init)(void)) { > - if (!state->done) { > - if (test_and_set(&state->begun)) > - while (!state->done) > - ; > - else { > - init(); > - state->done = 1; > - } > - } > -} > - > -#endif > - > /* State for once(). */ > -local once_t made = ONCE_INIT; > +local z_once_t made = Z_ONCE_INIT; > > /* > Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: > @@ -324,7 +257,7 @@ local void make_crc_table(void) { > p = (z_crc_t)1 << 30; /* x^1 */ > x2n_table[0] = p; > for (n = 1; n < 32; n++) > - x2n_table[n] = p = multmodp(p, p); > + x2n_table[n] = p = (z_crc_t)multmodp(p, p); > > #ifdef W > /* initialize the braiding tables -- needs x2n_table[] */ > @@ -527,11 +460,11 @@ local void braid(z_crc_t ltl[][256], z_w > int k; > z_crc_t i, p, q; > for (k = 0; k < w; k++) { > - p = x2nmodp((n * w + 3 - k) << 3, 0); > + p = (z_crc_t)x2nmodp((n * w + 3 - k) << 3, 0); > ltl[k][0] = 0; > big[w - 1 - k][0] = 0; > for (i = 1; i < 256; i++) { > - ltl[k][i] = q = multmodp(i << 24, p); > + ltl[k][i] = q = (z_crc_t)multmodp(i << 24, p); > big[w - 1 - k][i] = byte_swap(q); > } > } > @@ -546,7 +479,7 @@ local void braid(z_crc_t ltl[][256], z_w > */ > const z_crc_t FAR * ZEXPORT get_crc_table(void) { > #ifdef DYNAMIC_CRC_TABLE > - once(&made, make_crc_table); > + z_once(&made, make_crc_table); > #endif /* DYNAMIC_CRC_TABLE */ > return (const z_crc_t FAR *)crc_table; > } > @@ -570,9 +503,8 @@ const z_crc_t FAR * ZEXPORT get_crc_tabl > #define Z_BATCH_ZEROS 0xa10d3d0c /* computed from Z_BATCH = 3990 */ > #define Z_BATCH_MIN 800 /* fewest words in a final batch */ > > -unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, > - z_size_t len) { > - z_crc_t val; > +uLong ZEXPORT crc32_z(uLong crc, const unsigned char FAR *buf, z_size_t len) { > + uLong val; > z_word_t crc1, crc2; > const z_word_t *word; > z_word_t val0, val1, val2; > @@ -583,7 +515,7 @@ unsigned long ZEXPORT crc32_z(unsigned l > if (buf == Z_NULL) return 0; > > #ifdef DYNAMIC_CRC_TABLE > - once(&made, make_crc_table); > + z_once(&made, make_crc_table); > #endif /* DYNAMIC_CRC_TABLE */ > > /* Pre-condition the CRC */ > @@ -638,7 +570,7 @@ unsigned long ZEXPORT crc32_z(unsigned l > } > word += 3 * last; > num -= 3 * last; > - val = x2nmodp(last, 6); > + val = x2nmodp((int)last, 6); > crc = multmodp(val, crc) ^ crc1; > crc = multmodp(val, crc) ^ crc2; > } > @@ -689,13 +621,12 @@ local z_word_t crc_word_big(z_word_t dat > #endif > > /* ========================================================================= */ > -unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, > - z_size_t len) { > +uLong ZEXPORT crc32_z(uLong crc, const unsigned char FAR *buf, z_size_t len) { > /* Return initial CRC, if requested. */ > if (buf == Z_NULL) return 0; > > #ifdef DYNAMIC_CRC_TABLE > - once(&made, make_crc_table); > + z_once(&made, make_crc_table); > #endif /* DYNAMIC_CRC_TABLE */ > > /* Pre-condition the CRC */ > @@ -1010,42 +941,41 @@ unsigned long ZEXPORT crc32_z(unsigned l > #endif > > /* ========================================================================= */ > -unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, > - uInt len) { > +uLong ZEXPORT crc32(uLong crc, const unsigned char FAR *buf, uInt len) { > + #ifdef HAVE_S390X_VX > + return crc32_z_hook(crc, buf, len); > + #endif > return crc32_z(crc, buf, len); > } > > /* ========================================================================= */ > -uLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2) { > +uLong ZEXPORT crc32_combine_gen64(z_off64_t len2) { > if (len2 < 0) > return 0; > #ifdef DYNAMIC_CRC_TABLE > - once(&made, make_crc_table); > + z_once(&made, make_crc_table); > #endif /* DYNAMIC_CRC_TABLE */ > - return multmodp(x2nmodp(len2, 3), crc1) ^ (crc2 & 0xffffffff); > + return x2nmodp(len2, 3); > } > > /* ========================================================================= */ > -uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2) { > - return crc32_combine64(crc1, crc2, (z_off64_t)len2); > +uLong ZEXPORT crc32_combine_gen(z_off_t len2) { > + return crc32_combine_gen64((z_off64_t)len2); > } > > /* ========================================================================= */ > -uLong ZEXPORT crc32_combine_gen64(z_off64_t len2) { > - if (len2 < 0) > +uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op) { > + if (op == 0) > return 0; > -#ifdef DYNAMIC_CRC_TABLE > - once(&made, make_crc_table); > -#endif /* DYNAMIC_CRC_TABLE */ > - return x2nmodp(len2, 3); > + return multmodp(op, crc1 & 0xffffffff) ^ (crc2 & 0xffffffff); > } > > /* ========================================================================= */ > -uLong ZEXPORT crc32_combine_gen(z_off_t len2) { > - return crc32_combine_gen64((z_off64_t)len2); > +uLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2) { > + return crc32_combine_op(crc1, crc2, crc32_combine_gen64(len2)); > } > > /* ========================================================================= */ > -uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op) { > - return multmodp(op, crc1) ^ (crc2 & 0xffffffff); > +uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2) { > + return crc32_combine64(crc1, crc2, (z_off64_t)len2); > } > Index: sys/lib/libz/deflate.c > =================================================================== > RCS file: /cvs/src/sys/lib/libz/deflate.c,v > diff -u -p -r1.23 deflate.c > --- sys/lib/libz/deflate.c 7 Mar 2026 07:28:22 -0000 1.23 > +++ sys/lib/libz/deflate.c 10 Mar 2026 06:44:20 -0000 > @@ -1,5 +1,5 @@ > /* deflate.c -- compress data using the deflation algorithm > - * Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler > + * Copyright (C) 1995-2026 Jean-loup Gailly and Mark Adler > * For conditions of distribution and use, see copyright notice in zlib.h > */ > > @@ -37,7 +37,7 @@ > * REFERENCES > * > * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". > - * Available in http://tools.ietf.org/html/rfc1951 > + * Available at https://datatracker.ietf.org/doc/html/rfc1951 > * > * A description of the Rabin and Karp algorithm is given in the book > * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. > @@ -166,8 +166,7 @@ local const config configuration_table[1 > #define CLEAR_HASH(s) \ > do { \ > s->head[s->hash_size - 1] = NIL; \ > - zmemzero((Bytef *)s->head, \ > - (unsigned)(s->hash_size - 1)*sizeof(*s->head)); \ > + zmemzero(s->head, (unsigned)(s->hash_size - 1)*sizeof(*s->head)); \ > s->slid = 0; \ > } while (0) > > @@ -257,7 +256,14 @@ local void fill_window(deflate_state *s) > more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); > > /* Deal with !@#$% 64K limit: */ > +#ifdef _MSC_VER > +#pragma warning(push) > +#pragma warning(disable: 4127) > +#endif > if (sizeof(int) <= 2) { > +#ifdef _MSC_VER > +#pragma warning(pop) > +#endif > if (more == 0 && s->strstart == 0 && s->lookahead == 0) { > more = wsize; > > @@ -711,10 +717,15 @@ int ZEXPORT deflateSetHeader(z_streamp s > /* ========================================================================= */ > int ZEXPORT deflatePending(z_streamp strm, unsigned *pending, int *bits) { > if (deflateStateCheck(strm)) return Z_STREAM_ERROR; > - if (pending != Z_NULL) > - *pending = strm->state->pending; > if (bits != Z_NULL) > *bits = strm->state->bi_valid; > + if (pending != Z_NULL) { > + *pending = (unsigned)strm->state->pending; > + if (*pending != strm->state->pending) { > + *pending = (unsigned)-1; > + return Z_BUF_ERROR; > + } > + } > return Z_OK; > } > > @@ -838,24 +849,30 @@ int ZEXPORT deflateTune(z_streamp strm, > * > * Shifts are used to approximate divisions, for speed. > */ > -uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) { > +z_size_t ZEXPORT deflateBound_z(z_streamp strm, z_size_t sourceLen) { > deflate_state *s; > - uLong fixedlen, storelen, wraplen; > + z_size_t fixedlen, storelen, wraplen, bound; > > /* upper bound for fixed blocks with 9-bit literals and length 255 > (memLevel == 2, which is the lowest that may not use stored blocks) -- > ~13% overhead plus a small constant */ > fixedlen = sourceLen + (sourceLen >> 3) + (sourceLen >> 8) + > (sourceLen >> 9) + 4; > + if (fixedlen < sourceLen) > + fixedlen = (z_size_t)-1; > > /* upper bound for stored blocks with length 127 (memLevel == 1) -- > ~4% overhead plus a small constant */ > storelen = sourceLen + (sourceLen >> 5) + (sourceLen >> 7) + > (sourceLen >> 11) + 7; > + if (storelen < sourceLen) > + storelen = (z_size_t)-1; > > /* if can't get parameters, return larger bound plus a wrapper */ > - if (deflateStateCheck(strm)) > - return (fixedlen > storelen ? fixedlen : storelen) + 18; > + if (deflateStateCheck(strm)) { > + bound = fixedlen > storelen ? fixedlen : storelen; > + return bound + 18 < bound ? (z_size_t)-1 : bound + 18; > + } > > /* compute wrapper length */ > s = strm->state; > @@ -893,14 +910,21 @@ uLong ZEXPORT deflateBound(z_streamp str > } > > /* if not default parameters, return one of the conservative bounds */ > - if (s->w_bits != 15 || s->hash_bits != 8 + 7) > - return (s->w_bits <= s->hash_bits && s->level ? fixedlen : storelen) + > - wraplen; > + if (s->w_bits != 15 || s->hash_bits != 8 + 7) { > + bound = s->w_bits <= s->hash_bits && s->level ? fixedlen : > + storelen; > + return bound + wraplen < bound ? (z_size_t)-1 : bound + wraplen; > + } > > /* default settings: return tight bound for that case -- ~0.03% overhead > plus a small constant */ > - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + > - (sourceLen >> 25) + 13 - 6 + wraplen; > + bound = sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + > + (sourceLen >> 25) + 13 - 6 + wraplen; > + return bound < sourceLen ? (z_size_t)-1 : bound; > +} > +uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) { > + z_size_t bound = deflateBound_z(strm, sourceLen); > + return (uLong)bound != bound ? (uLong)-1 : (uLong)bound; > } > > /* ========================================================================= > @@ -924,8 +948,8 @@ local void flush_pending(z_streamp strm) > deflate_state *s = strm->state; > > _tr_flush_bits(s); > - len = s->pending; > - if (len > strm->avail_out) len = strm->avail_out; > + len = s->pending > strm->avail_out ? strm->avail_out : > + (unsigned)s->pending; > if (len == 0) return; > > zmemcpy(strm->next_out, s->pending_out, len); > @@ -945,8 +969,8 @@ local void flush_pending(z_streamp strm) > #define HCRC_UPDATE(beg) \ > do { \ > if (s->gzhead->hcrc && s->pending > (beg)) \ > - strm->adler = crc32(strm->adler, s->pending_buf + (beg), \ > - s->pending - (beg)); \ > + strm->adler = crc32_z(strm->adler, s->pending_buf + (beg), \ > + s->pending - (beg)); \ > } while (0) > > /* ========================================================================= */ > @@ -1080,8 +1104,8 @@ int ZEXPORT deflate(z_streamp strm, int > put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); > } > if (s->gzhead->hcrc) > - strm->adler = crc32(strm->adler, s->pending_buf, > - s->pending); > + strm->adler = crc32_z(strm->adler, s->pending_buf, > + s->pending); > s->gzindex = 0; > s->status = EXTRA_STATE; > } > @@ -1089,9 +1113,9 @@ int ZEXPORT deflate(z_streamp strm, int > if (s->status == EXTRA_STATE) { > if (s->gzhead->extra != Z_NULL) { > ulg beg = s->pending; /* start of bytes to update crc */ > - uInt left = (s->gzhead->extra_len & 0xffff) - s->gzindex; > + ulg left = (s->gzhead->extra_len & 0xffff) - s->gzindex; > while (s->pending + left > s->pending_buf_size) { > - uInt copy = s->pending_buf_size - s->pending; > + ulg copy = s->pending_buf_size - s->pending; > zmemcpy(s->pending_buf + s->pending, > s->gzhead->extra + s->gzindex, copy); > s->pending = s->pending_buf_size; > @@ -1302,13 +1326,13 @@ int ZEXPORT deflateCopy(z_streamp dest, > > ss = source->state; > > - zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); > + zmemcpy(dest, source, sizeof(z_stream)); > > ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); > if (ds == Z_NULL) return Z_MEM_ERROR; > zmemzero(ds, sizeof(deflate_state)); > dest->state = (struct internal_state FAR *) ds; > - zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); > + zmemcpy(ds, ss, sizeof(deflate_state)); > ds->strm = dest; > > ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); > @@ -1323,10 +1347,10 @@ int ZEXPORT deflateCopy(z_streamp dest, > } > /* following zmemcpy's do not work for 16-bit MSDOS */ > zmemcpy(ds->window, ss->window, ss->high_water); > - zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, > + zmemcpy(ds->prev, ss->prev, > (ss->slid || ss->strstart - ss->insert > ds->w_size ? ds->w_size : > ss->strstart - ss->insert) * sizeof(Pos)); > - zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); > + zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); > > ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); > zmemcpy(ds->pending_out, ss->pending_out, ss->pending); > @@ -1360,9 +1384,9 @@ int ZEXPORT deflateCopy(z_streamp dest, > */ > local uInt longest_match(deflate_state *s, IPos cur_match) { > unsigned chain_length = s->max_chain_length;/* max hash chain length */ > - register Bytef *scan = s->window + s->strstart; /* current string */ > - register Bytef *match; /* matched string */ > - register int len; /* length of current match */ > + Bytef *scan = s->window + s->strstart; /* current string */ > + Bytef *match; /* matched string */ > + int len; /* length of current match */ > int best_len = (int)s->prev_length; /* best match length so far */ > int nice_match = s->nice_match; /* stop if match long enough */ > IPos limit = s->strstart > (IPos)MAX_DIST(s) ? > @@ -1377,13 +1401,13 @@ local uInt longest_match(deflate_state * > /* Compare two bytes at a time. Note: this is not always beneficial. > * Try with and without -DUNALIGNED_OK to check. > */ > - register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; > - register ush scan_start = *(ushf*)scan; > - register ush scan_end = *(ushf*)(scan + best_len - 1); > + Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; > + ush scan_start = *(ushf*)scan; > + ush scan_end = *(ushf*)(scan + best_len - 1); > #else > - register Bytef *strend = s->window + s->strstart + MAX_MATCH; > - register Byte scan_end1 = scan[best_len - 1]; > - register Byte scan_end = scan[best_len]; > + Bytef *strend = s->window + s->strstart + MAX_MATCH; > + Byte scan_end1 = scan[best_len - 1]; > + Byte scan_end = scan[best_len]; > #endif > > /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. > @@ -1507,10 +1531,10 @@ local uInt longest_match(deflate_state * > * Optimized version for FASTEST only > */ > local uInt longest_match(deflate_state *s, IPos cur_match) { > - register Bytef *scan = s->window + s->strstart; /* current string */ > - register Bytef *match; /* matched string */ > - register int len; /* length of current match */ > - register Bytef *strend = s->window + s->strstart + MAX_MATCH; > + Bytef *scan = s->window + s->strstart; /* current string */ > + Bytef *match; /* matched string */ > + int len; /* length of current match */ > + Bytef *strend = s->window + s->strstart + MAX_MATCH; > > /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. > * It is easy to get rid of this optimization if necessary. > @@ -1570,7 +1594,7 @@ local uInt longest_match(deflate_state * > local void check_match(deflate_state *s, IPos start, IPos match, int length) { > /* check that the match is indeed a match */ > Bytef *back = s->window + (int)match, *here = s->window + start; > - IPos len = length; > + IPos len = (IPos)length; > if (match == (IPos)-1) { > /* match starts one byte before the current window -- just compare the > subsequent length-1 bytes */ > @@ -1644,7 +1668,7 @@ local block_state deflate_stored(deflate > * this is 32K. This can be as small as 507 bytes for memLevel == 1. For > * large input and output buffers, the stored block size will be larger. > */ > - unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size); > + unsigned min_block = (unsigned)(MIN(s->pending_buf_size - 5, s->w_size)); > > /* Copy as many min_block or larger stored blocks directly to next_out as > * possible. If flushing, copy the remaining available input to next_out as > @@ -1659,12 +1683,12 @@ local block_state deflate_stored(deflate > * would be copied from what's left in the window. > */ > len = MAX_STORED; /* maximum deflate stored block length */ > - have = (s->bi_valid + 42) >> 3; /* number of header bytes */ > + have = ((unsigned)s->bi_valid + 42) >> 3; /* bytes in header */ > if (s->strm->avail_out < have) /* need room for header */ > break; > /* maximum stored block length that will fit in avail_out: */ > have = s->strm->avail_out - have; > - left = s->strstart - s->block_start; /* bytes left in window */ > + left = (unsigned)(s->strstart - s->block_start); /* window bytes */ > if (len > (ulg)left + s->strm->avail_in) > len = left + s->strm->avail_in; /* limit len to the input */ > if (len > have) > @@ -1772,7 +1796,7 @@ local block_state deflate_stored(deflate > return block_done; > > /* Fill the window with any remaining input. */ > - have = s->window_size - s->strstart; > + have = (unsigned)(s->window_size - s->strstart); > if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) { > /* Slide the window down. */ > s->block_start -= s->w_size; > @@ -1799,11 +1823,11 @@ local block_state deflate_stored(deflate > * have enough input for a worthy block, or if flushing and there is enough > * room for the remaining input as a stored block in the pending buffer. > */ > - have = (s->bi_valid + 42) >> 3; /* number of header bytes */ > + have = ((unsigned)s->bi_valid + 42) >> 3; /* bytes in header */ > /* maximum stored block length that will fit in pending: */ > - have = MIN(s->pending_buf_size - have, MAX_STORED); > + have = (unsigned)MIN(s->pending_buf_size - have, MAX_STORED); > min_block = MIN(have, s->w_size); > - left = s->strstart - s->block_start; > + left = (unsigned)(s->strstart - s->block_start); > if (left >= min_block || > ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH && > s->strm->avail_in == 0 && left <= have)) { > @@ -1866,7 +1890,7 @@ local block_state deflate_fast(deflate_s > /* longest_match() sets match_start */ > } > if (s->match_length >= MIN_MATCH) { > - check_match(s, s->strstart, s->match_start, s->match_length); > + check_match(s, s->strstart, s->match_start, (int)s->match_length); > > _tr_tally_dist(s, s->strstart - s->match_start, > s->match_length - MIN_MATCH, bflush); > @@ -1988,7 +2012,7 @@ local block_state deflate_slow(deflate_s > uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; > /* Do not insert strings in hash table beyond this. */ > > - check_match(s, s->strstart - 1, s->prev_match, s->prev_length); > + check_match(s, s->strstart - 1, s->prev_match, (int)s->prev_length); > > _tr_tally_dist(s, s->strstart - 1 - s->prev_match, > s->prev_length - MIN_MATCH, bflush); > @@ -2096,7 +2120,7 @@ local block_state deflate_rle(deflate_st > > /* Emit match if have run of MIN_MATCH or longer, else emit literal */ > if (s->match_length >= MIN_MATCH) { > - check_match(s, s->strstart, s->strstart - 1, s->match_length); > + check_match(s, s->strstart, s->strstart - 1, (int)s->match_length); > > _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); > > Index: sys/lib/libz/deflate.h > =================================================================== > RCS file: /cvs/src/sys/lib/libz/deflate.h,v > diff -u -p -r1.14 deflate.h > --- sys/lib/libz/deflate.h 7 Mar 2026 07:28:22 -0000 1.14 > +++ sys/lib/libz/deflate.h 10 Mar 2026 06:44:20 -0000 > @@ -1,5 +1,5 @@ > /* deflate.h -- internal compression state > - * Copyright (C) 1995-2024 Jean-loup Gailly > + * Copyright (C) 1995-2026 Jean-loup Gailly > * For conditions of distribution and use, see copyright notice in zlib.h > */ > > Index: sys/lib/libz/infback.c > =================================================================== > RCS file: /cvs/src/sys/lib/libz/infback.c,v > diff -u -p -r1.14 infback.c > --- sys/lib/libz/infback.c 3 Feb 2025 19:18:30 -0000 1.14 > +++ sys/lib/libz/infback.c 10 Mar 2026 06:44:20 -0000 > @@ -1,5 +1,5 @@ > /* infback.c -- inflate using a call-back interface > - * Copyright (C) 1995-2022 Mark Adler > + * Copyright (C) 1995-2026 Mark Adler > * For conditions of distribution and use, see copyright notice in zlib.h > */ > > @@ -63,57 +63,6 @@ int ZEXPORT inflateBackInit_(z_streamp s > return Z_OK; > } > > -/* > - Return state with length and distance decoding tables and index sizes set to > - fixed code decoding. Normally this returns fixed tables from inffixed.h. > - If BUILDFIXED is defined, then instead this routine builds the tables the > - first time it's called, and returns those tables the first time and > - thereafter. This reduces the size of the code by about 2K bytes, in > - exchange for a little execution time. However, BUILDFIXED should not be > - used for threaded applications, since the rewriting of the tables and virgin > - may not be thread-safe. > - */ > -local void fixedtables(struct inflate_state FAR *state) { > -#ifdef BUILDFIXED > - static int virgin = 1; > - static code *lenfix, *distfix; > - static code fixed[544]; > - > - /* build fixed huffman tables if first call (may not be thread safe) */ > - if (virgin) { > - unsigned sym, bits; > - static code *next; > - > - /* literal/length table */ > - sym = 0; > - while (sym < 144) state->lens[sym++] = 8; > - while (sym < 256) state->lens[sym++] = 9; > - while (sym < 280) state->lens[sym++] = 7; > - while (sym < 288) state->lens[sym++] = 8; > - next = fixed; > - lenfix = next; > - bits = 9; > - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); > - > - /* distance table */ > - sym = 0; > - while (sym < 32) state->lens[sym++] = 5; > - distfix = next; > - bits = 5; > - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); > - > - /* do this just once */ > - virgin = 0; > - } > -#else /* !BUILDFIXED */ > -# include "inffixed.h" > -#endif /* BUILDFIXED */ > - state->lencode = lenfix; > - state->lenbits = 9; > - state->distcode = distfix; > - state->distbits = 5; > -} > - > /* Macros for inflateBack(): */ > > /* Load returned state from inflate_fast() */ > @@ -293,7 +242,7 @@ int ZEXPORT inflateBack(z_streamp strm, > state->mode = STORED; > break; > case 1: /* fixed block */ > - fixedtables(state); > + inflate_fixed(state); > Tracev((stderr, "inflate: fixed codes block%s\n", > state->last ? " (last)" : "")); > state->mode = LEN; /* decode codes */ > @@ -303,7 +252,7 @@ int ZEXPORT inflateBack(z_streamp strm, > state->last ? " (last)" : "")); > state->mode = TABLE; > break; > - case 3: > + default: > #ifdef SMALL > strm->msg = (z_const char *)"error"; > #else > @@ -364,7 +313,8 @@ int ZEXPORT inflateBack(z_streamp strm, > #ifdef SMALL > strm->msg = (z_const char *)"error"; > #else > - strm->msg = (z_const char *)"too many length or distance symbols"; > + strm->msg = (z_const char *) > + "too many length or distance symbols"; > #endif > state->mode = BAD; > break; > @@ -417,7 +367,8 @@ int ZEXPORT inflateBack(z_streamp strm, > #ifdef SMALL > strm->msg = (z_const char *)"error"; > #else > - strm->msg = (z_const char *)"invalid bit length repeat"; > + strm->msg = (z_const char *) > + "invalid bit length repeat"; > #endif > state->mode = BAD; > break; > @@ -444,7 +395,8 @@ int ZEXPORT inflateBack(z_streamp strm, > #ifdef SMALL > strm->msg = (z_const char *)"error"; > #else > - strm->msg = (z_const char *)"invalid bit length repeat"; > + strm->msg = (z_const char *) > + "invalid bit length repeat"; > #endif > state->mode = BAD; > break; > @@ -462,7 +414,8 @@ int ZEXPORT inflateBack(z_streamp strm, > #ifdef SMALL > strm->msg = (z_const char *)"error"; > #else > - strm->msg = (z_const char *)"invalid code -- missing end-of-block"; > + strm->msg = (z_const char *) > + "invalid code -- missing end-of-block"; > #endif > state->mode = BAD; > break; > Index: sys/lib/libz/inffast.c > =================================================================== > RCS file: /cvs/src/sys/lib/libz/inffast.c,v > diff -u -p -r1.17 inffast.c > --- sys/lib/libz/inffast.c 30 Jun 2024 05:18:14 -0000 1.17 > +++ sys/lib/libz/inffast.c 10 Mar 2026 06:44:20 -0000 > @@ -1,5 +1,5 @@ > /* inffast.c -- fast decoding > - * Copyright (C) 1995-2017 Mark Adler > + * Copyright (C) 1995-2026 Mark Adler > * For conditions of distribution and use, see copyright notice in zlib.h > */ > > @@ -155,7 +155,8 @@ void ZLIB_INTERNAL inflate_fast(z_stream > dist += (unsigned)hold & ((1U << op) - 1); > #ifdef INFLATE_STRICT > if (dist > dmax) { > - strm->msg = (z_const char *)"invalid distance too far back"; > + strm->msg = (z_const char *) > + "invalid distance too far back"; > state->mode = BAD; > break; > } > @@ -171,8 +172,8 @@ void ZLIB_INTERNAL inflate_fast(z_stream > #ifdef SMALL > strm->msg = (z_const char *)"error"; > #else > - strm->msg = > - (z_const char *)"invalid distance too far back"; > + strm->msg = (z_const char *) > + "invalid distance too far back"; > #endif > state->mode = BAD; > break; > Index: sys/lib/libz/inffixed.h > =================================================================== > RCS file: /cvs/src/sys/lib/libz/inffixed.h,v > diff -u -p -r1.6 inffixed.h > --- sys/lib/libz/inffixed.h 23 Oct 2022 06:00:23 -0000 1.6 > +++ sys/lib/libz/inffixed.h 10 Mar 2026 06:44:20 -0000 > @@ -1,94 +1,94 @@ > - /* inffixed.h -- table for decoding fixed codes > - * Generated automatically by makefixed(). > - */ > +/* inffixed.h -- table for decoding fixed codes > + * Generated automatically by makefixed(). > + */ > > - /* WARNING: this file should *not* be used by applications. > - It is part of the implementation of this library and is > - subject to change. Applications should only use zlib.h. > - */ > +/* WARNING: this file should *not* be used by applications. > + It is part of the implementation of this library and is > + subject to change. Applications should only use zlib.h. > + */ > > - static const code lenfix[512] = { > - {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, > - {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, > - {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, > - {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, > - {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, > - {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, > - {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, > - {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, > - {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, > - {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, > - {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, > - {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, > - {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, > - {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, > - {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, > - {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, > - {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, > - {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, > - {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, > - {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, > - {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, > - {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, > - {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, > - {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, > - {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, > - {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, > - {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, > - {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, > - {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, > - {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, > - {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, > - {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, > - {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, > - {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, > - {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, > - {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, > - {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, > - {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, > - {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, > - {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, > - {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, > - {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, > - {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, > - {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, > - {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, > - {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, > - {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, > - {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, > - {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, > - {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, > - {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, > - {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, > - {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, > - {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, > - {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, > - {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, > - {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, > - {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, > - {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, > - {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, > - {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, > - {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, > - {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, > - {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, > - {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, > - {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, > - {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, > - {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, > - {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, > - {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, > - {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, > - {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, > - {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, > - {0,9,255} > - }; > +static const code lenfix[512] = { > + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, > + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, > + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, > + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, > + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, > + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, > + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, > + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, > + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, > + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, > + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, > + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, > + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, > + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, > + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, > + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, > + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, > + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, > + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, > + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, > + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, > + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, > + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, > + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, > + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, > + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, > + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, > + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, > + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, > + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, > + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, > + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, > + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, > + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, > + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, > + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, > + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, > + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, > + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, > + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, > + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, > + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, > + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, > + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, > + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, > + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, > + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, > + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, > + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, > + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, > + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, > + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, > + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, > + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, > + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, > + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, > + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, > + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, > + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, > + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, > + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, > + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, > + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, > + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, > + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, > + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, > + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, > + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, > + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, > + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, > + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, > + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, > + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, > + {0,9,255} > +}; > > - static const code distfix[32] = { > - {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, > - {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, > - {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, > - {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, > - {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, > - {22,5,193},{64,5,0} > - }; > +static const code distfix[32] = { > + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, > + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, > + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, > + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, > + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, > + {22,5,193},{64,5,0} > +}; > Index: sys/lib/libz/inflate.c > =================================================================== > RCS file: /cvs/src/sys/lib/libz/inflate.c,v > diff -u -p -r1.28 inflate.c > --- sys/lib/libz/inflate.c 6 Mar 2026 05:37:06 -0000 1.28 > +++ sys/lib/libz/inflate.c 10 Mar 2026 06:44:20 -0000 > @@ -1,5 +1,5 @@ > /* inflate.c -- zlib decompression > - * Copyright (C) 1995-2022 Mark Adler > + * Copyright (C) 1995-2026 Mark Adler > * For conditions of distribution and use, see copyright notice in zlib.h > */ > > @@ -85,12 +85,6 @@ > #include "inflate.h" > #include "inffast.h" > > -#ifdef MAKEFIXED > -# ifndef BUILDFIXED > -# define BUILDFIXED > -# endif > -#endif > - > local int inflateStateCheck(z_streamp strm) { > struct inflate_state FAR *state; > if (strm == Z_NULL || > @@ -110,6 +104,7 @@ int ZEXPORT inflateResetKeep(z_streamp s > state = (struct inflate_state FAR *)strm->state; > strm->total_in = strm->total_out = state->total = 0; > strm->msg = Z_NULL; > + strm->data_type = 0; > if (state->wrap) /* to support ill-conceived Java test suite */ > strm->adler = state->wrap & 1; > state->mode = HEAD; > @@ -235,124 +230,12 @@ int ZEXPORT inflatePrime(z_streamp strm, > } > if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR; > value &= (1L << bits) - 1; > - state->hold += (unsigned)value << state->bits; > + state->hold += (unsigned long)value << state->bits; > state->bits += (uInt)bits; > return Z_OK; > } > > /* > - Return state with length and distance decoding tables and index sizes set to > - fixed code decoding. Normally this returns fixed tables from inffixed.h. > - If BUILDFIXED is defined, then instead this routine builds the tables the > - first time it's called, and returns those tables the first time and > - thereafter. This reduces the size of the code by about 2K bytes, in > - exchange for a little execution time. However, BUILDFIXED should not be > - used for threaded applications, since the rewriting of the tables and virgin > - may not be thread-safe. > - */ > -local void fixedtables(struct inflate_state FAR *state) { > -#ifdef BUILDFIXED > - static int virgin = 1; > - static code *lenfix, *distfix; > - static code fixed[544]; > - > - /* build fixed huffman tables if first call (may not be thread safe) */ > - if (virgin) { > - unsigned sym, bits; > - static code *next; > - > - /* literal/length table */ > - sym = 0; > - while (sym < 144) state->lens[sym++] = 8; > - while (sym < 256) state->lens[sym++] = 9; > - while (sym < 280) state->lens[sym++] = 7; > - while (sym < 288) state->lens[sym++] = 8; > - next = fixed; > - lenfix = next; > - bits = 9; > - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); > - > - /* distance table */ > - sym = 0; > - while (sym < 32) state->lens[sym++] = 5; > - distfix = next; > - bits = 5; > - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); > - > - /* do this just once */ > - virgin = 0; > - } > -#else /* !BUILDFIXED */ > -# include "inffixed.h" > -#endif /* BUILDFIXED */ > - state->lencode = lenfix; > - state->lenbits = 9; > - state->distcode = distfix; > - state->distbits = 5; > -} > - > -#ifdef MAKEFIXED > -#include > - > -/* > - Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also > - defines BUILDFIXED, so the tables are built on the fly. makefixed() writes > - those tables to stdout, which would be piped to inffixed.h. A small program > - can simply call makefixed to do this: > - > - void makefixed(void); > - > - int main(void) > - { > - makefixed(); > - return 0; > - } > - > - Then that can be linked with zlib built with MAKEFIXED defined and run: > - > - a.out > inffixed.h > - */ > -void makefixed(void) > -{ > - unsigned low, size; > - struct inflate_state state; > - > - fixedtables(&state); > - puts(" /* inffixed.h -- table for decoding fixed codes"); > - puts(" * Generated automatically by makefixed()."); > - puts(" */"); > - puts(""); > - puts(" /* WARNING: this file should *not* be used by applications."); > - puts(" It is part of the implementation of this library and is"); > - puts(" subject to change. Applications should only use zlib.h."); > - puts(" */"); > - puts(""); > - size = 1U << 9; > - printf(" static const code lenfix[%u] = {", size); > - low = 0; > - for (;;) { > - if ((low % 7) == 0) printf("\n "); > - printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, > - state.lencode[low].bits, state.lencode[low].val); > - if (++low == size) break; > - putchar(','); > - } > - puts("\n };"); > - size = 1U << 5; > - printf("\n static const code distfix[%u] = {", size); > - low = 0; > - for (;;) { > - if ((low % 6) == 0) printf("\n "); > - printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, > - state.distcode[low].val); > - if (++low == size) break; > - putchar(','); > - } > - puts("\n };"); > -} > -#endif /* MAKEFIXED */ > - > -/* > Update the window with the last wsize (normally 32K) bytes written before > returning. If window does not exist yet, create it. This is only called > when a window is already in use, or when output has been written during this > @@ -865,7 +748,7 @@ int ZEXPORT inflate(z_streamp strm, int > state->mode = STORED; > break; > case 1: /* fixed block */ > - fixedtables(state); > + inflate_fixed(state); > Tracev((stderr, "inflate: fixed codes block%s\n", > state->last ? " (last)" : "")); > state->mode = LEN_; /* decode codes */ > @@ -879,7 +762,7 @@ int ZEXPORT inflate(z_streamp strm, int > state->last ? " (last)" : "")); > state->mode = TABLE; > break; > - case 3: > + default: > #ifdef SMALL > strm->msg = (z_const char *)"error"; > #else > @@ -941,7 +824,8 @@ int ZEXPORT inflate(z_streamp strm, int > #ifdef SMALL > strm->msg = (z_const char *)"error"; > #else > - strm->msg = (z_const char *)"too many length or distance symbols"; > + strm->msg = (z_const char *) > + "too many length or distance symbols"; > #endif > state->mode = BAD; > break; > @@ -996,7 +880,8 @@ int ZEXPORT inflate(z_streamp strm, int > #ifdef SMALL > strm->msg = (z_const char *)"error"; > #else > - strm->msg = (z_const char *)"invalid bit length repeat"; > + strm->msg = (z_const char *) > + "invalid bit length repeat"; > #endif > state->mode = BAD; > break; > @@ -1023,7 +908,8 @@ int ZEXPORT inflate(z_streamp strm, int > #ifdef SMALL > strm->msg = (z_const char *)"error"; > #else > - strm->msg = (z_const char *)"invalid bit length repeat"; > + strm->msg = (z_const char *) > + "invalid bit length repeat"; > #endif > state->mode = BAD; > break; > @@ -1041,7 +927,8 @@ int ZEXPORT inflate(z_streamp strm, int > #ifdef SMALL > strm->msg = (z_const char *)"error"; > #else > - strm->msg = (z_const char *)"invalid code -- missing end-of-block"; > + strm->msg = (z_const char *) > + "invalid code -- missing end-of-block"; > #endif > state->mode = BAD; > break; > @@ -1214,7 +1101,8 @@ int ZEXPORT inflate(z_streamp strm, int > #ifdef SMALL > strm->msg = (z_const char *)"error"; > #else > - strm->msg = (z_const char *)"invalid distance too far back"; > + strm->msg = (z_const char *) > + "invalid distance too far back"; > #endif > state->mode = BAD; > break; > @@ -1549,8 +1437,8 @@ int ZEXPORT inflateCopy(z_streamp dest, > } > > /* copy state */ > - zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); > - zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); > + zmemcpy(dest, source, sizeof(z_stream)); > + zmemcpy(copy, state, sizeof(struct inflate_state)); > copy->strm = dest; > if (state->lencode >= state->codes && > state->lencode <= state->codes + ENOUGH - 1) { > Index: sys/lib/libz/inftrees.c > =================================================================== > RCS file: /cvs/src/sys/lib/libz/inftrees.c,v > diff -u -p -r1.23 inftrees.c > --- sys/lib/libz/inftrees.c 23 Jan 2024 14:46:51 -0000 1.23 > +++ sys/lib/libz/inftrees.c 10 Mar 2026 06:44:20 -0000 > @@ -1,10 +1,24 @@ > /* inftrees.c -- generate Huffman trees for efficient decoding > - * Copyright (C) 1995-2024 Mark Adler > + * Copyright (C) 1995-2026 Mark Adler > * For conditions of distribution and use, see copyright notice in zlib.h > */ > > +#ifdef MAKEFIXED > +# ifndef BUILDFIXED > +# define BUILDFIXED > +# endif > +#endif > +#ifdef BUILDFIXED > +# define Z_ONCE > +#endif > + > #include "zutil.h" > #include "inftrees.h" > +#include "inflate.h" > + > +#ifndef NULL > +# define NULL 0 > +#endif > > #define MAXBITS 15 > > @@ -45,9 +59,9 @@ int ZLIB_INTERNAL inflate_table(codetype > unsigned mask; /* mask for low root bits */ > code here; /* table entry for duplication */ > code FAR *next; /* next available space in table */ > - const unsigned short FAR *base; /* base value table to use */ > - const unsigned short FAR *extra; /* extra bits table to use */ > - unsigned match; /* use base and extra for symbol >= match */ > + const unsigned short FAR *base = NULL; /* base value table to use */ > + const unsigned short FAR *extra = NULL; /* extra bits table to use */ > + unsigned match = 0; /* use base and extra for symbol >= match */ > unsigned short count[MAXBITS+1]; /* number of codes of each length */ > unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ > static const unsigned short lbase[31] = { /* Length codes 257..285 base */ > @@ -55,7 +69,7 @@ int ZLIB_INTERNAL inflate_table(codetype > 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; > static const unsigned short lext[31] = { /* Length codes 257..285 extra */ > 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, > - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 73, 200}; > + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 199, 75}; > static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ > 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, > 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, > @@ -173,7 +187,6 @@ int ZLIB_INTERNAL inflate_table(codetype > /* set up for code type */ > switch (type) { > case CODES: > - base = extra = work; /* dummy value--not used */ > match = 20; > break; > case LENS: > @@ -181,10 +194,9 @@ int ZLIB_INTERNAL inflate_table(codetype > extra = lext; > match = 257; > break; > - default: /* DISTS */ > + case DISTS: > base = dbase; > extra = dext; > - match = 0; > } > > /* initialize state for loop */ > @@ -295,3 +307,116 @@ int ZLIB_INTERNAL inflate_table(codetype > *bits = root; > return 0; > } > + > +#ifdef BUILDFIXED > +/* > + If this is compiled with BUILDFIXED defined, and if inflate will be used in > + multiple threads, and if atomics are not available, then inflate() must be > + called with a fixed block (e.g. 0x03 0x00) to initialize the tables and must > + return before any other threads are allowed to call inflate. > + */ > + > +static code *lenfix, *distfix; > +static code fixed[544]; > + > +/* State for z_once(). */ > +local z_once_t built = Z_ONCE_INIT; > + > +local void buildtables(void) { > + unsigned sym, bits; > + static code *next; > + unsigned short lens[288], work[288]; > + > + /* literal/length table */ > + sym = 0; > + while (sym < 144) lens[sym++] = 8; > + while (sym < 256) lens[sym++] = 9; > + while (sym < 280) lens[sym++] = 7; > + while (sym < 288) lens[sym++] = 8; > + next = fixed; > + lenfix = next; > + bits = 9; > + inflate_table(LENS, lens, 288, &(next), &(bits), work); > + > + /* distance table */ > + sym = 0; > + while (sym < 32) lens[sym++] = 5; > + distfix = next; > + bits = 5; > + inflate_table(DISTS, lens, 32, &(next), &(bits), work); > +} > +#else /* !BUILDFIXED */ > +# include "inffixed.h" > +#endif /* BUILDFIXED */ > + > +/* > + Return state with length and distance decoding tables and index sizes set to > + fixed code decoding. Normally this returns fixed tables from inffixed.h. > + If BUILDFIXED is defined, then instead this routine builds the tables the > + first time it's called, and returns those tables the first time and > + thereafter. This reduces the size of the code by about 2K bytes, in > + exchange for a little execution time. However, BUILDFIXED should not be > + used for threaded applications if atomics are not available, as it will > + not be thread-safe. > + */ > +void inflate_fixed(struct inflate_state FAR *state) { > +#ifdef BUILDFIXED > + z_once(&built, buildtables); > +#endif /* BUILDFIXED */ > + state->lencode = lenfix; > + state->lenbits = 9; > + state->distcode = distfix; > + state->distbits = 5; > +} > + > +#ifdef MAKEFIXED > +#include > + > +/* > + Write out the inffixed.h that will be #include'd above. Defining MAKEFIXED > + also defines BUILDFIXED, so the tables are built on the fly. main() writes > + those tables to stdout, which would directed to inffixed.h. Compile this > + along with zutil.c: > + > + cc -DMAKEFIXED -o fix inftrees.c zutil.c > + ./fix > inffixed.h > + */ > +int main(void) { > + unsigned low, size; > + struct inflate_state state; > + > + inflate_fixed(&state); > + puts("/* inffixed.h -- table for decoding fixed codes"); > + puts(" * Generated automatically by makefixed()."); > + puts(" */"); > + puts(""); > + puts("/* WARNING: this file should *not* be used by applications."); > + puts(" It is part of the implementation of this library and is"); > + puts(" subject to change. Applications should only use zlib.h."); > + puts(" */"); > + puts(""); > + size = 1U << 9; > + printf("static const code lenfix[%u] = {", size); > + low = 0; > + for (;;) { > + if ((low % 7) == 0) printf("\n "); > + printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, > + state.lencode[low].bits, state.lencode[low].val); > + if (++low == size) break; > + putchar(','); > + } > + puts("\n};"); > + size = 1U << 5; > + printf("\nstatic const code distfix[%u] = {", size); > + low = 0; > + for (;;) { > + if ((low % 6) == 0) printf("\n "); > + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, > + state.distcode[low].val); > + if (++low == size) break; > + putchar(','); > + } > + puts("\n};"); > + return 0; > +} > +#endif /* MAKEFIXED */ > Index: sys/lib/libz/inftrees.h > =================================================================== > RCS file: /cvs/src/sys/lib/libz/inftrees.h,v > diff -u -p -r1.14 inftrees.h > --- sys/lib/libz/inftrees.h 18 Nov 2023 22:43:56 -0000 1.14 > +++ sys/lib/libz/inftrees.h 10 Mar 2026 06:44:20 -0000 > @@ -1,5 +1,5 @@ > /* inftrees.h -- header to use inftrees.c > - * Copyright (C) 1995-2005, 2010 Mark Adler > + * Copyright (C) 1995-2026 Mark Adler > * For conditions of distribution and use, see copyright notice in zlib.h > */ > > @@ -60,3 +60,5 @@ typedef enum { > int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, > unsigned codes, code FAR * FAR *table, > unsigned FAR *bits, unsigned short FAR *work); > +struct inflate_state; > +void ZLIB_INTERNAL inflate_fixed(struct inflate_state FAR *state); > Index: sys/lib/libz/trees.c > =================================================================== > RCS file: /cvs/src/sys/lib/libz/trees.c,v > diff -u -p -r1.14 trees.c > --- sys/lib/libz/trees.c 1 Aug 2024 04:03:10 -0000 1.14 > +++ sys/lib/libz/trees.c 10 Mar 2026 06:44:20 -0000 > @@ -1,5 +1,5 @@ > /* trees.c -- output deflated data using Huffman coding > - * Copyright (C) 1995-2024 Jean-loup Gailly > + * Copyright (C) 1995-2026 Jean-loup Gailly > * detect_data_type() function provided freely by Cosmin Truta, 2006 > * For conditions of distribution and use, see copyright notice in zlib.h > */ > @@ -110,7 +110,7 @@ local int base_dist[D_CODES]; > > #else > # include "trees.h" > -#endif /* GEN_TREES_H */ > +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ > > struct static_tree_desc_s { > const ct_data *static_tree; /* static tree or NULL */ > @@ -150,7 +150,7 @@ local TCONST static_tree_desc static_bl_ > * IN assertion: 1 <= len <= 15 > */ > local unsigned bi_reverse(unsigned code, int len) { > - register unsigned res = 0; > + unsigned res = 0; > do { > res |= code & 1; > code >>= 1, res <<= 1; > @@ -186,7 +186,7 @@ local void bi_windup(deflate_state *s) { > s->bi_buf = 0; > s->bi_valid = 0; > #ifdef ZLIB_DEBUG > - s->bits_sent = (s->bits_sent + 7) & ~7; > + s->bits_sent = (s->bits_sent + 7) & ~(ulg)7; > #endif > } > > @@ -817,7 +817,7 @@ local int build_bl_tree(deflate_state *s > } > /* Update opt_len to include the bit length tree and counts */ > s->opt_len += 3*((ulg)max_blindex + 1) + 5 + 5 + 4; > - Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", > + Tracev((stderr, "\ndyn trees: dyn %lu, stat %lu", > s->opt_len, s->static_len)); > > return max_blindex; > @@ -843,13 +843,13 @@ local void send_all_trees(deflate_state > Tracev((stderr, "\nbl code %2d ", bl_order[rank])); > send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); > } > - Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); > + Tracev((stderr, "\nbl tree: sent %lu", s->bits_sent)); > > send_tree(s, (ct_data *)s->dyn_ltree, lcodes - 1); /* literal tree */ > - Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); > + Tracev((stderr, "\nlit tree: sent %lu", s->bits_sent)); > > send_tree(s, (ct_data *)s->dyn_dtree, dcodes - 1); /* distance tree */ > - Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); > + Tracev((stderr, "\ndist tree: sent %lu", s->bits_sent)); > } > > /* =========================================================================== > @@ -932,7 +932,7 @@ local void compress_block(deflate_state > extra = extra_dbits[code]; > if (extra != 0) { > dist -= (unsigned)base_dist[code]; > - send_bits(s, dist, extra); /* send the extra distance bits */ > + send_bits(s, (int)dist, extra); /* send the extra bits */ > } > } /* literal or match pair ? */ > > @@ -1006,11 +1006,11 @@ void ZLIB_INTERNAL _tr_flush_block(defla > > /* Construct the literal and distance trees */ > build_tree(s, (tree_desc *)(&(s->l_desc))); > - Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, > + Tracev((stderr, "\nlit data: dyn %lu, stat %lu", s->opt_len, > s->static_len)); > > build_tree(s, (tree_desc *)(&(s->d_desc))); > - Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, > + Tracev((stderr, "\ndist data: dyn %lu, stat %lu", s->opt_len, > s->static_len)); > /* At this point, opt_len and static_len are the total bit lengths of > * the compressed block data, excluding the tree representations. > @@ -1083,7 +1083,7 @@ void ZLIB_INTERNAL _tr_flush_block(defla > #endif > } > Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len >> 3, > - s->compressed_len - 7*last)); > + s->compressed_len - 7*(ulg)last)); > } > > /* =========================================================================== > Index: sys/lib/libz/zconf.h > =================================================================== > RCS file: /cvs/src/sys/lib/libz/zconf.h,v > diff -u -p -r1.27 zconf.h > --- sys/lib/libz/zconf.h 19 Feb 2025 12:15:09 -0000 1.27 > +++ sys/lib/libz/zconf.h 10 Mar 2026 06:44:24 -0000 > @@ -1,5 +1,5 @@ > /* zconf.h -- configuration of the zlib compression library > - * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler > + * Copyright (C) 1995-2026 Jean-loup Gailly, Mark Adler > * For conditions of distribution and use, see copyright notice in zlib.h > */ > > @@ -31,7 +31,10 @@ > # ifndef Z_SOLO > # define compress z_compress > # define compress2 z_compress2 > +# define compress_z z_compress_z > +# define compress2_z z_compress2_z > # define compressBound z_compressBound > +# define compressBound_z z_compressBound_z > # endif > # define crc32 z_crc32 > # define crc32_combine z_crc32_combine > @@ -42,6 +45,7 @@ > # define crc32_z z_crc32_z > # define deflate z_deflate > # define deflateBound z_deflateBound > +# define deflateBound_z z_deflateBound_z > # define deflateCopy z_deflateCopy > # define deflateEnd z_deflateEnd > # define deflateGetDictionary z_deflateGetDictionary > @@ -127,9 +131,12 @@ > # define inflate_copyright z_inflate_copyright > # define inflate_fast z_inflate_fast > # define inflate_table z_inflate_table > +# define inflate_fixed z_inflate_fixed > # ifndef Z_SOLO > # define uncompress z_uncompress > # define uncompress2 z_uncompress2 > +# define uncompress_z z_uncompress_z > +# define uncompress2_z z_uncompress2_z > # endif > # define zError z_zError > # ifndef Z_SOLO > @@ -436,6 +443,7 @@ typedef uLong FAR uLongf; > > #ifdef _KERNEL > # define Z_HAVE_UNISTD_H > +# include > #endif > #ifdef _STANDALONE > # define z_off_t long > Index: sys/lib/libz/zlib.h > =================================================================== > RCS file: /cvs/src/sys/lib/libz/zlib.h,v > diff -u -p -r1.33 zlib.h > --- sys/lib/libz/zlib.h 4 Mar 2026 05:44:56 -0000 1.33 > +++ sys/lib/libz/zlib.h 10 Mar 2026 06:44:20 -0000 > @@ -1,7 +1,7 @@ > /* zlib.h -- interface of the 'zlib' general purpose compression library > - version 1.3.1.1, January xxth, 2024 > + version 1.3.2, February 17th, 2026 > > - Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler > + Copyright (C) 1995-2026 Jean-loup Gailly and Mark Adler > > This software is provided 'as-is', without any express or implied > warranty. In no event will the authors be held liable for any damages > @@ -24,7 +24,7 @@ > > > The data format used by the zlib library is described by RFCs (Request for > - Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 > + Comments) 1950 to 1952 at https://datatracker.ietf.org/doc/html/rfc1950 > (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). > */ > > @@ -41,12 +41,12 @@ > extern "C" { > #endif > > -#define ZLIB_VERSION "1.3.1.1-motley" > -#define ZLIB_VERNUM 0x1311 > +#define ZLIB_VERSION "1.3.2" > +#define ZLIB_VERNUM 0x1320 > #define ZLIB_VER_MAJOR 1 > #define ZLIB_VER_MINOR 3 > -#define ZLIB_VER_REVISION 1 > -#define ZLIB_VER_SUBREVISION 1 > +#define ZLIB_VER_REVISION 2 > +#define ZLIB_VER_SUBREVISION 0 > > /* > The 'zlib' compression library provides in-memory compression and > @@ -445,7 +445,7 @@ ZEXTERN int ZEXPORT inflate(z_streamp st > > The Z_BLOCK option assists in appending to or combining deflate streams. > To assist in this, on return inflate() always sets strm->data_type to the > - number of unused bits in the last byte taken from strm->next_in, plus 64 if > + number of unused bits in the input taken from strm->next_in, plus 64 if > inflate() is currently decoding the last block in the deflate stream, plus > 128 if inflate() returned immediately after decoding an end-of-block code or > decoding the complete header up to just before the first byte of the deflate > @@ -765,8 +765,8 @@ ZEXTERN int ZEXPORT deflateTune(z_stream > returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. > */ > > -ZEXTERN uLong ZEXPORT deflateBound(z_streamp strm, > - uLong sourceLen); > +ZEXTERN uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen); > +ZEXTERN z_size_t ZEXPORT deflateBound_z(z_streamp strm, z_size_t sourceLen); > /* > deflateBound() returns an upper bound on the compressed size after > deflation of sourceLen bytes. It must be called after deflateInit() or > @@ -778,6 +778,9 @@ ZEXTERN uLong ZEXPORT deflateBound(z_str > to return Z_STREAM_END. Note that it is possible for the compressed size to > be larger than the value returned by deflateBound() if flush options other > than Z_FINISH or Z_NO_FLUSH are used. > + > + delfateBound_z() is the same, but takes and returns a size_t length. Note > + that a long is 32 bits on Windows. > */ > > ZEXTERN int ZEXPORT deflatePending(z_streamp strm, > @@ -792,7 +795,10 @@ ZEXTERN int ZEXPORT deflatePending(z_str > or bits are Z_NULL, then those values are not set. > > deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source > - stream state was inconsistent. > + stream state was inconsistent. If an int is 16 bits and memLevel is 9, then > + it is possible for the number of pending bytes to not fit in an unsigned. In > + that case Z_BUF_ERROR is returned and *pending is set to the maximum value > + of an unsigned. > */ > > ZEXTERN int ZEXPORT deflateUsed(z_streamp strm, > @@ -1006,13 +1012,15 @@ ZEXTERN int ZEXPORT inflatePrime(z_strea > int bits, > int value); > /* > - This function inserts bits in the inflate input stream. The intent is > - that this function is used to start inflating at a bit position in the > - middle of a byte. The provided bits will be used before any bytes are used > - from next_in. This function should only be used with raw inflate, and > - should be used before the first inflate() call after inflateInit2() or > - inflateReset(). bits must be less than or equal to 16, and that many of the > - least significant bits of value will be inserted in the input. > + This function inserts bits in the inflate input stream. The intent is to > + use inflatePrime() to start inflating at a bit position in the middle of a > + byte. The provided bits will be used before any bytes are used from > + next_in. This function should be used with raw inflate, before the first > + inflate() call, after inflateInit2() or inflateReset(). It can also be used > + after an inflate() return indicates the end of a deflate block or header > + when using Z_BLOCK. bits must be less than or equal to 16, and that many of > + the least significant bits of value will be inserted in the input. The > + other bits in value can be non-zero, and will be ignored. > > If bits is negative, then the input stream bit buffer is emptied. Then > inflatePrime() can be called again to put bits in the buffer. This is used > @@ -1020,7 +1028,15 @@ ZEXTERN int ZEXPORT inflatePrime(z_strea > to feeding inflate codes. > > inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source > - stream state was inconsistent. > + stream state was inconsistent, or if bits is out of range. If inflate was > + in the middle of processing a header, trailer, or stored block lengths, then > + it is possible for there to be only eight bits available in the bit buffer. > + In that case, bits > 8 is considered out of range. However, when used as > + outlined above, there will always be 16 bits available in the buffer for > + insertion. As noted in its documentation above, inflate records the number > + of bits in the bit buffer on return in data_type. 32 minus that is the > + number of bits available for insertion. inflatePrime does not update > + data_type with the new number of bits in buffer. > */ > > ZEXTERN long ZEXPORT inflateMark(z_streamp strm); > @@ -1066,20 +1082,22 @@ ZEXTERN int ZEXPORT inflateGetHeader(z_s > > The text, time, xflags, and os fields are filled in with the gzip header > contents. hcrc is set to true if there is a header CRC. (The header CRC > - was valid if done is set to one.) If extra is not Z_NULL, then extra_max > - contains the maximum number of bytes to write to extra. Once done is true, > - extra_len contains the actual extra field length, and extra contains the > - extra field, or that field truncated if extra_max is less than extra_len. > - If name is not Z_NULL, then up to name_max characters are written there, > - terminated with a zero unless the length is greater than name_max. If > - comment is not Z_NULL, then up to comm_max characters are written there, > - terminated with a zero unless the length is greater than comm_max. When any > - of extra, name, or comment are not Z_NULL and the respective field is not > - present in the header, then that field is set to Z_NULL to signal its > - absence. This allows the use of deflateSetHeader() with the returned > - structure to duplicate the header. However if those fields are set to > - allocated memory, then the application will need to save those pointers > - elsewhere so that they can be eventually freed. > + was valid if done is set to one.) The extra, name, and comment pointers > + much each be either Z_NULL or point to space to store that information from > + the header. If extra is not Z_NULL, then extra_max contains the maximum > + number of bytes that can be written to extra. Once done is true, extra_len > + contains the actual extra field length, and extra contains the extra field, > + or that field truncated if extra_max is less than extra_len. If name is not > + Z_NULL, then up to name_max characters, including the terminating zero, are > + written there. If comment is not Z_NULL, then up to comm_max characters, > + including the terminating zero, are written there. The application can tell > + that the name or comment did not fit in the provided space by the absence of > + a terminating zero. If any of extra, name, or comment are not present in > + the header, then that field's pointer is set to Z_NULL. This allows the use > + of deflateSetHeader() with the returned structure to duplicate the header. > + Note that if those fields initially pointed to allocated memory, then the > + application will need to save them elsewhere so that they can be eventually > + freed. > > If inflateGetHeader is not used, then the header information is simply > discarded. The header is always checked for validity, including the header > @@ -1227,13 +1245,14 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags(v > 21: FASTEST -- deflate algorithm with only one, lowest compression level > 22,23: 0 (reserved) > > - The sprintf variant used by gzprintf (zero is best): > + The sprintf variant used by gzprintf (all zeros is best): > 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format > - 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! > + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() is not secure! > 26: 0 = returns value, 1 = void -- 1 means inferred string length returned > + 27: 0 = gzprintf() present, 1 = not -- 1 means gzprintf() returns an error > > Remainder: > - 27-31: 0 (reserved) > + 28-31: 0 (reserved) > */ > > #ifndef Z_SOLO > @@ -1245,11 +1264,14 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags(v > stream-oriented functions. To simplify the interface, some default options > are assumed (compression level and memory usage, standard memory allocation > functions). The source code of these utility functions can be modified if > - you need special options. > + you need special options. The _z versions of the functions use the size_t > + type for lengths. Note that a long is 32 bits on Windows. > */ > > -ZEXTERN int ZEXPORT compress(Bytef *dest, uLongf *destLen, > +ZEXTERN int ZEXPORT compress(Bytef *dest, uLongf *destLen, > const Bytef *source, uLong sourceLen); > +ZEXTERN int ZEXPORT compress_z(Bytef *dest, z_size_t *destLen, > + const Bytef *source, z_size_t sourceLen); > /* > Compresses the source buffer into the destination buffer. sourceLen is > the byte length of the source buffer. Upon entry, destLen is the total size > @@ -1263,9 +1285,12 @@ ZEXTERN int ZEXPORT compress(Bytef *dest > buffer. > */ > > -ZEXTERN int ZEXPORT compress2(Bytef *dest, uLongf *destLen, > +ZEXTERN int ZEXPORT compress2(Bytef *dest, uLongf *destLen, > const Bytef *source, uLong sourceLen, > int level); > +ZEXTERN int ZEXPORT compress2_z(Bytef *dest, z_size_t *destLen, > + const Bytef *source, z_size_t sourceLen, > + int level); > /* > Compresses the source buffer into the destination buffer. The level > parameter has the same meaning as in deflateInit. sourceLen is the byte > @@ -1280,21 +1305,24 @@ ZEXTERN int ZEXPORT compress2(Bytef *des > */ > > ZEXTERN uLong ZEXPORT compressBound(uLong sourceLen); > +ZEXTERN z_size_t ZEXPORT compressBound_z(z_size_t sourceLen); > /* > compressBound() returns an upper bound on the compressed size after > compress() or compress2() on sourceLen bytes. It would be used before a > compress() or compress2() call to allocate the destination buffer. > */ > > -ZEXTERN int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, > +ZEXTERN int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, > const Bytef *source, uLong sourceLen); > +ZEXTERN int ZEXPORT uncompress_z(Bytef *dest, z_size_t *destLen, > + const Bytef *source, z_size_t sourceLen); > /* > Decompresses the source buffer into the destination buffer. sourceLen is > - the byte length of the source buffer. Upon entry, destLen is the total size > + the byte length of the source buffer. On entry, *destLen is the total size > of the destination buffer, which must be large enough to hold the entire > uncompressed data. (The size of the uncompressed data must have been saved > previously by the compressor and transmitted to the decompressor by some > - mechanism outside the scope of this compression library.) Upon exit, destLen > + mechanism outside the scope of this compression library.) On exit, *destLen > is the actual size of the uncompressed data. > > uncompress returns Z_OK if success, Z_MEM_ERROR if there was not > @@ -1304,8 +1332,10 @@ ZEXTERN int ZEXPORT uncompress(Bytef *de > buffer with the uncompressed data up to that point. > */ > > -ZEXTERN int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, > +ZEXTERN int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, > const Bytef *source, uLong *sourceLen); > +ZEXTERN int ZEXPORT uncompress2_z(Bytef *dest, z_size_t *destLen, > + const Bytef *source, z_size_t *sourceLen); > /* > Same as uncompress, except that sourceLen is a pointer, where the > length of the source is *sourceLen. On return, *sourceLen is the number of > @@ -1333,13 +1363,17 @@ ZEXTERN gzFile ZEXPORT gzopen(const char > 'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression > as in "wb9F". (See the description of deflateInit2 for more information > about the strategy parameter.) 'T' will request transparent writing or > - appending with no compression and not using the gzip format. > + appending with no compression and not using the gzip format. 'T' cannot be > + used to force transparent reading. Transparent reading is automatically > + performed if there is no gzip header at the start. Transparent reading can > + be disabled with the 'G' option, which will instead return an error if there > + is no gzip header. 'N' will open the file in non-blocking mode. > > - "a" can be used instead of "w" to request that the gzip stream that will > - be written be appended to the file. "+" will result in an error, since > + 'a' can be used instead of 'w' to request that the gzip stream that will > + be written be appended to the file. '+' will result in an error, since > reading and writing to the same gzip file is not supported. The addition of > - "x" when writing will create the file exclusively, which fails if the file > - already exists. On systems that support it, the addition of "e" when > + 'x' when writing will create the file exclusively, which fails if the file > + already exists. On systems that support it, the addition of 'e' when > reading or writing will set the flag to close the file on an execve() call. > > These functions, as well as gzip, will read and decode a sequence of gzip > @@ -1358,14 +1392,22 @@ ZEXTERN gzFile ZEXPORT gzopen(const char > insufficient memory to allocate the gzFile state, or if an invalid mode was > specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). > errno can be checked to determine if the reason gzopen failed was that the > - file could not be opened. > + file could not be opened. Note that if 'N' is in mode for non-blocking, the > + open() itself can fail in order to not block. In that case gzopen() will > + return NULL and errno will be EAGAIN or ENONBLOCK. The call to gzopen() can > + then be re-tried. If the application would like to block on opening the > + file, then it can use open() without O_NONBLOCK, and then gzdopen() with the > + resulting file descriptor and 'N' in the mode, which will set it to non- > + blocking. > */ > > ZEXTERN gzFile ZEXPORT gzdopen(int fd, const char *mode); > /* > Associate a gzFile with the file descriptor fd. File descriptors are > obtained from calls like open, dup, creat, pipe or fileno (if the file has > - been previously opened with fopen). The mode parameter is as in gzopen. > + been previously opened with fopen). The mode parameter is as in gzopen. An > + 'e' in mode will set fd's flag to close the file on an execve() call. An 'N' > + in mode will set fd's non-blocking flag. > > The next call of gzclose on the returned gzFile will also close the file > descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor > @@ -1435,10 +1477,16 @@ ZEXTERN int ZEXPORT gzread(gzFile file, > stream. Alternatively, gzerror can be used before gzclose to detect this > case. > > + gzread can be used to read a gzip file on a non-blocking device. If the > + input stalls and there is no uncompressed data to return, then gzread() will > + return -1, and errno will be EAGAIN or EWOULDBLOCK. gzread() can then be > + called again. > + > gzread returns the number of uncompressed bytes actually read, less than > len for end of file, or -1 for error. If len is too large to fit in an int, > then nothing is read, -1 is returned, and the error state is set to > - Z_STREAM_ERROR. > + Z_STREAM_ERROR. If some data was read before an error, then that data is > + returned until exhausted, after which the next call will signal the error. > */ > > ZEXTERN z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, > @@ -1462,15 +1510,20 @@ ZEXTERN z_size_t ZEXPORT gzfread(voidp b > multiple of size, then the final partial item is nevertheless read into buf > and the end-of-file flag is set. The length of the partial item read is not > provided, but could be inferred from the result of gztell(). This behavior > - is the same as the behavior of fread() implementations in common libraries, > - but it prevents the direct use of gzfread() to read a concurrently written > - file, resetting and retrying on end-of-file, when size is not 1. > + is the same as that of fread() implementations in common libraries. This > + could result in data loss if used with size != 1 when reading a concurrently > + written file or a non-blocking file. In that case, use size == 1 or gzread() > + instead. > */ > > ZEXTERN int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len); > /* > Compress and write the len uncompressed bytes at buf to file. gzwrite > - returns the number of uncompressed bytes written or 0 in case of error. > + returns the number of uncompressed bytes written, or 0 in case of error or > + if len is 0. If the write destination is non-blocking, then gzwrite() may > + return a number of bytes written that is not 0 and less than len. > + > + If len does not fit in an int, then 0 is returned and nothing is written. > */ > > ZEXTERN z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, > @@ -1485,9 +1538,18 @@ ZEXTERN z_size_t ZEXPORT gzfwrite(voidpc > if there was an error. If the multiplication of size and nitems overflows, > i.e. the product does not fit in a z_size_t, then nothing is written, zero > is returned, and the error state is set to Z_STREAM_ERROR. > + > + If writing a concurrently read file or a non-blocking file with size != 1, > + a partial item could be written, with no way of knowing how much of it was > + not written, resulting in data loss. In that case, use size == 1 or > + gzwrite() instead. > */ > > +#if defined(STDC) || defined(Z_HAVE_STDARG_H) > ZEXTERN int ZEXPORTVA gzprintf(gzFile file, const char *format, ...); > +#else > +ZEXTERN int ZEXPORTVA gzprintf(); > +#endif > /* > Convert, format, compress, and write the arguments (...) to file under > control of the string format, as in fprintf. gzprintf returns the number of > @@ -1495,11 +1557,19 @@ ZEXTERN int ZEXPORTVA gzprintf(gzFile fi > of error. The number of uncompressed bytes written is limited to 8191, or > one less than the buffer size given to gzbuffer(). The caller should assure > that this limit is not exceeded. If it is exceeded, then gzprintf() will > - return an error (0) with nothing written. In this case, there may also be a > - buffer overflow with unpredictable consequences, which is possible only if > - zlib was compiled with the insecure functions sprintf() or vsprintf(), > - because the secure snprintf() or vsnprintf() functions were not available. > - This can be determined using zlibCompileFlags(). > + return an error (0) with nothing written. > + > + In that last case, there may also be a buffer overflow with unpredictable > + consequences, which is possible only if zlib was compiled with the insecure > + functions sprintf() or vsprintf(), because the secure snprintf() and > + vsnprintf() functions were not available. That would only be the case for > + a non-ANSI C compiler. zlib may have been built without gzprintf() because > + secure functions were not available and having gzprintf() be insecure was > + not an option, in which case, gzprintf() returns Z_STREAM_ERROR. All of > + these possibilities can be determined using zlibCompileFlags(). > + > + If a Z_BUF_ERROR is returned, then nothing was written due to a stall on > + the non-blocking write destination. > */ > > ZEXTERN int ZEXPORT gzputs(gzFile file, const char *s); > @@ -1508,6 +1578,11 @@ ZEXTERN int ZEXPORT gzputs(gzFile file, > the terminating null character. > > gzputs returns the number of characters written, or -1 in case of error. > + The number of characters written may be less than the length of the string > + if the write destination is non-blocking. > + > + If the length of the string does not fit in an int, then -1 is returned > + and nothing is written. > */ > > ZEXTERN char * ZEXPORT gzgets(gzFile file, char *buf, int len); > @@ -1520,8 +1595,13 @@ ZEXTERN char * ZEXPORT gzgets(gzFile fil > left untouched. > > gzgets returns buf which is a null-terminated string, or it returns NULL > - for end-of-file or in case of error. If there was an error, the contents at > - buf are indeterminate. > + for end-of-file or in case of error. If some data was read before an error, > + then that data is returned until exhausted, after which the next call will > + return NULL to signal the error. > + > + gzgets can be used on a file being concurrently written, and on a non- > + blocking device, both as for gzread(). However lines may be broken in the > + middle, leaving it up to the application to reassemble them as needed. > */ > > ZEXTERN int ZEXPORT gzputc(gzFile file, int c); > @@ -1532,11 +1612,19 @@ ZEXTERN int ZEXPORT gzputc(gzFile file, > > ZEXTERN int ZEXPORT gzgetc(gzFile file); > /* > - Read and decompress one byte from file. gzgetc returns this byte or -1 > - in case of end of file or error. This is implemented as a macro for speed. > - As such, it does not do all of the checking the other functions do. I.e. > - it does not check to see if file is NULL, nor whether the structure file > - points to has been clobbered or not. > + Read and decompress one byte from file. gzgetc returns this byte or -1 in > + case of end of file or error. If some data was read before an error, then > + that data is returned until exhausted, after which the next call will return > + -1 to signal the error. > + > + This is implemented as a macro for speed. As such, it does not do all of > + the checking the other functions do. I.e. it does not check to see if file > + is NULL, nor whether the structure file points to has been clobbered or not. > + > + gzgetc can be used to read a gzip file on a non-blocking device. If the > + input stalls and there is no uncompressed data to return, then gzgetc() will > + return -1, and errno will be EAGAIN or EWOULDBLOCK. gzread() can then be > + called again. > */ > > ZEXTERN int ZEXPORT gzungetc(int c, gzFile file); > @@ -1549,6 +1637,11 @@ ZEXTERN int ZEXPORT gzungetc(int c, gzFi > output buffer size of pushed characters is allowed. (See gzbuffer above.) > The pushed character will be discarded if the stream is repositioned with > gzseek() or gzrewind(). > + > + gzungetc(-1, file) will force any pending seek to execute. Then gztell() > + will report the position, even if the requested seek reached end of file. > + This can be used to determine the number of uncompressed bytes in a gzip > + file without having to read it into a buffer. > */ > > ZEXTERN int ZEXPORT gzflush(gzFile file, int flush); > @@ -1578,7 +1671,8 @@ ZEXTERN z_off_t ZEXPORT gzseek(gzFile fi > If the file is opened for reading, this function is emulated but can be > extremely slow. If the file is opened for writing, only forward seeks are > supported; gzseek then compresses a sequence of zeroes up to the new > - starting position. > + starting position. For reading or writing, any actual seeking is deferred > + until the next read or write operation, or close operation when writing. > > gzseek returns the resulting offset location as measured in bytes from > the beginning of the uncompressed stream, or -1 in case of error, in > @@ -1586,7 +1680,7 @@ ZEXTERN z_off_t ZEXPORT gzseek(gzFile fi > would be before the current position. > */ > > -ZEXTERN int ZEXPORT gzrewind(gzFile file); > +ZEXTERN int ZEXPORT gzrewind(gzFile file); > /* > Rewind file. This function is supported only for reading. > > @@ -1594,7 +1688,7 @@ ZEXTERN int ZEXPORT gzrewind(gzFile f > */ > > /* > -ZEXTERN z_off_t ZEXPORT gztell(gzFile file); > +ZEXTERN z_off_t ZEXPORT gztell(gzFile file); > > Return the starting position for the next gzread or gzwrite on file. > This position represents a number of bytes in the uncompressed data stream, > @@ -1639,8 +1733,11 @@ ZEXTERN int ZEXPORT gzdirect(gzFile file > > If gzdirect() is used immediately after gzopen() or gzdopen() it will > cause buffers to be allocated to allow reading the file to determine if it > - is a gzip file. Therefore if gzbuffer() is used, it should be called before > - gzdirect(). > + is a gzip file. Therefore if gzbuffer() is used, it should be called before > + gzdirect(). If the input is being written concurrently or the device is non- > + blocking, then gzdirect() may give a different answer once four bytes of > + input have been accumulated, which is what is needed to confirm or deny a > + gzip header. Before this, gzdirect() will return true (1). > > When writing, gzdirect() returns true (1) if transparent writing was > requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: > @@ -1650,7 +1747,7 @@ ZEXTERN int ZEXPORT gzdirect(gzFile file > gzip file reading and decompression, which may not be desired.) > */ > > -ZEXTERN int ZEXPORT gzclose(gzFile file); > +ZEXTERN int ZEXPORT gzclose(gzFile file); > /* > Flush all pending output for file, if necessary, close file and > deallocate the (de)compression state. Note that once file is closed, you > @@ -1678,9 +1775,10 @@ ZEXTERN int ZEXPORT gzclose_w(gzFile fil > ZEXTERN const char * ZEXPORT gzerror(gzFile file, int *errnum); > /* > Return the error message for the last error which occurred on file. > - errnum is set to zlib error number. If an error occurred in the file system > - and not in the compression library, errnum is set to Z_ERRNO and the > - application may consult errno to get the exact error code. > + If errnum is not NULL, *errnum is set to zlib error number. If an error > + occurred in the file system and not in the compression library, *errnum is > + set to Z_ERRNO and the application may consult errno to get the exact error > + code. > > The application must not modify the returned string. Future calls to > this function may invalidate the previously returned string. If file is > @@ -1731,7 +1829,8 @@ ZEXTERN uLong ZEXPORT adler32(uLong adle > ZEXTERN uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, > z_size_t len); > /* > - Same as adler32(), but with a size_t length. > + Same as adler32(), but with a size_t length. Note that a long is 32 bits > + on Windows. > */ > > /* > @@ -1767,7 +1866,8 @@ ZEXTERN uLong ZEXPORT crc32(uLong crc, c > ZEXTERN uLong ZEXPORT crc32_z(uLong crc, const Bytef *buf, > z_size_t len); > /* > - Same as crc32(), but with a size_t length. > + Same as crc32(), but with a size_t length. Note that a long is 32 bits on > + Windows. > */ > > /* > Index: sys/lib/libz/zutil.c > =================================================================== > RCS file: /cvs/src/sys/lib/libz/zutil.c,v > diff -u -p -r1.7 zutil.c > --- sys/lib/libz/zutil.c 25 Apr 2023 16:59:57 -0000 1.7 > +++ sys/lib/libz/zutil.c 10 Mar 2026 06:44:20 -0000 > @@ -1,5 +1,5 @@ > /* zutil.c -- target dependent utility functions for the compression library > - * Copyright (C) 1995-2017 Jean-loup Gailly > + * Copyright (C) 1995-2026 Jean-loup Gailly > * For conditions of distribution and use, see copyright notice in zlib.h > */ > > @@ -87,28 +87,36 @@ uLong ZEXPORT zlibCompileFlags(void) { > flags += 1L << 21; > #endif > #if defined(STDC) || defined(Z_HAVE_STDARG_H) > -# ifdef NO_vsnprintf > - flags += 1L << 25; > -# ifdef HAS_vsprintf_void > - flags += 1L << 26; > -# endif > -# else > -# ifdef HAS_vsnprintf_void > - flags += 1L << 26; > -# endif > -# endif > +# ifdef NO_vsnprintf > +# ifdef ZLIB_INSECURE > + flags += 1L << 25; > +# else > + flags += 1L << 27; > +# endif > +# ifdef HAS_vsprintf_void > + flags += 1L << 26; > +# endif > +# else > +# ifdef HAS_vsnprintf_void > + flags += 1L << 26; > +# endif > +# endif > #else > flags += 1L << 24; > -# ifdef NO_snprintf > - flags += 1L << 25; > -# ifdef HAS_sprintf_void > - flags += 1L << 26; > -# endif > -# else > -# ifdef HAS_snprintf_void > - flags += 1L << 26; > -# endif > -# endif > +# ifdef NO_snprintf > +# ifdef ZLIB_INSECURE > + flags += 1L << 25; > +# else > + flags += 1L << 27; > +# endif > +# ifdef HAS_sprintf_void > + flags += 1L << 26; > +# endif > +# else > +# ifdef HAS_snprintf_void > + flags += 1L << 26; > +# endif > +# endif > #endif > return flags; > } > @@ -143,28 +151,34 @@ const char * ZEXPORT zError(int err) { > > #ifndef HAVE_MEMCPY > > -void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len) { > - if (len == 0) return; > - do { > - *dest++ = *source++; /* ??? to be unrolled */ > - } while (--len != 0); > +void ZLIB_INTERNAL zmemcpy(void FAR *dst, const void FAR *src, z_size_t n) { > + uchf *p = dst; > + const uchf *q = src; > + while (n) { > + *p++ = *q++; > + n--; > + } > } > > -int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len) { > - uInt j; > - > - for (j = 0; j < len; j++) { > - if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; > +int ZLIB_INTERNAL zmemcmp(const void FAR *s1, const void FAR *s2, z_size_t n) { > + const uchf *p = s1, *q = s2; > + while (n) { > + if (*p++ != *q++) > + return (int)p[-1] - (int)q[-1]; > + n--; > } > return 0; > } > > -void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len) { > +void ZLIB_INTERNAL zmemzero(void FAR *b, z_size_t len) { > + uchf *p = b; > if (len == 0) return; > - do { > - *dest++ = 0; /* ??? to be unrolled */ > - } while (--len != 0); > + while (len) { > + *p++ = 0; > + len--; > + } > } > + > #endif > > #ifndef Z_SOLO > Index: sys/lib/libz/zutil.h > =================================================================== > RCS file: /cvs/src/sys/lib/libz/zutil.h,v > diff -u -p -r1.34 zutil.h > --- sys/lib/libz/zutil.h 9 Nov 2024 21:52:06 -0000 1.34 > +++ sys/lib/libz/zutil.h 10 Mar 2026 06:44:30 -0000 > @@ -1,5 +1,5 @@ > /* zutil.h -- internal interface and configuration of the compression library > - * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler > + * Copyright (C) 1995-2026 Jean-loup Gailly, Mark Adler > * For conditions of distribution and use, see copyright notice in zlib.h > */ > > @@ -51,6 +51,10 @@ typedef long ptrdiff_t; > define "local" for the non-static meaning of "static", for readability > (compile with -Dlocal if your debugger can't find static symbols) */ > > +extern const char deflate_copyright[]; > +extern const char inflate_copyright[]; > +extern const char inflate9_copyright[]; > + > typedef unsigned char uch; > typedef uch FAR uchf; > typedef unsigned short ush; > @@ -229,9 +233,9 @@ extern z_const char * const z_errmsg[10] > # define zmemzero(dest, len) memset(dest, 0, len) > # endif > #else > - void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len); > - int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len); > - void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len); > + void ZLIB_INTERNAL zmemcpy(void FAR *, const void FAR *, z_size_t); > + int ZLIB_INTERNAL zmemcmp(const void FAR *, const void FAR *, z_size_t); > + void ZLIB_INTERNAL zmemzero(void FAR *, z_size_t); > #endif > > /* Diagnostic functions */ > @@ -269,5 +273,73 @@ extern z_const char * const z_errmsg[10] > /* Reverse the bytes in a 32-bit value */ > #define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ > (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) > + > +#ifdef Z_ONCE > +/* > + Create a local z_once() function depending on the availability of atomics. > + */ > + > +/* Check for the availability of atomics. */ > +#if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \ > + !defined(__STDC_NO_ATOMICS__) && !defined(SMALL) > + > +#include > +typedef struct { > + atomic_flag begun; > + atomic_int done; > +} z_once_t; > +#define Z_ONCE_INIT {ATOMIC_FLAG_INIT, 0} > + > +/* > + Run the provided init() function exactly once, even if multiple threads > + invoke once() at the same time. The state must be a once_t initialized with > + Z_ONCE_INIT. > + */ > +local void z_once(z_once_t *state, void (*init)(void)) { > + if (!atomic_load(&state->done)) { > + if (atomic_flag_test_and_set(&state->begun)) > + while (!atomic_load(&state->done)) > + ; > + else { > + init(); > + atomic_store(&state->done, 1); > + } > + } > +} > + > +#else /* no atomics */ > + > +typedef struct z_once_s { > + volatile int begun; > + volatile int done; > +} z_once_t; > +#define Z_ONCE_INIT {0, 0} > + > +/* Test and set. Alas, not atomic, but tries to limit the period of > + vulnerability. */ > +local int test_and_set(int volatile *flag) { > + int was; > + > + was = *flag; > + *flag = 1; > + return was; > +} > + > +/* Run the provided init() function once. This is not thread-safe. */ > +local void z_once(z_once_t *state, void (*init)(void)) { > + if (!state->done) { > + if (test_and_set(&state->begun)) > + while (!state->done) > + ; > + else { > + init(); > + state->done = 1; > + } > + } > +} > + > +#endif /* ?atomics */ > + > +#endif /* Z_ONCE */ > > #endif /* ZUTIL_H */ > >