From 90dcb64584267733bc51d8fb3495c7990fba05a5 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Thu, 5 Nov 2026 16:12:37 -0600 Subject: [PATCH] Update vendored zlib to 1.4 for security fixes Refresh the vendored dependency to upstream v1.4 to pick up its security and correctness fixes. Preserve the SDK symbol prefix and legacy build targets, align the CMake configuration with native Windows large-file support, and exercise 64-bit offset consumers on Windows. Files changed: cgmanifest.json zlib/CMakeLists.txt zlib/ChangeLog zlib/Makefile.in zlib/compress.c zlib/configure zlib/contrib/delphi/ZLib.pas zlib/contrib/dotzlib/DotZLib/UnitTests.cs zlib/contrib/infback9/inftree9.c zlib/contrib/minizip/CMakeLists.txt zlib/contrib/minizip/Makefile.am zlib/contrib/minizip/configure.ac zlib/contrib/minizip/crypt.h zlib/contrib/minizip/ioapi.h zlib/contrib/minizip/miniunz.c zlib/contrib/minizip/minizipConfig.cmake.in zlib/contrib/minizip/mztools.c zlib/contrib/minizip/skipset.h zlib/contrib/minizip/test/CMakeLists.txt zlib/contrib/minizip/test/add_subdirectory_exclude_test.cmake.in zlib/contrib/minizip/test/add_subdirectory_test.cmake.in zlib/contrib/minizip/test/find_package_no_components_test.cmake.in zlib/contrib/minizip/test/find_package_test.cmake.in zlib/contrib/minizip/test/find_package_wrong_components_test.cmake.in zlib/contrib/minizip/unzip.c zlib/contrib/minizip/unzip.h zlib/contrib/minizip/zip.c zlib/contrib/minizip/zip.h zlib/contrib/pascal/zlibpas.pas zlib/crc32.c zlib/deflate.c zlib/gzguts.h zlib/gzlib.c zlib/gzread.c zlib/gzwrite.c zlib/infback.c zlib/inflate.c zlib/inflate.h zlib/inftrees.c zlib/inftrees.h zlib/qnx/package.qpg zlib/test/infcover.c zlib/test/minigzip.c zlib/treebuild.xml zlib/trees.c zlib/uncompr.c zlib/win32/Makefile.msc zlib/win32/README-WIN32.txt zlib/zconf.h zlib/zconf.h.cmakein zlib/zconf.h.in zlib/zlib.3 zlib/zlib.3.pdf zlib/zlib.h zlib/zlib.pc.cmakein zlib/zutil.c Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 75db4712-f7f2-445b-bb95-9881e4c13228 --- cgmanifest.json | 2 +- zlib/CMakeLists.txt | 8 +- zlib/ChangeLog | 31 ++ zlib/Makefile.in | 16 +- zlib/compress.c | 4 +- zlib/configure | 43 +- zlib/contrib/delphi/ZLib.pas | 2 +- zlib/contrib/dotzlib/DotZLib/UnitTests.cs | 2 +- zlib/contrib/infback9/inftree9.c | 22 +- zlib/contrib/minizip/CMakeLists.txt | 407 +++++++++--------- zlib/contrib/minizip/Makefile.am | 3 +- zlib/contrib/minizip/configure.ac | 2 +- zlib/contrib/minizip/crypt.h | 23 +- zlib/contrib/minizip/ioapi.h | 2 +- zlib/contrib/minizip/miniunz.c | 106 +++-- zlib/contrib/minizip/minizipConfig.cmake.in | 42 +- zlib/contrib/minizip/mztools.c | 2 +- zlib/contrib/minizip/skipset.h | 243 ++++++----- zlib/contrib/minizip/test/CMakeLists.txt | 185 ++++---- .../add_subdirectory_exclude_test.cmake.in | 2 +- .../test/add_subdirectory_test.cmake.in | 2 +- .../find_package_no_components_test.cmake.in | 2 +- .../minizip/test/find_package_test.cmake.in | 12 +- ...ind_package_wrong_components_test.cmake.in | 2 +- zlib/contrib/minizip/unzip.c | 200 +++++---- zlib/contrib/minizip/unzip.h | 7 +- zlib/contrib/minizip/zip.c | 272 ++++++------ zlib/contrib/minizip/zip.h | 11 +- zlib/contrib/pascal/zlibpas.pas | 4 +- zlib/crc32.c | 2 +- zlib/deflate.c | 104 +++-- zlib/gzguts.h | 29 +- zlib/gzlib.c | 74 ++-- zlib/gzread.c | 141 ++++-- zlib/gzwrite.c | 53 ++- zlib/infback.c | 2 - zlib/inflate.c | 56 ++- zlib/inflate.h | 4 +- zlib/inftrees.c | 4 +- zlib/inftrees.h | 10 +- zlib/qnx/package.qpg | 10 +- zlib/test/infcover.c | 5 +- zlib/test/minigzip.c | 9 +- zlib/treebuild.xml | 4 +- zlib/trees.c | 2 +- zlib/uncompr.c | 4 +- zlib/win32/Makefile.msc | 2 +- zlib/win32/README-WIN32.txt | 4 +- zlib/zconf.h | 11 +- zlib/zconf.h.cmakein | 11 +- zlib/zconf.h.in | 11 +- zlib/zlib.3 | 4 +- zlib/zlib.3.pdf | Bin 28222 -> 21682 bytes zlib/zlib.h | 88 ++-- zlib/zlib.pc.cmakein | 8 +- zlib/zutil.c | 7 +- 56 files changed, 1396 insertions(+), 922 deletions(-) diff --git a/cgmanifest.json b/cgmanifest.json index a366860da..996908061 100644 --- a/cgmanifest.json +++ b/cgmanifest.json @@ -26,7 +26,7 @@ "Type": "git", "git": { "RepositoryUrl": "https://github.com/madler/zlib", - "CommitHash": "da607da739fa6047df13e66a2af6b8bec7c2a498" + "CommitHash": "99623ef7097352da7993ba614161fd6a311e046e" } }, "DevelopmentDependency": false diff --git a/zlib/CMakeLists.txt b/zlib/CMakeLists.txt index d7c3867da..20623c21e 100644 --- a/zlib/CMakeLists.txt +++ b/zlib/CMakeLists.txt @@ -3,7 +3,8 @@ set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) project(zlib C) -set(VERSION "1.3.2") +set(VERSION "1.4") +set(zlib_VERSION "${VERSION}") option(ASM686 "Enable building i686 assembly implementation") option(AMD64 "Enable building amd64 assembly implementation") @@ -14,6 +15,9 @@ set(INSTALL_INC_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "Installation d set(INSTALL_MAN_DIR "${CMAKE_INSTALL_PREFIX}/share/man" CACHE PATH "Installation directory for manual pages") set(INSTALL_PKGCONFIG_DIR "${CMAKE_INSTALL_PREFIX}/share/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files") +set(pc_libdir "${INSTALL_LIB_DIR}") +set(pc_includedir "${INSTALL_INC_DIR}") + include(CheckTypeSize) include(CheckFunctionExists) include(CheckIncludeFile) @@ -226,7 +230,7 @@ add_test(example example) add_executable(minigzip test/minigzip.c) target_link_libraries(minigzip zlib) -if(HAVE_OFF64_T) +if(HAVE_OFF64_T OR WIN32) add_executable(example64 test/example.c) target_link_libraries(example64 zlib) set_target_properties(example64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64") diff --git a/zlib/ChangeLog b/zlib/ChangeLog index 312753eda..228a03afa 100644 --- a/zlib/ChangeLog +++ b/zlib/ChangeLog @@ -1,6 +1,37 @@ ChangeLog file for zlib +Changes in 1.4 (4 Nov 2026) +- Change CMake library names on MSVC +- Return z_off_t default to long for portability +- Fail gzopen() with "x" if O_EXCL not available +- Deliver all gzip data before reporting error +- Fix gzwrite() buffer overflow (CVE-2026-85091) +- Fix inflateGetDictionary() write past buffer on invalid window size +- Fix window write overrun after inflateSync() +- Fix read before provided data after repeated inflatePrime()'s +- Fix write past pending buffer after repeated deflatePrime()'s +- Fix copy of uninitialized memory by inflateBack() on invalid data +- Fix copy of uninitialized memory after gzseek() as first write action +- Fix read outside window after a deflateResetKeep() mid-stream +- Avoid out-of-bounds pointer arithmetic in infback9() (CVE-2026-4738) +- Fix several vulnerabilities in contrib/minizip +- Fix truncated stream detection in gzread() +- Fix pending skip handling in gzread() +- Fix loss of zero fill on repeated gzseek()'s when writing +- Fix inaccurate total_in after Z_NEED_DICT returned +- Detect and report bad deflateSetDictionary() calls +- Avoid undefined behaviors in C language usage +- Fix minizip extra field overflows when almost full and need Zip64 +- Don't assume NULL is defined in compress.c and uncompr.c +- Use the generated zconf.h when building test programs out of tree +- Improve portability and functionality of CMake builds +- Provide 64-bit file offsets on Windows with #defines as on Linux +- Improve portability to Android, AIX, PowerPC, s390x, and Windows +- Use a PCG random number generator instead of rand() in minizip +- Clarify documentation +- (See https://github.com/madler/zlib for all 195 commits) + Changes in 1.3.2 (17 Feb 2026) - Continued rewrite of CMake build [Vollstrecker] - Various portability improvements diff --git a/zlib/Makefile.in b/zlib/Makefile.in index f68d6988b..011912641 100644 --- a/zlib/Makefile.in +++ b/zlib/Makefile.in @@ -31,7 +31,7 @@ VGFMAFLAG= STATICLIB=libz.a SHAREDLIB=libz.so -SHAREDLIBV=libz.so.1.3.2 +SHAREDLIBV=libz.so.1.4 SHAREDLIBM=libz.so.1 LIBS=$(STATICLIB) $(SHAREDLIBV) @@ -40,6 +40,8 @@ ARFLAGS=rc RANLIB=ranlib LDCONFIG=ldconfig LDSHAREDLIBC=-lc +SHAREDEXP= +SHAREDEXPFLAG= TAR=tar SHELL=/bin/sh EXE= @@ -285,13 +287,21 @@ gzwrite.lo: $(SRCDIR)gzwrite.c -@mv objs/gzwrite.o $@ -placebo $(SHAREDLIBV): $(PIC_OBJS) libz.a $(SRCDIR)zlib.map - $(LDSHARED) $(SFLAGS) -o $@ $(PIC_OBJS) $(LDSHAREDLIBC) $(LDFLAGS) +placebo $(SHAREDLIBV): $(PIC_OBJS) libz.a $(SRCDIR)zlib.map $(SHAREDEXP) + $(LDSHARED) $(SFLAGS) $(SHAREDEXPFLAG) -o $@ $(PIC_OBJS) $(LDSHAREDLIBC) $(LDFLAGS) rm -f $(SHAREDLIB) $(SHAREDLIBM) ln -s $@ $(SHAREDLIB) ln -s $@ $(SHAREDLIBM) -@rmdir objs +libz.exp: $(PIC_OBJS) + dump -tov -X 32_64 $(PIC_OBJS) | \ + awk '$$1 ~ /^\[[0-9]+\]$$/ && $$2 == "m" && \ + $$4 ~ /^\.(text|data|bss)$$/ && ($$6 == "extern" || $$6 == "weak") && \ + $$7 != "HIDDEN" && $$7 != "INTERNAL" && $$NF !~ /^\./ { print $$NF }' | \ + sort -u > $@ + @test -s $@ || { echo "no symbols found for $@" >&2; rm -f $@; false; } + example$(EXE): example.o $(STATICLIB) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ example.o $(TEST_LIBS) diff --git a/zlib/compress.c b/zlib/compress.c index bd74b9488..2e967145b 100644 --- a/zlib/compress.c +++ b/zlib/compress.c @@ -28,8 +28,8 @@ int ZEXPORT compress2_z(Bytef *dest, z_size_t *destLen, const Bytef *source, const uInt max = (uInt)-1; z_size_t left; - if ((sourceLen > 0 && source == NULL) || - destLen == NULL || (*destLen > 0 && dest == NULL)) + if ((sourceLen > 0 && source == Z_NULL) || + destLen == Z_NULL || (*destLen > 0 && dest == Z_NULL)) return Z_STREAM_ERROR; left = *destLen; diff --git a/zlib/configure b/zlib/configure index b1c4960c8..729b5dc91 100644 --- a/zlib/configure +++ b/zlib/configure @@ -26,7 +26,7 @@ if test $SRCDIR = "."; then SRCDIR="" else ZINC='-I. -include zconf.h' - ZINCOUT='-I. -I$(SRCDIR)' + ZINCOUT='-I. -I$(SRCDIR) -include zconf.h' SRCDIR="$SRCDIR/" fi @@ -321,7 +321,9 @@ if test "$gcc" -eq 1 && ($cc -c $test.c) >> configure.log 2>&1; then esac ;; AIX*) LDSHARED=${LDSHARED-"$cc -shared"} - LDFLAGS="${LDFLAGS} -Wl,-brtl" ;; + LDFLAGS="${LDFLAGS} -Wl,-brtl" + SHAREDEXP=libz.exp + SHAREDEXPFLAG=-Wl,-bE:libz.exp ;; Darwin* | darwin* | *-darwin*) shared_ext='.dylib' SHAREDLIB=libz$shared_ext @@ -403,6 +405,7 @@ else fi if test -n "$ZINC"; then ZINC='-I- -I. -I$(SRCDIR)' + ZINCOUT='-I- -I. -I$(SRCDIR)' fi ;; SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"} @@ -507,6 +510,29 @@ else leave 1 fi +# turn off useless GCC 5 warning about PowerPC vector type alignments. +if test "$gcc" -eq 1; then + cat > $test.c << EOF +typedef int zvec __attribute__((vector_size(8))); +struct zstruct { char c; zvec v; }; +int zfunc(struct zstruct *s) { return s->c; } +EOF + echo "Checking for gcc vector ABI notes..." >> configure.log + show $CC -c $CFLAGS $test.c + got=`( $CC -c $CFLAGS $test.c ) 2>&1` + if test "$got" != ""; then + printf "%s\n" "$got" >> configure.log + fi + case "$got" in + *"changed in GCC 5"*) + if tryboth $CC -c $CFLAGS -Wno-psabi $test.c; then + echo "... turning the notes off with -Wno-psabi" >> configure.log + CFLAGS="${CFLAGS} -Wno-psabi" + SFLAGS="${SFLAGS} -Wno-psabi" + fi ;; + esac +fi + echo >> configure.log # see if shared library build supported @@ -517,8 +543,15 @@ EOF if test $shared -eq 1; then echo Checking for shared library support... | tee -a configure.log # we must test in two steps (cc then ld), required at least on SunOS 4.x + # the second link test is for linkers like lld that by default reject a + # version script naming symbols that the test object doesn't define -- if + # that's needed, keep the option, since some builds (e.g. --solo) don't + # define all of the symbols in zlib.map if try $CC -c $SFLAGS $test.c && - try $LDSHARED $SFLAGS $LDFLAGS -o $test$shared_ext $test.o; then + { try $LDSHARED $SFLAGS $LDFLAGS -o $test$shared_ext $test.o || + { try $LDSHARED $SFLAGS $LDFLAGS -Wl,--undefined-version \ + -o $test$shared_ext $test.o && + LDSHARED="$LDSHARED -Wl,--undefined-version"; }; }; then echo Building shared library $SHAREDLIBV with $CC. | tee -a configure.log elif test -z "$old_cc" -a -z "$old_cflags"; then echo No shared library support. | tee -a configure.log @@ -1024,6 +1057,7 @@ sed < ${SRCDIR}Makefile.in " /^LDFLAGS *=/s#=.*#=$LDFLAGS# /^LDSHARED *=/s#=.*#=$LDSHARED# /^CPP *=/s#=.*#=$CPP# +/^VGFMAFLAG *=/s#=.*#=$VGFMAFLAG# /^STATICLIB *=/s#=.*#=$STATICLIB# /^SHAREDLIB *=/s#=.*#=$SHAREDLIB# /^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV# @@ -1033,6 +1067,8 @@ sed < ${SRCDIR}Makefile.in " /^RANLIB *=/s#=.*#=$RANLIB# /^LDCONFIG *=/s#=.*#=$LDCONFIG# /^LDSHAREDLIBC *=/s#=.*#=$LDSHAREDLIBC# +/^SHAREDEXP *=/s#=.*#=$SHAREDEXP# +/^SHAREDEXPFLAG *=/s#=.*#=$SHAREDEXPFLAG# /^EXE *=/s#=.*#=$EXE# /^SRCDIR *=/s#=.*#=$SRCDIR# /^ZINC *=/s#=.*#=$ZINC# @@ -1054,6 +1090,7 @@ sed < ${SRCDIR}zlib.pc.in " /^CC *=/s#=.*#=$CC# /^CFLAGS *=/s#=.*#=$CFLAGS# /^CPP *=/s#=.*#=$CPP# +/^VGFMAFLAG *=/s#=.*#=$VGFMAFLAG# /^LDSHARED *=/s#=.*#=$LDSHARED# /^STATICLIB *=/s#=.*#=$STATICLIB# /^SHAREDLIB *=/s#=.*#=$SHAREDLIB# diff --git a/zlib/contrib/delphi/ZLib.pas b/zlib/contrib/delphi/ZLib.pas index cda3b09e9..f7c389b57 100644 --- a/zlib/contrib/delphi/ZLib.pas +++ b/zlib/contrib/delphi/ZLib.pas @@ -152,7 +152,7 @@ procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer; const OutBuf: Pointer; BufSize: Integer); const - zlib_version = '1.3.2'; + zlib_version = '1.4'; type EZlibError = class(Exception); diff --git a/zlib/contrib/dotzlib/DotZLib/UnitTests.cs b/zlib/contrib/dotzlib/DotZLib/UnitTests.cs index 4625f50f2..50203a299 100644 --- a/zlib/contrib/dotzlib/DotZLib/UnitTests.cs +++ b/zlib/contrib/dotzlib/DotZLib/UnitTests.cs @@ -156,7 +156,7 @@ public class InfoTests public void Info_Version() { Info info = new Info(); - Assert.AreEqual("1.3.2", Info.Version); + Assert.AreEqual("1.4", Info.Version); Assert.AreEqual(32, info.SizeOfUInt); Assert.AreEqual(32, info.SizeOfULong); Assert.AreEqual(32, info.SizeOfPointer); diff --git a/zlib/contrib/infback9/inftree9.c b/zlib/contrib/infback9/inftree9.c index cb96cf874..4044a2aa5 100644 --- a/zlib/contrib/infback9/inftree9.c +++ b/zlib/contrib/infback9/inftree9.c @@ -9,7 +9,7 @@ #define MAXBITS 15 const char inflate9_copyright[] = - " inflate9 1.3.2 Copyright 1995-2026 Mark Adler "; + " inflate9 1.4 Copyright 1995-2026 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -49,7 +49,7 @@ int inflate_table9(codetype type, unsigned short FAR *lens, unsigned codes, 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 */ - int end; /* use base and extra for symbol > end */ + unsigned match; /* 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 */ @@ -59,7 +59,7 @@ int inflate_table9(codetype type, unsigned short FAR *lens, unsigned codes, static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129, 130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132, - 133, 133, 133, 133, 144, 199, 75}; + 133, 133, 133, 133, 144, 71, 77}; static const unsigned short dbase[32] = { /* Distance codes 0..31 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, @@ -170,19 +170,17 @@ int inflate_table9(codetype type, unsigned short FAR *lens, unsigned codes, switch (type) { case CODES: base = extra = work; /* dummy value--not used */ - end = 19; + match = 20; break; case LENS: base = lbase; - base -= 257; extra = lext; - extra -= 257; - end = 256; + match = 257; break; default: /* DISTS */ base = dbase; extra = dext; - end = -1; + match = 0; } /* initialize state for loop */ @@ -205,13 +203,13 @@ int inflate_table9(codetype type, unsigned short FAR *lens, unsigned codes, for (;;) { /* create table entry */ this.bits = (unsigned char)(len - drop); - if ((int)(work[sym]) < end) { + if ((unsigned)(work[sym]) + 1 < match) { this.op = (unsigned char)0; this.val = work[sym]; } - else if ((int)(work[sym]) > end) { - this.op = (unsigned char)(extra[work[sym]]); - this.val = base[work[sym]]; + else if ((work[sym]) >= match) { + this.op = (unsigned char)(extra[work[sym]- match]); + this.val = base[work[sym]- match]; } else { this.op = (unsigned char)(32 + 64); /* end of block */ diff --git a/zlib/contrib/minizip/CMakeLists.txt b/zlib/contrib/minizip/CMakeLists.txt index 80ccf9906..6a18fa22c 100644 --- a/zlib/contrib/minizip/CMakeLists.txt +++ b/zlib/contrib/minizip/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.12...3.31) +cmake_minimum_required(VERSION 3.15...3.31) project( minizip @@ -7,11 +7,6 @@ project( DESCRIPTION "A library for creating zipfiles based in zlib" HOMEPAGE_URL "https://www.winimage.com/zLibDll/minizip.html") -if(CMAKE_SIZEOF_VOID_P LESS 8 AND NOT MINGW) - message(WARNING "libminizip needs 64bit - stopping here") - return() -endif(CMAKE_SIZEOF_VOID_P LESS 8 AND NOT MINGW) - # ============================================================================ # CPack # ============================================================================ @@ -26,7 +21,7 @@ set(CPACK_RESOURCE_FILE_README ${minizip_SOURCE_DIR}/MiniZip64_info.txt) if(ZLIB_BUILD_MINIZIP) set(MINIZIP_BUILD_SHARED ${ZLIB_MINIZIP_BUILD_SHARED} CACHE BOOL "") set(MINIZIP_BUILD_STATIC ${ZLIB_MINIZIP_BUILD_STATIC} CACHE BOOL "") - set(MINIZIP_BUILD_TESTING ${ZLIB_MINIZIP_INSTALL} CACHE BOOL "") + set(MINIZIP_BUILD_TESTING ${ZLIB_MINIZIP_BUILD_TESTING} CACHE BOOL "") set(MINIZIP_INSTALL ${ZLIB_MINIZIP_INSTALL} CACHE BOOL "") endif(ZLIB_BUILD_MINIZIP) @@ -40,7 +35,7 @@ option(MINIZIP_ENABLE_BZIP2 "Build minizip with bzip2 support" OFF) option(MINIZIP_INSTALL "Enable installation of minizip" ON) include(CheckCSourceCompiles) -include(CheckFunctionExists) +include(CheckSymbolExists) include(CheckIncludeFile) include(CMakePackageConfigHelpers) include(CheckTypeSize) @@ -69,12 +64,12 @@ endif(MINIZIP_ENABLE_BZIP2) # # Check for fopen64 # -check_function_exists(fopen64 HAVE_FOPEN64) +check_symbol_exists(fopen64 stdio.h HAVE_FOPEN64) # # Check for fseeko # -check_function_exists(fseeko HAVE_FSEEKO) +check_symbol_exists(fseeko stdio.h HAVE_FSEEKO) # # Check for unistd.h @@ -107,125 +102,228 @@ check_c_source_compiles( unset(CMAKE_REQUIRED_FLAGS) -set(LIBMINIZIP_SRCS ioapi.c mztools.c unzip.c zip.c) +set(LIBMINIZIP_SRCS + ioapi.c + mztools.c + unzip.c + zip.c + $<$:iowin32.c>) -set(LIBMINIZIP_HDRS crypt.h ints.h ioapi.h mztools.h unzip.h zip.h) +set(LIBMINIZIP_HDRS + crypt.h + ints.h + ioapi.h + mztools.h + unzip.h + zip.h + $<$:${minizip_SOURCE_DIR}/iowin32.h>) -set(MINIZIP_SRCS ioapi.c $<$:iowin32.c> minizip.c zip.c) +set(MINIZIP_SRCS + ioapi.c + minizip.c + zip.c) -set(MINIZIP_HDRS crypt.h ints.h ioapi.h $<$:iowin32.h> skipset.h - zip.h) +set(MINIZIP_HDRS + crypt.h + ints.h + ioapi.h + skipset.h + zip.h) -set(MINIUNZIP_SRCS ioapi.c $<$:iowin32.c> miniunz.c unzip.c - zip.c) +set(MINIUNZIP_SRCS + ioapi.c + miniunz.c + unzip.c + zip.c) set(MINIUNZIP_HDRS crypt.h ints.h ioapi.h - $<$:iowin32.h> skipset.h unzip.h zip.h) +set(LIBMINIZIP_PC ${minizip_BINARY_DIR}/minizip.pc) +configure_file(${minizip_SOURCE_DIR}/minizip.pc.txt ${LIBMINIZIP_PC} @ONLY) + if(WIN32 OR CYGWIN) set(minizip_static_suffix "s") set(CMAKE_DEBUG_POSTFIX "d") + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) endif(WIN32 OR CYGWIN) if(MINIZIP_BUILD_SHARED) - set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) - add_library(libminizip SHARED ${LIBMINIZIP_SRCS} ${LIBMINIZIP_HDRS}) - add_library(MINIZIP::minizip ALIAS libminizip) - target_include_directories( - libminizip PUBLIC $ - $) - target_compile_definitions( - libminizip - PRIVATE $<$:_CRT_SECURE_NO_WARNINGS> - $<$:HAVE_HIDDEN> - $<$:HAVE_UNISTD_H=1> - PUBLIC $<$:_LARGEFILE64_SOURCE=1> - $<$:HAVE_BZIP2=1> - $<$:USE_FILE32API=1>) - - if(NOT CYGWIN) - set_target_properties(libminizip PROPERTIES SOVERSION - ${minizip_VERSION_MAJOR}) - endif(NOT CYGWIN) - - set_target_properties( - libminizip - PROPERTIES EXPORT_NAME minizip - OUTPUT_NAME minizip - VERSION ${minizip_VERSION} - SOVERSION ${minizip_VERSION_MAJOR}) - - target_link_libraries(libminizip - PUBLIC ZLIB::ZLIB + add_library(${ZLIB_CONTRIB_PREFIX}libminizip SHARED + ${LIBMINIZIP_SRCS} + ${LIBMINIZIP_HDRS}) + add_library(MINIZIP::minizip ALIAS ${ZLIB_CONTRIB_PREFIX}libminizip) + target_include_directories(${ZLIB_CONTRIB_PREFIX}libminizip + PUBLIC + $ + $) + target_compile_definitions(${ZLIB_CONTRIB_PREFIX}libminizip + PRIVATE + $<$:_CRT_SECURE_NO_WARNINGS> + $<$:HAVE_HIDDEN> + $<$:HAVE_UNISTD_H=1> + PUBLIC + $<$:_LARGEFILE64_SOURCE=1> + $<$:HAVE_BZIP2=1> + $<$>,$>>:USE_FILE32API=1>) + + if(CYGWIN) + set_target_properties(${ZLIB_CONTRIB_PREFIX}libminizip + PROPERTIES + PREFIX "lib") + else(CYGWIN) + set_target_properties(${ZLIB_CONTRIB_PREFIX}libminizip + PROPERTIES + SOVERSION ${zlib_VERSION_MAJOR} + VERSION ${INSTALL_VERSION}) + endif(CYGWIN) + + set_target_properties(${ZLIB_CONTRIB_PREFIX}libminizip + PROPERTIES + EXPORT_NAME minizip + PUBLIC_HEADER "${LIBMINIZIP_HDRS}") + + if(MSVC) + set_target_properties(${ZLIB_CONTRIB_PREFIX}libminizip + PROPERTIES + OUTPUT_NAME libminizip) + else(MSVC) + set_target_properties(${ZLIB_CONTRIB_PREFIX}libminizip + PROPERTIES + OUTPUT_NAME minizip) + endif(MSVC) + + target_link_libraries(${ZLIB_CONTRIB_PREFIX}libminizip + PUBLIC + ZLIB::ZLIB $<$:BZip2::BZip2>) - add_executable(minizip ${MINIZIP_SRCS} ${MINIZIP_HDRS}) - set_target_properties(minizip PROPERTIES EXPORT_NAME minizip_executable) - target_compile_definitions( - minizip PRIVATE $<$:_CRT_SECURE_NO_WARNINGS>) - target_link_libraries(minizip PRIVATE MINIZIP::minizip) - add_executable(miniunzip ${MINIUNZIP_SRCS} ${MINIUNZIP_HDRS}) - set_target_properties(miniunzip PROPERTIES EXPORT_NAME miniunzip_executable) - target_compile_definitions( - miniunzip PRIVATE $<$:_CRT_SECURE_NO_WARNINGS>) - target_link_libraries(miniunzip PRIVATE MINIZIP::minizip) + add_executable(${ZLIB_CONTRIB_PREFIX}minizip + ${MINIZIP_SRCS} + ${MINIZIP_HDRS} + $<$:iowin32.h>) + set_target_properties(${ZLIB_CONTRIB_PREFIX}minizip + PROPERTIES + EXPORT_NAME minizip_executable + OUTPUT_NAME minizip) + target_compile_definitions(${ZLIB_CONTRIB_PREFIX}minizip + PRIVATE $<$:_CRT_SECURE_NO_WARNINGS>) + target_link_libraries(${ZLIB_CONTRIB_PREFIX}minizip + PRIVATE MINIZIP::minizip) + add_executable(${ZLIB_CONTRIB_PREFIX}miniunzip + ${MINIUNZIP_SRCS} + ${MINIUNZIP_HDRS} + $<$:iowin32.c> + $<$:iowin32.h>) + set_target_properties(${ZLIB_CONTRIB_PREFIX}miniunzip + PROPERTIES + EXPORT_NAME miniunzip_executable + OUTPUT_NAME miniunzip) + target_compile_definitions(${ZLIB_CONTRIB_PREFIX}miniunzip + PRIVATE $<$:_CRT_SECURE_NO_WARNINGS>) + target_link_libraries(${ZLIB_CONTRIB_PREFIX}miniunzip + PRIVATE MINIZIP::minizip) endif(MINIZIP_BUILD_SHARED) if(MINIZIP_BUILD_STATIC) - add_library(libminizipstatic STATIC ${LIBMINIZIP_SRCS} ${LIBMINIZIP_HDRS}) - add_library(MINIZIP::minizipstatic ALIAS libminizipstatic) - target_include_directories( - libminizipstatic - PUBLIC $ - $) - target_compile_definitions( - libminizipstatic - PRIVATE $<$:_CRT_SECURE_NO_WARNINGS> - $<$:HAVE_HIDDEN> - $<$:HAVE_UNISTD_H=1> - PUBLIC $<$:_LARGEFILE64_SOURCE=1> - $<$:HAVE_BZIP2=1> - $<$:USE_FILE32API=1>) - set_target_properties( - libminizipstatic PROPERTIES EXPORT_NAME minizipstatic - OUTPUT_NAME minizip${minizip_static_suffix}) + add_library(${ZLIB_CONTRIB_PREFIX}libminizipstatic + STATIC + ${LIBMINIZIP_SRCS} + ${LIBMINIZIP_HDRS}) + add_library(MINIZIP::minizipstatic ALIAS + ${ZLIB_CONTRIB_PREFIX}libminizipstatic) + target_include_directories(${ZLIB_CONTRIB_PREFIX}libminizipstatic + PUBLIC + $ + $) + target_compile_definitions(${ZLIB_CONTRIB_PREFIX}libminizipstatic + PRIVATE + $<$:_CRT_SECURE_NO_WARNINGS> + $<$:HAVE_HIDDEN> + $<$:HAVE_UNISTD_H=1> + PUBLIC + $<$:_LARGEFILE64_SOURCE=1> + $<$:HAVE_BZIP2=1> + $<$>,$>>:USE_FILE32API=1>) + set_target_properties(${ZLIB_CONTRIB_PREFIX}libminizipstatic + PROPERTIES + EXPORT_NAME minizipstatic + PUBLIC_HEADER "${LIBMINIZIP_HDRS}") + + if(CYGWIN) + set_target_properties(${ZLIB_CONTRIB_PREFIX}libminizipstatic + PROPERTIES + PREFIX "lib") + endif(CYGWIN) + + if(MSVC) + set_target_properties(${ZLIB_CONTRIB_PREFIX}libminizipstatic + PROPERTIES + ARCHIVE_OUTPUT_NAME libminizip${minizip_static_suffix}) + else(MSVC) + set_target_properties(${ZLIB_CONTRIB_PREFIX}libminizipstatic + PROPERTIES + ARCHIVE_OUTPUT_NAME minizip${minizip_static_suffix}) + endif(MSVC) if(CYGWIN) - set_target_properties(libminizipstatic PROPERTIES SUFFIX ".dll.a") + set_target_properties(${ZLIB_CONTRIB_PREFIX}libminizipstatic + PROPERTIES + SUFFIX ".dll.a") endif(CYGWIN) - target_link_libraries(libminizipstatic PUBLIC ZLIB::ZLIBSTATIC - $<$:BZip2::BZip2>) - - add_executable(minizipstatic ${MINIZIP_SRCS} ${MINIZIP_HDRS}) - set_target_properties(minizipstatic PROPERTIES EXPORT_NAME - minizip_static_executable) - target_compile_definitions( - minizipstatic PRIVATE $<$:_CRT_SECURE_NO_WARNINGS>) - target_link_libraries(minizipstatic PRIVATE MINIZIP::minizipstatic) - add_executable(miniunzipstatic ${MINIUNZIP_SRCS} ${MINIUNZIP_HDRS}) - set_target_properties(miniunzipstatic - PROPERTIES EXPORT_NAME miniunzip_static_executable) - target_compile_definitions( - miniunzipstatic PRIVATE $<$:_CRT_SECURE_NO_WARNINGS>) - target_link_libraries(miniunzipstatic PRIVATE MINIZIP::minizipstatic) + target_link_libraries(${ZLIB_CONTRIB_PREFIX}libminizipstatic + PUBLIC + ZLIB::ZLIBSTATIC + $<$:BZip2::BZip2>) + + add_executable(${ZLIB_CONTRIB_PREFIX}minizipstatic + ${MINIZIP_SRCS} + ${MINIZIP_HDRS} + $<$:iowin32.h>) + set_target_properties(${ZLIB_CONTRIB_PREFIX}minizipstatic + PROPERTIES + EXPORT_NAME minizip_static_executable + OUTPUT_NAME minizipstatic) + target_compile_definitions(${ZLIB_CONTRIB_PREFIX}minizipstatic + PRIVATE $<$:_CRT_SECURE_NO_WARNINGS>) + target_link_libraries(${ZLIB_CONTRIB_PREFIX}minizipstatic + PRIVATE MINIZIP::minizipstatic) + add_executable(${ZLIB_CONTRIB_PREFIX}miniunzipstatic + ${MINIUNZIP_SRCS} + ${MINIUNZIP_HDRS} + $<$:iowin32.c> + $<$:iowin32.h>) + set_target_properties(${ZLIB_CONTRIB_PREFIX}miniunzipstatic + PROPERTIES + EXPORT_NAME miniunzip_static_executable + OUTPUT_NAME miniunzipstatic) + target_compile_definitions(${ZLIB_CONTRIB_PREFIX}miniunzipstatic + PRIVATE $<$:_CRT_SECURE_NO_WARNINGS>) + target_link_libraries(${ZLIB_CONTRIB_PREFIX}miniunzipstatic + PRIVATE MINIZIP::minizipstatic) endif(MINIZIP_BUILD_STATIC) if(MINIZIP_INSTALL) if(MINIZIP_BUILD_SHARED) install( - TARGETS libminizip minizip miniunzip + TARGETS + ${ZLIB_CONTRIB_PREFIX}libminizip + ${ZLIB_CONTRIB_PREFIX}minizip + ${ZLIB_CONTRIB_PREFIX}miniunzip COMPONENT Runtime EXPORT minizipSharedExport RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + PUBLIC_HEADER + COMPONENT Development + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/minizip") install( EXPORT minizipSharedExport FILE minizip-shared.cmake @@ -234,7 +332,7 @@ if(MINIZIP_INSTALL) if(MSVC) install( - FILES $ + FILES $ COMPONENT Runtime DESTINATION ${CMAKE_INSTALL_BINDIR} CONFIGURATIONS Debug OR RelWithDebInfo @@ -244,14 +342,18 @@ if(MINIZIP_INSTALL) if(MINIZIP_BUILD_STATIC) install( - TARGETS libminizipstatic + TARGETS + ${ZLIB_CONTRIB_PREFIX}libminizipstatic + ${ZLIB_CONTRIB_PREFIX}minizipstatic + ${ZLIB_CONTRIB_PREFIX}miniunzipstatic COMPONENT Development - TARGETS minizipstatic miniunzipstatic - COMPONENT Runtime EXPORT minizipStaticExport - RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + RUNTIME + DESTINATION "${CMAKE_INSTALL_BINDIR}" + COMPONENT Runtime ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/minizip") install( EXPORT minizipStaticExport FILE minizip-static.cmake @@ -271,117 +373,12 @@ if(MINIZIP_INSTALL) ${minizip_BINARY_DIR}/minizipConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/minizip) install( - FILES ${LIBMINIZIP_HDRS} + FILES ${LIBMINIZIP_PC} COMPONENT Development - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") + DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") endif(MINIZIP_INSTALL) if(MINIZIP_BUILD_TESTING) enable_testing() - - if(MINIZIP_BUILD_SHARED AND NOT ${CMAKE_SHARED_LIBRARY_SUFFIX} STREQUAL - ".dll") - add_test( - NAME minizip_prepare_shared_zip - COMMAND ${CMAKE_COMMAND} -DCREATE_SHARED=ON -P - ${CMAKE_CURRENT_SOURCE_DIR}/test/test_helper.cm - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test) - add_test( - NAME minizip_zipping_test_file_shared - COMMAND minizip test_file_shared.zip test_file_shared.txt - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test) - add_test( - NAME minizip_prepare_shared_unzip - COMMAND ${CMAKE_COMMAND} -DMOVE_SHARED=ON -P - ${CMAKE_CURRENT_SOURCE_DIR}/test/test_helper.cm - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test) - add_test( - NAME minizip_miniunzipping_test_file_shared.zip - COMMAND miniunzip test_file_shared.zip - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test) - add_test( - NAME minizip_compare_shared - COMMAND ${CMAKE_COMMAND} -E compare_files test_file_shared.txt - test_file_shared.orig - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test) - add_test( - NAME minizip_clean_shared_zip - COMMAND ${CMAKE_COMMAND} -DDELETE_SHARED=ON -P - ${CMAKE_CURRENT_SOURCE_DIR}/test/test_helper.cm - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test) - set_tests_properties(minizip_prepare_shared_zip - PROPERTIES FIXTURES_SETUP prepare_shared) - set_tests_properties( - minizip_zipping_test_file_shared - PROPERTIES FIXTURES_REQUIRED prepare_shared FIXTURES_SETUP - zip_shared) - set_tests_properties( - minizip_prepare_shared_unzip - PROPERTIES FIXTURES_REQUIRED zip_shared FIXTURES_SETUP - prepare_unzip_shared) - set_tests_properties( - minizip_miniunzipping_test_file_shared.zip - PROPERTIES FIXTURES_REQUIRED prepare_unzip_shared FIXTURES_SETUP - prepare_compare_shared) - set_tests_properties( - minizip_compare_shared - PROPERTIES FIXTURES_REQUIRED prepare_compare_shared FIXTURES_SETUP - compared_shared) - set_tests_properties(minizip_clean_shared_zip - PROPERTIES FIXTURES_CLEANUP compared_shared) - endif(MINIZIP_BUILD_SHARED AND NOT ${CMAKE_SHARED_LIBRARY_SUFFIX} STREQUAL - ".dll") - - if(MINIZIP_BUILD_STATIC) - add_test( - NAME minizip_prepare_static_zip - COMMAND ${CMAKE_COMMAND} -DCREATE_STATIC=ON -P - ${CMAKE_CURRENT_SOURCE_DIR}/test/test_helper.cm - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test) - add_test( - NAME minizip_zipping_test_file_static - COMMAND minizipstatic test_file_static.zip test_file_static.txt - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test) - add_test( - NAME minizip_prepare_static_unzip - COMMAND ${CMAKE_COMMAND} -DMOVE_STATIC=ON -P - ${CMAKE_CURRENT_SOURCE_DIR}/test/test_helper.cm - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test) - add_test( - NAME minizip_miniunzipping_test_file_static.zip - COMMAND miniunzipstatic test_file_static.zip - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test) - add_test( - NAME minizip_compare_static - COMMAND ${CMAKE_COMMAND} -E compare_files test_file_static.txt - test_file_static.orig - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test) - add_test( - NAME minizip_clean_static_zip - COMMAND ${CMAKE_COMMAND} -DDELETE_STATIC=ON -P - ${CMAKE_CURRENT_SOURCE_DIR}/test/test_helper.cm - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test) - set_tests_properties(minizip_prepare_static_zip - PROPERTIES FIXTURES_SETUP prepare_static) - set_tests_properties( - minizip_zipping_test_file_static - PROPERTIES FIXTURES_REQUIRED prepare_static FIXTURES_SETUP - zip_static) - set_tests_properties( - minizip_prepare_static_unzip - PROPERTIES FIXTURES_REQUIRED zip_static FIXTURES_SETUP - prepare_unzip_static) - set_tests_properties( - minizip_miniunzipping_test_file_static.zip - PROPERTIES FIXTURES_REQUIRED prepare_unzip_static FIXTURES_SETUP - prepare_compare_static) - set_tests_properties( - minizip_compare_static - PROPERTIES FIXTURES_REQUIRED prepare_compare_static FIXTURES_SETUP - compared_static) - set_tests_properties(minizip_clean_static_zip - PROPERTIES FIXTURES_CLEANUP compared_static) - endif(MINIZIP_BUILD_STATIC) - add_subdirectory(test) endif(MINIZIP_BUILD_TESTING) diff --git a/zlib/contrib/minizip/Makefile.am b/zlib/contrib/minizip/Makefile.am index d343011eb..b626f42c1 100644 --- a/zlib/contrib/minizip/Makefile.am +++ b/zlib/contrib/minizip/Makefile.am @@ -27,6 +27,7 @@ libminizip_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:0:0 -lz minizip_includedir = $(includedir)/minizip minizip_include_HEADERS = \ crypt.h \ + ints.h \ ioapi.h \ mztools.h \ unzip.h \ @@ -39,7 +40,7 @@ pkgconfig_DATA = minizip.pc EXTRA_PROGRAMS = miniunzip minizip miniunzip_SOURCES = miniunz.c -miniunzip_LDADD = libminizip.la +miniunzip_LDADD = libminizip.la -lz minizip_SOURCES = minizip.c minizip_LDADD = libminizip.la -lz diff --git a/zlib/contrib/minizip/configure.ac b/zlib/contrib/minizip/configure.ac index b739fa0c7..e79d58165 100644 --- a/zlib/contrib/minizip/configure.ac +++ b/zlib/contrib/minizip/configure.ac @@ -1,7 +1,7 @@ # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. -AC_INIT([minizip], [1.3.2], [bugzilla.redhat.com]) +AC_INIT([minizip], [1.4], [bugzilla.redhat.com]) AC_CONFIG_SRCDIR([minizip.c]) AM_INIT_AUTOMAKE([foreign]) LT_INIT diff --git a/zlib/contrib/minizip/crypt.h b/zlib/contrib/minizip/crypt.h index dd548938a..d23cc6a0b 100644 --- a/zlib/contrib/minizip/crypt.h +++ b/zlib/contrib/minizip/crypt.h @@ -77,11 +77,10 @@ static void init_keys(const char* passwd, unsigned long* pkeys, const z_crc_t* p #ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED #define RAND_HEAD_LEN 12 - /* "last resort" source for second part of crypt seed pattern */ -# ifndef ZCR_SEED2 -# define ZCR_SEED2 3141592654UL /* use PI as default pattern */ -# endif +/* The random header bytes come from the PCG32 generator in skipset.h, which + must be included before this file when INCLUDECRYPTINGCODE_IFCRYPTALLOWED is + defined. */ static unsigned crypthead(const char* passwd, /* password string */ unsigned char* buf, /* where to write header */ int bufSize, @@ -92,23 +91,25 @@ static unsigned crypthead(const char* passwd, /* password string */ int t; /* temporary */ int c; /* random byte */ unsigned char header[RAND_HEAD_LEN-2]; /* random header */ - static unsigned calls = 0; /* ensure different random header each time */ + static int seeded = 0; /* true once gen has been seeded */ + static set_rand_t gen; /* random header generator, persists so that + each header is different */ if (bufSize> 7) & 0xff; + c = (int)(set_rand(&gen) >> 24); header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); } /* Encrypt random header (last two bytes is high word of crc) */ diff --git a/zlib/contrib/minizip/ioapi.h b/zlib/contrib/minizip/ioapi.h index a5211239e..8dc78ae6e 100644 --- a/zlib/contrib/minizip/ioapi.h +++ b/zlib/contrib/minizip/ioapi.h @@ -21,7 +21,7 @@ #ifndef ZLIBIOAPI64_H #define ZLIBIOAPI64_H -#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__)) && (!(defined(__ANDROID_API__) || __ANDROID_API__ >= 24)) +#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__)) && (!defined(__ANDROID_API__) || __ANDROID_API__ >= 24) /* Linux needs this to support file operation on files larger then 4+GB */ /* But might need better if/def to select just the platforms that needs them.*/ diff --git a/zlib/contrib/minizip/miniunz.c b/zlib/contrib/minizip/miniunz.c index cd577ea03..19724d1ac 100644 --- a/zlib/contrib/minizip/miniunz.c +++ b/zlib/contrib/minizip/miniunz.c @@ -184,6 +184,59 @@ static int makedir(const char *newdir) { return 1; } +/* Copy to out a version of the path name that can only be created under the + extraction directory. Both '/' and '\\' are taken as separators. Empty and + "." path components are removed, and a ".." component is removed along with + the component before it, if any. On Windows, drive specifiers at the start + and components of only dots and spaces are also removed. The result is + always a relative path, and is no longer than name. out must have room for + strlen(name) + 1 characters. */ +static void safe_path(char* out, const char* name) { + char* start = out; + while (*name != '\0') + { + const char* comp = name; + size_t len; + while (*name != '\0' && *name != '/' && *name != '\\') + name++; + len = (size_t)(name - comp); +#ifdef _WIN32 + while (out == start && len >= 2 && comp[1] == ':') + { + comp += 2; /* remove drive specifiers, e.g. "C:" */ + len -= 2; + } + { + /* Windows drops trailing dots and spaces from a name, so remove + any other component made of only those, such as "..." */ + size_t i = 0; + while (i < len && (comp[i] == '.' || comp[i] == ' ')) + i++; + if (i == len && !(len == 2 && comp[0] == '.' && comp[1] == '.')) + len = 0; + } +#endif + if (len == 2 && comp[0] == '.' && comp[1] == '.') + { + /* remove the previous component and its separator, if any */ + if (out > start) + out--; + while (out > start && out[-1] != '/' && out[-1] != '\\') + out--; + } + else if (len != 0 && !(len == 1 && comp[0] == '.')) + { + memcpy(out, comp, len); + out += len; + if (*name != '\0') + *out++ = *name; /* keep the separator */ + } + if (*name != '\0') + name++; + } + *out = '\0'; +} + static void do_banner(void) { printf("MiniUnz 1.1, demo of zLib + Unz package written by Gilles Vollant\n"); printf("more info at https://www.winimage.com/zLibDll/unzip.html\n\n"); @@ -267,7 +320,7 @@ static int do_list(unzFile uf) { string_method="Defl:N"; else if (iLevel==1) string_method="Defl:X"; - else if ((iLevel==2) || (iLevel==3)) + else /* iLevel==2 || iLevel==3 */ string_method="Defl:F"; /* 2:fast , 3 : extra fast*/ } else @@ -305,6 +358,7 @@ static int do_list(unzFile uf) { static int do_extract_currentfile(unzFile uf, const int* popt_extract_without_path, int* popt_overwrite, const char* password) { char filename_inzip[65536+1]; + char write_name[65536+1]; char* filename_withoutpath; char* p; int err=UNZ_OK; @@ -339,36 +393,28 @@ static int do_extract_currentfile(unzFile uf, const int* popt_extract_without_pa if ((*filename_withoutpath)=='\0') { - if ((*popt_extract_without_path)==0) + safe_path(write_name, filename_inzip); + if (((*popt_extract_without_path)==0) && (write_name[0]!='\0')) { - printf("creating directory: %s\n",filename_inzip); - mymkdir(filename_inzip); + printf("creating directory: %s\n",write_name); + mymkdir(write_name); } } else { - const char* write_filename; + const char* write_filename = write_name; int skip=0; if ((*popt_extract_without_path)==0) - write_filename = filename_inzip; + safe_path(write_name, filename_inzip); else - write_filename = filename_withoutpath; - - if (write_filename[0]!='\0') + safe_path(write_name, filename_withoutpath); + if (write_name[0]=='\0') { - const char* relative_check = write_filename; - while (relative_check[1]!='\0') - { - if (relative_check[0]=='.' && relative_check[1]=='.') - write_filename = relative_check; - relative_check++; - } + printf("skipping %s: no name left to extract to\n",filename_inzip); + skip = 1; } - while (write_filename[0]=='/' || write_filename[0]=='.') - write_filename++; - err = unzOpenCurrentFilePassword(uf,password); if (err!=UNZ_OK) { @@ -412,14 +458,22 @@ static int do_extract_currentfile(unzFile uf, const int* popt_extract_without_pa { fout=FOPEN_FUNC(write_filename,"wb"); /* some zipfile don't contain directory alone before file */ - if ((fout==NULL) && ((*popt_extract_without_path)==0) && - (filename_withoutpath!=(char*)filename_inzip)) + if ((fout==NULL) && ((*popt_extract_without_path)==0)) { - char c=*(filename_withoutpath-1); - *(filename_withoutpath-1)='\0'; - makedir(write_filename); - *(filename_withoutpath-1)=c; - fout=FOPEN_FUNC(write_filename,"wb"); + /* make the directories leading up to the file */ + char* sep = NULL; + char* q; + for (q = write_name; *q != '\0'; q++) + if (*q == '/' || *q == '\\') + sep = q; + if (sep != NULL) + { + char c = *sep; + *sep = '\0'; + makedir(write_name); + *sep = c; + fout=FOPEN_FUNC(write_filename,"wb"); + } } if (fout==NULL) diff --git a/zlib/contrib/minizip/minizipConfig.cmake.in b/zlib/contrib/minizip/minizipConfig.cmake.in index f2fb3052f..71bed1d67 100644 --- a/zlib/contrib/minizip/minizipConfig.cmake.in +++ b/zlib/contrib/minizip/minizipConfig.cmake.in @@ -1,11 +1,15 @@ -@PACKAGE_INIT@ - set(_MINIZIP_supported_components "shared" "static") include(CMakeFindDependencyMacro) -if(@MINIZIP_ENABLE_BZIP2@) +set(minizip_HAS_BZIP2 + "@MINIZIP_ENABLE_BZIP2@" + CACHE + BOOL + "Indicates if minizip was compiled with bzip2 support") + +if(minizip_HAS_BZIP2) find_dependency(BZip2) -endif(@MINIZIP_ENABLE_BZIP2@) +endif(minizip_HAS_BZIP2) if(minizip_FIND_COMPONENTS) find_dependency(ZLIB CONFIG COMPONENTS ${minizip_FIND_COMPONENTS}) @@ -16,12 +20,36 @@ if(minizip_FIND_COMPONENTS) set(minizip_NOT_FOUND_MESSAGE "Unsupported component: ${_comp}") endif(NOT _comp IN_LIST _MINIZIP_supported_components) - include("${CMAKE_CURRENT_LIST_DIR}/minizip-${_comp}.cmake") - endforeach(_comp ${ZLIB_FIND_COMPONENTS}) + include("${CMAKE_CURRENT_LIST_DIR}/minizip-${_comp}.cmake" + OPTIONAL + RESULT_VARIABLE _comp_loaded) + + if(NOT _comp_loaded) + set(minizip_FOUND False) + set(minizip_NOT_FOUND_MESSAGE "Component ${_comp} not found.") + else(NOT _comp_loaded) + set(minizip_${_comp}_FOUND TRUE) + endif(NOT _comp_loaded) + endforeach(_comp ${minizip_FIND_COMPONENTS}) else(minizip_FIND_COMPONENTS) find_dependency(ZLIB CONFIG) foreach(_component_config IN LISTS _MINIZIP_supported_components) - include("${CMAKE_CURRENT_LIST_DIR}/minizip-${_component_config}.cmake") + include("${CMAKE_CURRENT_LIST_DIR}/minizip-${_component_config}.cmake" + OPTIONAL) endforeach(_component_config IN LISTS _MINIZIP_supported_components) + + if(NOT TARGET MINIZIP::minizip) + set(minizip_FOUND False) + set(minizip_NOT_FOUND_MESSAGE "Target ZLIB::ZLIB not created\n") + string(APPEND minizip_NOT_FOUND_MESSAGE "build minizip with support for shared libs or\n") + string(APPEND minizip_NOT_FOUND_MESSAGE "specify COMPONENTS static in your find_package call") + endif(NOT TARGET MINIZIP::minizip) + + if(NOT TARGET MINIZIP::minizipstatic) + set(minizip_FOUND False) + set(minizip_NOT_FOUND_MESSAGE "Target ZLIB::ZLIBSTATIC not created\n") + string(APPEND minizip_NOT_FOUND_MESSAGE "build minizip with support for static libs or\n") + string(APPEND minizip_NOT_FOUND_MESSAGE "specify COMPONENTS shared in your find_package call") + endif(NOT TARGET MINIZIP::minizipstatic) endif(minizip_FIND_COMPONENTS) diff --git a/zlib/contrib/minizip/mztools.c b/zlib/contrib/minizip/mztools.c index 1e2bb5685..f88060f84 100644 --- a/zlib/contrib/minizip/mztools.c +++ b/zlib/contrib/minizip/mztools.c @@ -16,7 +16,7 @@ #define READ_8(adr) ((unsigned char)*(adr)) #define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) ) -#define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) ) +#define READ_32(adr) ( (uLong)READ_16(adr) | ((uLong)READ_16((adr)+2) << 16) ) #define WRITE_8(buff, n) do { \ *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \ diff --git a/zlib/contrib/minizip/skipset.h b/zlib/contrib/minizip/skipset.h index ec4d4ab4d..ad09dd09b 100644 --- a/zlib/contrib/minizip/skipset.h +++ b/zlib/contrib/minizip/skipset.h @@ -1,56 +1,59 @@ /* skipset.h -- set operations using a skiplist -// Copyright (C) 2024-2026 Mark Adler -// See MiniZip_info.txt for the license. - -// This implements a skiplist set, i.e. just keys, no data, with ~O(log n) time -// insert and search operations. The application defines the type of a key, and -// provides a function to compare two keys. - -// This header is not definitions of functions found in another source file -- -// it creates the set functions, with the application's key type, right where -// the #include is. Before this header is #included, these must be defined: -// -// 1. A macro or typedef for set_key_t, the type of a key. -// 2. A macro or function set_cmp(a, b) to compare two keys. The return values -// are < 0 for a < b, 0 for a == b, and > 0 for a > b. -// 3. A macro or function set_drop(s, k) to release the key k's resources, if -// any, when doing a set_end() or set_clear(). s is a pointer to the set -// that key is in, for use with set_free() if desired. -// -// Example usage: -// -// typedef int set_key_t; -// #define set_cmp(a, b) ((a) < (b) ? -1 : (a) == (b) ? 0 : 1) -// #define set_drop(s, k) -// #include "skipset.h" -// -// int test(void) { // return 0: good, 1: bad, -1: out of memory -// set_t set; -// if (setjmp(set.env)) -// return -1; -// set_start(&set); -// set_insert(&set, 2); -// set_insert(&set, 1); -// set_insert(&set, 7); -// int bad = !set_found(&set, 2); -// bad = bad || set_found(&set, 5); -// set_end(&set); -// return bad; -// } -// -// Interface summary (see more details below): -// - set_t is the type of the set being operated on (a set_t pointer is passed) -// - set_start() initializes a new, empty set (initialize set.env first) -// - set_insert() inserts a new key into the set, or not if it's already there -// - set_found() determines whether or not a key is in the set -// - set_end() ends the use of the set, freeing all memory -// - set_clear() empties the set, equivalent to set_end() and then set_start() -// - set_ok() checks if set appears to be usable, i.e. started and not ended -// -// Auxiliary functions available to the application: -// - set_alloc() allocates memory with optional tracking (#define SET_TRACK) -// - set_free() deallocates memory allocated by set_alloc() -// - set_rand() returns 32 random bits (seeded by set_start()) */ + Copyright (C) 2024-2026 Mark Adler + See MiniZip_info.txt for the license. + */ + +/* + This implements a skiplist set, i.e. just keys, no data, with ~O(log n) time + insert and search operations. The application defines the type of a key, and + provides a function to compare two keys. + + This header is not definitions of functions found in another source file -- + it creates the set functions, with the application's key type, right where + the #include is. Before this header is #included, these must be defined: + + 1. A macro or typedef for set_key_t, the type of a key. + 2. A macro or function set_cmp(a, b) to compare two keys. The return values + are < 0 for a < b, 0 for a == b, and > 0 for a > b. + 3. A macro or function set_drop(s, k) to release the key k's resources, if + any, when doing a set_end() or set_clear(). s is a pointer to the set + that key is in, for use with set_free() if desired. + + Example usage: + + typedef int set_key_t; + #define set_cmp(a, b) ((a) < (b) ? -1 : (a) == (b) ? 0 : 1) + #define set_drop(s, k) + #include "skipset.h" + + int test(void) { // return 0: good, 1: bad, -1: out of memory + set_t set; + if (setjmp(set.env)) + return -1; + set_start(&set); + set_insert(&set, 2); + set_insert(&set, 1); + set_insert(&set, 7); + int bad = !set_found(&set, 2); + bad = bad || set_found(&set, 5); + set_end(&set); + return bad; + } + + Interface summary (see more details below): + - set_t is the type of the set being operated on (a set_t pointer is passed) + - set_start() initializes a new, empty set (initialize set.env first) + - set_insert() inserts a new key into the set, or not if it's already there + - set_found() determines whether or not a key is in the set + - set_end() ends the use of the set, freeing all memory + - set_clear() empties the set, equivalent to set_end() and then set_start() + - set_ok() checks if set appears to be usable, i.e. started and not ended + + Auxiliary functions available to the application: + - set_alloc() allocates memory with optional tracking (#define SET_TRACK) + - set_free() deallocates memory allocated by set_alloc() + - set_rand() returns 32 random bits (seeded by set_start()) + */ #ifndef SKIPSET_H #define SKIPSET_H @@ -63,38 +66,44 @@ #include /* assert.h */ #include "ints.h" /* i16_t, ui32_t, ui64_t */ -/* Structures and functions below noted as "--private--" should not be used by -// the application. set_t is partially private and partially public -- see the -// comments there. +/* + Structures and functions below noted as "--private--" should not be used by + the application. set_t is partially private and partially public -- see the + comments there. -// There is no POSIX random() in MSVC, and rand() is awful. For portability, we -// cannot rely on a library function for random numbers. Instead we use the -// fast and effective algorithm below, invented by Melissa O'Neill. + There is no POSIX random() in MSVC, and rand() is awful. For portability, we + cannot rely on a library function for random numbers. Instead we use the + fast and effective algorithm below, invented by Melissa O'Neill. + */ -// *Really* minimal PCG32 code / (c) 2014 M.E. O'Neill / www.pcg-random.org -// Licensed under Apache License 2.0 (NO WARRANTY, etc. see website) -// --private-- Random number generator state. */ +/* + *Really* minimal PCG32 code / (c) 2014 M.E. O'Neill / www.pcg-random.org + Licensed under Apache License 2.0 (NO WARRANTY, etc. see website) + --private-- Random number generator state. + */ typedef struct { ui64_t state; /* 64-bit generator state */ ui64_t inc; /* 63-bit sequence id */ } set_rand_t; /* --private-- Initialize the state *gen using seed and seq. seed seeds the -// advancing 64-bit state. seq is a sequence selection constant. */ -void set_seed(set_rand_t *gen, ui64_t seed, ui64_t seq) { + advancing 64-bit state. seq is a sequence selection constant. */ +static void set_seed(set_rand_t *gen, ui64_t seed, ui64_t seq) { gen->inc = (seq << 1) | 1; gen->state = (seed + gen->inc) * 6364136223846793005ULL + gen->inc; } /* Start a unique random number sequence using bits from noise sources. */ -void set_uniq(set_rand_t *gen, const void *ptr) { +static void set_uniq(set_rand_t *gen, const void *ptr) { set_seed(gen, ((ui64_t)(ptrdiff_t)ptr << 32) ^ ((ui64_t)time(NULL) << 12) ^ clock(), 0); } /* Return 32 random bits, advancing the state *gen. */ -ui32_t set_rand(set_rand_t *gen) { +static ui32_t set_rand(set_rand_t *gen) { + ui32_t mix; + int rot; ui64_t state = gen->state; gen->state = state * 6364136223846793005ULL + gen->inc; - ui32_t mix = (ui32_t)(((state >> 18) ^ state) >> 27); - int rot = state >> 59; + mix = (ui32_t)(((state >> 18) ^ state) >> 27); + rot = state >> 59; return (mix >> rot) | (mix << ((-rot) & 31)); } /* End of PCG32 code. */ @@ -109,7 +118,7 @@ struct set_node_s { }; /* A set. The application sets env, may use gen with set_rand(), and may read -// allocs and memory. The remaining variables are --private-- . */ + allocs and memory. The remaining variables are --private-- . */ typedef struct set_s { set_node_t *head; /* skiplist head -- no key, just links */ set_node_t *path; /* right[] is path to key from set_found() */ @@ -120,15 +129,15 @@ typedef struct set_s { jmp_buf env; /* setjmp() environment for allocation errors */ #ifdef SET_TRACK size_t allocs; /* number of allocations */ - size_t memory; /* total amount of allocated memory (>= requests) */ + size_t memory; /* total size of allocated memory (>= requests) */ #endif } set_t; /* Memory allocation and deallocation. set_alloc(set, ptr, size) returns a -// pointer to an allocation of size bytes if ptr is NULL, or the previous -// allocation ptr resized to size bytes. set_alloc() will never return NULL. -// set_free(set, ptr) frees an allocation created by set_alloc(). These may be -// used by the application. e.g. if allocation tracking is desired. */ + pointer to an allocation of size bytes if ptr is NULL, or the previous + allocation ptr resized to size bytes. set_alloc() will never return NULL. + set_free(set, ptr) frees an allocation created by set_alloc(). These may be + used by the application. e.g. if allocation tracking is desired. */ #ifdef SET_TRACK /* Track the number of allocations and the total backing memory size. */ # if defined(_WIN32) @@ -146,11 +155,11 @@ typedef struct set_s { # elif defined(__NetBSD__) # include # define SET_ALLOC_SIZE(ptr) malloc_usable_size(ptr) -# else // e.g. OpenBSD +# else /* e.g. OpenBSD */ # define SET_ALLOC_SIZE(ptr) 0 # endif -// With tracking. -void *set_alloc(set_t *set, void *ptr, size_t size) { +/* With tracking. */ +static void *set_alloc(set_t *set, void *ptr, size_t size) { size_t had = ptr == NULL ? 0 : SET_ALLOC_SIZE(ptr); void *mem = realloc(ptr, size); if (mem == NULL) @@ -159,7 +168,7 @@ void *set_alloc(set_t *set, void *ptr, size_t size) { set->memory += SET_ALLOC_SIZE(mem) - had; return mem; } -void set_free(set_t *set, void *ptr) { +static void set_free(set_t *set, void *ptr) { if (ptr != NULL) { set->allocs--; set->memory -= SET_ALLOC_SIZE(ptr); @@ -168,23 +177,24 @@ void set_free(set_t *set, void *ptr) { } #else /* Without tracking. */ -void *set_alloc(set_t *set, void *ptr, size_t size) { +static void *set_alloc(set_t *set, void *ptr, size_t size) { void *mem = realloc(ptr, size); if (mem == NULL) longjmp(set->env, ENOMEM); return mem; } -void set_free(set_t *set, void *ptr) { +static void set_free(set_t *set, void *ptr) { (void)set; free(ptr); } #endif /* --private-- Grow node's array right[] as needed to be able to hold at least -// want links. If fill is true, assure that the first want links are filled in, -// setting them to set->head if not previously filled in. Otherwise it is -// assumed that the first want links are about to be filled in. */ -void set_grow(set_t *set, set_node_t *node, int want, int fill) { + want links. If fill is true, assure that the first want links are filled in, + setting them to set->head if not previously filled in. Otherwise it is + assumed that the first want links are about to be filled in. */ +static void set_grow(set_t *set, set_node_t *node, int want, int fill) { + int i; if (node->size < want) { int more = node->size ? node->size : 1; while (more < want) @@ -193,7 +203,6 @@ void set_grow(set_t *set, set_node_t *node, int want, int fill) { (size_t)more * sizeof(set_node_t *)); node->size = (i16_t)more; } - int i; if (fill) for (i = node->fill; i < want; i++) node->right[i] = set->head; @@ -201,7 +210,7 @@ void set_grow(set_t *set, set_node_t *node, int want, int fill) { } /* --private-- Return a new node. key is left uninitialized. */ -set_node_t *set_node(set_t *set) { +static set_node_t *set_node(set_t *set) { set_node_t *node = set_alloc(set, NULL, sizeof(set_node_t)); node->size = 0; node->fill = 0; @@ -210,7 +219,7 @@ set_node_t *set_node(set_t *set) { } /* --private-- Free the list linked from head, along with the keys. */ -void set_sweep(set_t *set) { +static void set_sweep(set_t *set) { set_node_t *step = set->head->right[0]; while (step != set->head) { set_node_t *next = step->right[0]; /* save link to next node */ @@ -222,12 +231,12 @@ void set_sweep(set_t *set) { } /* Initialize a new set. set->env must be initialized using setjmp() before -// set_start() is called. A longjmp(set->env, ENOMEM) will be used to handle a -// memory allocation failure during any of the operations. (See setjmp.h and -// errno.h.) The set can still be used if this happens, assuming that it didn't -// happen during set_start(). Whether set_start() completed or not, set_end() -// can be used to free the set's memory after a longjmp(). */ -void set_start(set_t *set) { + set_start() is called. A longjmp(set->env, ENOMEM) will be used to handle a + memory allocation failure during any of the operations. (See setjmp.h and + errno.h.) The set can still be used if this happens, assuming that it didn't + happen during set_start(). Whether set_start() completed or not, set_end() + can be used to free the set's memory after a longjmp(). */ +SKIPSET_EXPORT void set_start(set_t *set) { #ifdef SET_TRACK set->allocs = 0; set->memory = 0; @@ -235,7 +244,7 @@ void set_start(set_t *set) { set->head = set->path = set->node = NULL; /* in case set_node() fails */ set->path = set_node(set); set->head = set_node(set); - set_grow(set, set->head, 1, 1); /* one link back to head for an empty set */ + set_grow(set, set->head, 1, 1); /* one link back to head for empty set */ *(unsigned char *)&set->head->key = 137; /* set id */ set->depth = 0; set_uniq(&set->gen, set); @@ -243,34 +252,36 @@ void set_start(set_t *set) { } /* Return true if *set appears to be in a usable state. If *set has been zeroed -// out, then set_ok(set) will be false and set_end(set) will be safe. */ -int set_ok(set_t *set) { + out, then set_ok(set) will be false and set_end(set) will be safe. */ +SKIPSET_EXPORT int set_ok(set_t *set) { return set->head != NULL && set->head->right != NULL && *(unsigned char *)&set->head->key == 137; } +#if 0 /* not used in minizip */ /* Empty the set. This frees the memory used for the previous set contents. -// After set_clear(), *set is ready for use, as if after a set_start(). */ -void set_clear(set_t *set) { + After set_clear(), *set is ready for use, as if after a set_start(). */ +SKIPSET_EXPORT void set_clear(set_t *set) { assert(set_ok(set) && "improper use"); /* Free all the keys and their nodes. */ set_sweep(set); /* Leave the head and path allocations as is. Clear their contents, with - // head pointing to itself and setting depth to zero, for an empty set. */ + head pointing to itself and setting depth to zero, for an empty set. */ set->head->right[0] = set->head; set->head->fill = 1; set->path->fill = 0; set->depth = 0; } +#endif /* Done using the set -- free all allocations. The only operation on *set -// permitted after this is set_start(). Though another set_end() would do no -// harm. This can be done at any time after a set_start(), or after a longjmp() -// on any allocation failure, including during a set_start(). */ -void set_end(set_t *set) { + permitted after this is set_start(). Though another set_end() would do no + harm. This can be done at any time after a set_start(), or after a longjmp() + on any allocation failure, including during a set_start(). */ +SKIPSET_EXPORT void set_end(set_t *set) { if (set->head != NULL) { /* Empty the set and free the head node. */ if (set->head->right != NULL) { @@ -296,13 +307,16 @@ void set_end(set_t *set) { } /* Look for key. Return 1 if found or 0 if not. This also puts the path to get -// there in set->path, for use by set_insert(). */ -int set_found(set_t *set, set_key_t key) { + there in set->path, for use by set_insert(). */ +SKIPSET_EXPORT int set_found(set_t *set, set_key_t key) { + set_node_t *head, *here; + int i; assert(set_ok(set) && "improper use"); - /* Start at depth and work down and right as determined by key comparisons. */ - set_node_t *head = set->head, *here = head; - int i = set->depth; + /* Start at depth. Work down and right as determined by key comparisons. */ + head = set->head; + here = head; + i = set->depth; set_grow(set, set->path, i + 1, 0); do { while (here->right[i] != head && @@ -316,8 +330,11 @@ int set_found(set_t *set, set_key_t key) { return here != head && set_cmp(here->key, key) == 0; } -/* Insert the key key. Return 0 on success, or 1 if key is already in the set. */ -int set_insert(set_t *set, set_key_t key) { +/* Insert the key key. Return 0 on success, or 1 if it's already in the set. */ +SKIPSET_EXPORT int set_insert(set_t *set, set_key_t key) { + int level = 0; + int bit; + int i; assert(set_ok(set) && "improper use"); if (set_found(set, key)) @@ -325,13 +342,12 @@ int set_insert(set_t *set, set_key_t key) { return 1; /* Randomly generate a new level-- level 0 with probability 1/2, 1 with - // probability 1/4, 2 with probability 1/8, etc. */ - int level = 0; + probability 1/4, 2 with probability 1/8, etc. */ for (;;) { if (set->ran == 1) /* Ran out. Get another 32 random bits. */ set->ran = set_rand(&set->gen) | (1ULL << 32); - int bit = set->ran & 1; + bit = set->ran & 1; set->ran >>= 1; if (bit) break; @@ -347,11 +363,10 @@ int set_insert(set_t *set, set_key_t key) { } /* Make a new node for the provided key, and insert it in the lists up to - // and including level. */ + and including level. */ set->node = set_node(set); set->node->key = key; set_grow(set, set->node, level + 1, 0); - int i; for (i = 0; i <= level; i++) { set->node->right[i] = set->path->right[i]->right[i]; set->path->right[i]->right[i] = set->node; diff --git a/zlib/contrib/minizip/test/CMakeLists.txt b/zlib/contrib/minizip/test/CMakeLists.txt index 822420185..d70a260a9 100644 --- a/zlib/contrib/minizip/test/CMakeLists.txt +++ b/zlib/contrib/minizip/test/CMakeLists.txt @@ -1,50 +1,43 @@ # if we are built from with zlib, use this path's) -if(DEFINED ZLIB_BUILD_MINIZIP) - set(WORK_DIR ${zlib_BINARY_DIR}) - set(inst_setup zlib_install) -else(DEFINED ZLIB_BUILD_MINIZIP) - set(WORK_DIR ${minizip_BINARY_DIR}) +if(NOT DEFINED ZLIB_BUILD_MINIZIP) + set(WORK_DIR ${CMAKE_CURRENT_BINARY_DIR}) set(inst_setup minizip_install) set(ZLIB_ARG "-DZLIB_DIR=${ZLIB_DIR}") add_test( NAME minizip_install - COMMAND ${CMAKE_COMMAND} --install ${minizip_BINARY_DIR} --prefix - ${CMAKE_CURRENT_BINARY_DIR}/test_install --config $ - WORKING_DIRECTORY ${minizip_BINARY_DIR}) + COMMAND ${CMAKE_COMMAND} + --install ${minizip_BINARY_DIR} + --prefix ${WORK_DIR}/test_install + --config $ + WORKING_DIRECTORY ${WORK_DIR}) set_tests_properties(minizip_install PROPERTIES FIXTURES_SETUP minizip_install) -endif(DEFINED ZLIB_BUILD_MINIZIP) - -file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/findpackage_test) -file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/findpackage_no_componentstest) -file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/findpackage_wrong_components_test) -file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/add_subdirectory_test) -file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/add_subdirectory_exclude_test) +endif(NOT DEFINED ZLIB_BUILD_MINIZIP) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/find_package_test.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/findpackage_test/CMakeLists.txt @ONLY) + ${WORK_DIR}/minizip_find_package_test/CMakeLists.txt @ONLY) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/find_package_no_components_test.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/findpackage_no_components_test/CMakeLists.txt + ${WORK_DIR}/minizip_find_package_no_components_test/CMakeLists.txt @ONLY) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/find_package_wrong_components_test.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/findpackage_wrong_components_test/CMakeLists.txt + ${WORK_DIR}/minizip_find_package_wrong_components_test/CMakeLists.txt @ONLY) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/add_subdirectory_test.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/add_subdirectory_test/CMakeLists.txt @ONLY) + ${WORK_DIR}/minizip_add_subdirectory_test/CMakeLists.txt @ONLY) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/add_subdirectory_exclude_test.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/add_subdirectory_exclude_test/CMakeLists.txt + ${WORK_DIR}/minizip_add_subdirectory_exclude_test/CMakeLists.txt @ONLY) # CMAKE_GENERATOR_PLATFORM doesn't work in the if @@ -55,69 +48,90 @@ if(GENERATOR) endif(GENERATOR) # -# findpackage_test +# find_package_test # add_test( NAME minizip_find_package_configure COMMAND - ${CMAKE_COMMAND} ${PLATFORM} - -B${CMAKE_CURRENT_BINARY_DIR}/findpackage_test_build - -DCMAKE_BUILD_TYPE=$ -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + ${CMAKE_COMMAND} + ${PLATFORM} + -B${WORK_DIR}/minizip_find_package_test_build + -DCMAKE_BUILD_TYPE=$ + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} - -DCMAKE_INSTALL_PREFIX=${WORK_DIR}/test/test_install ${ZLIB_ARG} - --fresh -G "${CMAKE_GENERATOR}" - -S${CMAKE_CURRENT_BINARY_DIR}/findpackage_test) + "-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}" + "-DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}" + -DCMAKE_INSTALL_PREFIX=${WORK_DIR}/test_install + ${ZLIB_ARG} + $<$:--fresh> + -G "${CMAKE_GENERATOR}" + -S${WORK_DIR}/minizip_find_package_test) add_test( NAME minizip_find_package_build COMMAND ${CMAKE_COMMAND} --build . --config $ - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/findpackage_test_build) + WORKING_DIRECTORY ${WORK_DIR}/minizip_find_package_test_build) -set_tests_properties( - minizip_find_package_configure PROPERTIES FIXTURES_REQUIRED ${inst_setup} - FIXTURES_SETUP mzfp_config) +set_tests_properties(minizip_find_package_configure + PROPERTIES + FIXTURES_REQUIRED ${inst_setup} + FIXTURES_SETUP mzfp_config) -set_tests_properties(minizip_find_package_build PROPERTIES FIXTURES_REQUIRED - mzfp_config) +set_tests_properties(minizip_find_package_build + PROPERTIES + FIXTURES_REQUIRED mzfp_config) # -# findpackage_no_components_test +# find_package_no_components_test # add_test( NAME minizip_find_package_no_components_configure COMMAND - ${CMAKE_COMMAND} ${PLATFORM} - -B${CMAKE_CURRENT_BINARY_DIR}/findpackage_no_components_test_build - -DCMAKE_BUILD_TYPE=$ -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + ${CMAKE_COMMAND} + ${PLATFORM} + -B${WORK_DIR}/minizip_find_package_no_components_test_build + -DCMAKE_BUILD_TYPE=$ + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} - -DCMAKE_INSTALL_PREFIX=${WORK_DIR}/test/test_install ${ZLIB_ARG} - --fresh -G "${CMAKE_GENERATOR}" - -S${CMAKE_CURRENT_BINARY_DIR}/findpackage_no_components_test) - -set_tests_properties( - minizip_find_package_no_components_configure PROPERTIES FIXTURES_REQUIRED ${inst_setup}) + "-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}" + "-DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}" + -DCMAKE_INSTALL_PREFIX=${WORK_DIR}/test_install + ${ZLIB_ARG} + $<$:--fresh> + -G "${CMAKE_GENERATOR}" + -S${WORK_DIR}/minizip_find_package_no_components_test) + +set_tests_properties(minizip_find_package_no_components_configure + PROPERTIES + FIXTURES_REQUIRED ${inst_setup}) if(NOT MINIZIP_BUILD_SHARED OR NOT MINIZIP_BUILD_STATIC) - set_tests_properties( - minizip_find_package_no_components_configure PROPERTIES WILL_FAIL TRUE) + set_tests_properties(minizip_find_package_no_components_configure + PROPERTIES + WILL_FAIL TRUE) endif(NOT MINIZIP_BUILD_SHARED OR NOT MINIZIP_BUILD_STATIC) # -# findpackage_no_components_test +# find_package_no_components_test # add_test( NAME minizip_find_package_wrong_components_configure COMMAND - ${CMAKE_COMMAND} ${PLATFORM} - -B${CMAKE_CURRENT_BINARY_DIR}/findpackage_wrong_components_test_build - -DCMAKE_BUILD_TYPE=$ -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + ${CMAKE_COMMAND} + ${PLATFORM} + -B${WORK_DIR}/minizip_find_package_wrong_components_test_build + -DCMAKE_BUILD_TYPE=$ + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} - -DCMAKE_INSTALL_PREFIX=${WORK_DIR}/test/test_install ${ZLIB_ARG} - --fresh -G "${CMAKE_GENERATOR}" - -S${CMAKE_CURRENT_BINARY_DIR}/findpackage_wrong_components_test) - -set_tests_properties( - minizip_find_package_wrong_components_configure + "-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}" + "-DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}" + -DCMAKE_INSTALL_PREFIX=${WORK_DIR}/test_install + ${ZLIB_ARG} + $<$:--fresh> + -G "${CMAKE_GENERATOR}" + -S${WORK_DIR}/minizip_find_package_wrong_components_test) + +set_tests_properties(minizip_find_package_wrong_components_configure PROPERTIES FIXTURES_REQUIRED ${inst_setup} WILL_FAIL TRUE) @@ -128,25 +142,32 @@ set_tests_properties( add_test( NAME minizip_add_subdirectory_configure COMMAND - ${CMAKE_COMMAND} ${PLATFORM} - -B${CMAKE_CURRENT_BINARY_DIR}/add_subdirectory_test_build - -DCMAKE_BUILD_TYPE=$ -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + ${CMAKE_COMMAND} + ${PLATFORM} + -B${WORK_DIR}/minizip_add_subdirectory_test_build + -DCMAKE_BUILD_TYPE=$ + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} - -DCMAKE_INSTALL_PREFIX=${WORK_DIR}/test/test_install ${ZLIB_ARG} - --fresh -G "${CMAKE_GENERATOR}" - -S${CMAKE_CURRENT_BINARY_DIR}/add_subdirectory_test) + "-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}" + "-DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}" + -DCMAKE_INSTALL_PREFIX=${WORK_DIR}/test_install ${ZLIB_ARG} + $<$:--fresh> + -G "${CMAKE_GENERATOR}" + -S${WORK_DIR}/minizip_add_subdirectory_test) add_test( NAME minizip_add_subdirectory_build COMMAND ${CMAKE_COMMAND} --build . --config $ - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/add_subdirectory_test_build) + WORKING_DIRECTORY ${WORK_DIR}/minizip_add_subdirectory_test_build) -set_tests_properties( - minizip_add_subdirectory_configure - PROPERTIES FIXTURES_REQUIRED ${inst_setup} FIXTURES_SETUP mzas_config) +set_tests_properties(minizip_add_subdirectory_configure + PROPERTIES + FIXTURES_REQUIRED ${inst_setup} + FIXTURES_SETUP mzas_config) -set_tests_properties(minizip_add_subdirectory_build PROPERTIES FIXTURES_REQUIRED - mzas_config) +set_tests_properties(minizip_add_subdirectory_build + PROPERTIES + FIXTURES_REQUIRED mzas_config) # # add_subdirectory_exclude_test @@ -154,23 +175,31 @@ set_tests_properties(minizip_add_subdirectory_build PROPERTIES FIXTURES_REQUIRED add_test( NAME minizip_add_subdirectory_exclude_configure COMMAND - ${CMAKE_COMMAND} ${PLATFORM} - -B${CMAKE_CURRENT_BINARY_DIR}/add_subdirectory_exclude_test_build - -DCMAKE_BUILD_TYPE=$ -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + ${CMAKE_COMMAND} + ${PLATFORM} + -B${WORK_DIR}/minizip_add_subdirectory_exclude_test_build + -DCMAKE_BUILD_TYPE=$ + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} - -DCMAKE_INSTALL_PREFIX=${WORK_DIR}/test/test_install ${ZLIB_ARG} - --fresh -G "${CMAKE_GENERATOR}" - -S${CMAKE_CURRENT_BINARY_DIR}/add_subdirectory_exclude_test) + "-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}" + "-DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}" + -DCMAKE_INSTALL_PREFIX=${WORK_DIR}/test_install + ${ZLIB_ARG} + $<$:--fresh> + -G "${CMAKE_GENERATOR}" + -S${WORK_DIR}/minizip_add_subdirectory_exclude_test) add_test( NAME minizip_add_subdirectory_exclude_build COMMAND ${CMAKE_COMMAND} --build . --config $ WORKING_DIRECTORY - ${CMAKE_CURRENT_BINARY_DIR}/add_subdirectory_exclude_test_build) + ${WORK_DIR}/minizip_add_subdirectory_exclude_test_build) -set_tests_properties( - minizip_add_subdirectory_exclude_configure - PROPERTIES FIXTURES_REQUIRED ${inst_setup} FIXTURES_SETUP mzasx_config) +set_tests_properties(minizip_add_subdirectory_exclude_configure + PROPERTIES + FIXTURES_REQUIRED ${inst_setup} + FIXTURES_SETUP mzasx_config) set_tests_properties(minizip_add_subdirectory_exclude_build - PROPERTIES FIXTURES_REQUIRED mzasx_config) + PROPERTIES + FIXTURES_REQUIRED mzasx_config) diff --git a/zlib/contrib/minizip/test/add_subdirectory_exclude_test.cmake.in b/zlib/contrib/minizip/test/add_subdirectory_exclude_test.cmake.in index 2b9fc68f3..c5a0878d5 100644 --- a/zlib/contrib/minizip/test/add_subdirectory_exclude_test.cmake.in +++ b/zlib/contrib/minizip/test/add_subdirectory_exclude_test.cmake.in @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.12...3.31) +cmake_minimum_required(VERSION 3.15...3.31) project( minizip_add_subdirectory_exclude_from_all diff --git a/zlib/contrib/minizip/test/add_subdirectory_test.cmake.in b/zlib/contrib/minizip/test/add_subdirectory_test.cmake.in index ca49895ba..a02d59612 100644 --- a/zlib/contrib/minizip/test/add_subdirectory_test.cmake.in +++ b/zlib/contrib/minizip/test/add_subdirectory_test.cmake.in @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.12...3.31) +cmake_minimum_required(VERSION 3.15...3.31) project( minizip_add_subdirectory_exclude_from_all diff --git a/zlib/contrib/minizip/test/find_package_no_components_test.cmake.in b/zlib/contrib/minizip/test/find_package_no_components_test.cmake.in index a235e4b98..c5dad90f6 100644 --- a/zlib/contrib/minizip/test/find_package_no_components_test.cmake.in +++ b/zlib/contrib/minizip/test/find_package_no_components_test.cmake.in @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.12...3.31) +cmake_minimum_required(VERSION 3.15...3.31) project( minizip_find_package diff --git a/zlib/contrib/minizip/test/find_package_test.cmake.in b/zlib/contrib/minizip/test/find_package_test.cmake.in index 7a7f85fc2..5da6afa1b 100644 --- a/zlib/contrib/minizip/test/find_package_test.cmake.in +++ b/zlib/contrib/minizip/test/find_package_test.cmake.in @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.12...3.31) +cmake_minimum_required(VERSION 3.15...3.31) project( minizip_find_package @@ -14,13 +14,19 @@ set(MINIZIP_SRCS @minizip_SOURCE_DIR@/minizip.c @minizip_SOURCE_DIR@/zip.c) if(MINIZIP_BUILD_SHARED) - find_package(minizip ${minizip_VERSION} CONFIG COMPONENTS shared REQUIRED) + find_package(minizip ${minizip_VERSION} + CONFIG + COMPONENTS shared + REQUIRED) add_executable(test_example ${MINIZIP_SRCS}) target_link_libraries(test_example MINIZIP::minizip) endif(MINIZIP_BUILD_SHARED) if(MINIZIP_BUILD_STATIC) - find_package(minizip ${minizip_VERSION} CONFIG COMPONENTS static REQUIRED) + find_package(minizip ${minizip_VERSION} + CONFIG + COMPONENTS static + REQUIRED) add_executable(test_example_static ${MINIZIP_SRCS}) target_link_libraries(test_example_static MINIZIP::minizipstatic) endif(MINIZIP_BUILD_STATIC) diff --git a/zlib/contrib/minizip/test/find_package_wrong_components_test.cmake.in b/zlib/contrib/minizip/test/find_package_wrong_components_test.cmake.in index d183760c0..8dc2f46ec 100644 --- a/zlib/contrib/minizip/test/find_package_wrong_components_test.cmake.in +++ b/zlib/contrib/minizip/test/find_package_wrong_components_test.cmake.in @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.12...3.31) +cmake_minimum_required(VERSION 3.15...3.31) project( minizip_find_package diff --git a/zlib/contrib/minizip/unzip.c b/zlib/contrib/minizip/unzip.c index d7ff21cb5..44ba47b8c 100644 --- a/zlib/contrib/minizip/unzip.c +++ b/zlib/contrib/minizip/unzip.c @@ -326,7 +326,7 @@ local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f unsigned char* buf; ZPOS64_T uSizeFile; ZPOS64_T uBackRead; - ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uMaxBack=0xffff+22; /* maximum comment and end-of-central-directory record */ ZPOS64_T uPosFound=CENTRALDIRINVALID; if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) @@ -362,7 +362,7 @@ local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) break; - for (i=(int)uReadSize-3; (i--)>0;) + for (i=(int)uReadSize-4; i>=0; --i) if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) { @@ -379,75 +379,29 @@ local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f /* - Locate the Central directory 64 of a zipfile (at the end, just before - the global comment) + Locate the ZIP64 end of central directory record using the locator immediately + preceding the classic end of central directory record. */ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream) { - unsigned char* buf; - ZPOS64_T uSizeFile; - ZPOS64_T uBackRead; - ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ - ZPOS64_T uPosFound=CENTRALDIRINVALID; + voidpf filestream, + ZPOS64_T centralDirPos) { + ZPOS64_T uPosFound; uLong uL; - ZPOS64_T relativeOffset; - - if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) - return CENTRALDIRINVALID; - - - uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); - - if (uMaxBack>uSizeFile) - uMaxBack = uSizeFile; - - buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); - if (buf==NULL) - return CENTRALDIRINVALID; - - uBackRead = 4; - while (uBackReaduMaxBack) - uBackRead = uMaxBack; - else - uBackRead+=BUFREADCOMMENT; - uReadPos = uSizeFile-uBackRead ; - - uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? - (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); - if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) - break; - - if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) - break; - - for (i=(int)uReadSize-3; (i--)>0;) - if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && - ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) - { - uPosFound = uReadPos+(unsigned)i; - break; - } + ZPOS64_T relativeOffset; - if (uPosFound!=CENTRALDIRINVALID) - break; - } - free(buf); - if (uPosFound == CENTRALDIRINVALID) + /* The ZIP64 locator immediately precedes the classic EOCD. Checking only + this position prevents a locator signature in file data from overriding + the central directory referenced by the actual EOCD. */ + if (centralDirPos == CENTRALDIRINVALID || centralDirPos < 20) return CENTRALDIRINVALID; - /* Zip64 end of central directory locator */ + uPosFound = centralDirPos - 20; if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) return CENTRALDIRINVALID; - /* the signature, already checked */ - if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK || + uL != 0x07064b50) return CENTRALDIRINVALID; - /* number of the disk with the start of the zip64 end of central directory */ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) return CENTRALDIRINVALID; @@ -493,6 +447,7 @@ local unzFile unzOpenInternal(const void *path, unz64_s us; unz64_s *s; ZPOS64_T central_pos; + ZPOS64_T central_pos64; uLong uL; uLong number_disk; /* number of the current disk, used for @@ -525,12 +480,16 @@ local unzFile unzOpenInternal(const void *path, if (us.filestream==NULL) return NULL; - central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream); - if (central_pos!=CENTRALDIRINVALID) + central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream); + central_pos64 = unz64local_SearchCentralDir64(&us.z_filefunc, + us.filestream, + central_pos); + if (central_pos64!=CENTRALDIRINVALID) { uLong uS; ZPOS64_T uL64; + central_pos = central_pos64; us.isZip64 = 1; if (ZSEEK64(us.z_filefunc, us.filestream, @@ -587,7 +546,6 @@ local unzFile unzOpenInternal(const void *path, } else { - central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream); if (central_pos==CENTRALDIRINVALID) err=UNZ_ERRNO; @@ -780,6 +738,8 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file, uLong uMagic; long lSeek=0; uLong uL; + unsigned zip64_required; + unsigned zip64_consumed = 0; if (file==NULL) return UNZ_PARAMERROR; @@ -850,6 +810,17 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file, err=UNZ_ERRNO; file_info_internal.offset_curfile = uL; + + /* Remember ZIP64 requirements before replacing any values. */ + if (err != UNZ_OK) + return err; + + zip64_required = + (file_info.uncompressed_size == MAXU32 ? 1U : 0U) | + (file_info.compressed_size == MAXU32 ? 2U : 0U) | + (file_info_internal.offset_curfile == MAXU32 ? 4U : 0U) | + (file_info.disk_num_start == 0xffff ? 8U : 0U); + lSeek+=file_info.size_filename; if ((err==UNZ_OK) && (szFileName!=NULL)) { @@ -913,51 +884,80 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file, while(acc < file_info.size_file_extra) { uLong headerId; - uLong dataSize; - - if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK) - err=UNZ_ERRNO; + uLong dataSize; + uLong used = 0; + uLong remaining = file_info.size_file_extra - acc; + + /* Every extra-field record starts with four bytes. */ + if (remaining < 4) + return UNZ_BADZIPFILE; + + if (unz64local_getShort(&s->z_filefunc, s->filestream, + &headerId) != UNZ_OK || + unz64local_getShort(&s->z_filefunc, s->filestream, + &dataSize) != UNZ_OK) + return UNZ_ERRNO; - if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK) - err=UNZ_ERRNO; + remaining -= 4; + if (dataSize > remaining) + return UNZ_BADZIPFILE; - /* ZIP64 extra fields */ + /* ZIP64 values must fit within this record. */ if (headerId == 0x0001) { - if(file_info.uncompressed_size == MAXU32) + if ((zip64_required & 1U) && !(zip64_consumed & 1U)) { - if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) - err=UNZ_ERRNO; + if (dataSize - used < 8) + return UNZ_BADZIPFILE; + if (unz64local_getLong64(&s->z_filefunc, s->filestream, + &file_info.uncompressed_size) != UNZ_OK) + return UNZ_ERRNO; + used += 8; + zip64_consumed |= 1U; } - if(file_info.compressed_size == MAXU32) + if ((zip64_required & 2U) && !(zip64_consumed & 2U)) { - if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) - err=UNZ_ERRNO; + if (dataSize - used < 8) + return UNZ_BADZIPFILE; + if (unz64local_getLong64(&s->z_filefunc, s->filestream, + &file_info.compressed_size) != UNZ_OK) + return UNZ_ERRNO; + used += 8; + zip64_consumed |= 2U; } - if(file_info_internal.offset_curfile == MAXU32) + if ((zip64_required & 4U) && !(zip64_consumed & 4U)) { - /* Relative Header offset */ - if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) - err=UNZ_ERRNO; + if (dataSize - used < 8) + return UNZ_BADZIPFILE; + if (unz64local_getLong64(&s->z_filefunc, s->filestream, + &file_info_internal.offset_curfile) != UNZ_OK) + return UNZ_ERRNO; + used += 8; + zip64_consumed |= 4U; } - if(file_info.disk_num_start == 0xffff) + if ((zip64_required & 8U) && !(zip64_consumed & 8U)) { - /* Disk Start Number */ - if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) - err=UNZ_ERRNO; + if (dataSize - used < 4) + return UNZ_BADZIPFILE; + if (unz64local_getLong(&s->z_filefunc, s->filestream, + &file_info.disk_num_start) != UNZ_OK) + return UNZ_ERRNO; + used += 4; + zip64_consumed |= 8U; } - - } - else - { - if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0) - err=UNZ_ERRNO; } - acc += 2 + 2 + dataSize; + /* Skip remaining bytes, but never leave this record. */ + if (used < dataSize && + ZSEEK64(s->z_filefunc, s->filestream, + dataSize - used, + ZLIB_FILEFUNC_SEEK_CUR) != 0) + return UNZ_ERRNO; + + acc += 4 + dataSize; } } @@ -1167,13 +1167,12 @@ extern int ZEXPORT unzLocateFile(unzFile file, const char *szFileName, int iCase /* -/////////////////////////////////////////// -// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) -// I need random access -// -// Further optimization could be realized by adding an ability -// to cache the directory in memory. The goal being a single -// comprehensive file read to put the file I need in a memory. + Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) + I need random access + + Further optimization could be realized by adding an ability + to cache the directory in memory. The goal being a single + comprehensive file read to put the file I need in a memory. */ /* @@ -1242,8 +1241,7 @@ extern int ZEXPORT unzGoToFilePos(unzFile file, unz_file_pos* file_pos) { } /* -// Unzip Helper Functions - should be here? -/////////////////////////////////////////// + Unzip Helper Functions - should be here? */ /* diff --git a/zlib/contrib/minizip/unzip.h b/zlib/contrib/minizip/unzip.h index 9c98b608c..c85c65e56 100644 --- a/zlib/contrib/minizip/unzip.h +++ b/zlib/contrib/minizip/unzip.h @@ -315,9 +315,10 @@ extern int ZEXPORT unzGetCurrentFileInfo(unzFile file, if szComment!=NULL, the comment string of the file will be copied in szComment (commentBufferSize is the size of the buffer) The file name and comment will be zero-terminated if there is room in the - provided buffer. Otherwise the buffer will contain as much as will fit. If at - least 65537 bytes of room is provided, then the result will always be - complete and zero-terminated. + provided buffer. Otherwise the buffer will contain as much as will fit. It is + up to the application to zero-terminate the string in that case, if it plans + to use the truncated result. If at least 65537 bytes of room is provided, then + the result will always be complete and zero-terminated. */ diff --git a/zlib/contrib/minizip/zip.c b/zlib/contrib/minizip/zip.c index 31005c51b..b263680bf 100644 --- a/zlib/contrib/minizip/zip.c +++ b/zlib/contrib/minizip/zip.c @@ -128,7 +128,8 @@ typedef struct linkedlist_data_s /* zipAlreadyThere() set functions for a set of zero-terminated strings, and -// a block_t type for reading the central directory datablocks. */ + a block_t type for reading the central directory datablocks. */ +#define SKIPSET_EXPORT static typedef char *set_key_t; #define set_cmp(a, b) strcmp(a, b) #define set_drop(s, k) set_free(s, k) @@ -286,18 +287,18 @@ local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) } /* zipAlreadyThere() operations. "set" in the zip internal structure keeps the -// set of names that are in the under-construction central directory so far. A -// skipset provides ~O(log n) time insertion and searching. Central directory -// records, stored in a linked list of allocated memory datablocks, is read -// through "block" in the zip internal structure. - -// The block_*() functions support extracting the central directory file names -// from the datablocks. They are designed to support a growing directory by -// automatically continuing once more data has been appended to the linked -// datablocks. - -// Initialize *block to the head of list. This should only be called once the -// list has at least some data in it, i.e. list->first_block is not NULL. */ + set of names that are in the under-construction central directory so far. A + skipset provides ~O(log n) time insertion and searching. Central directory + records, stored in a linked list of allocated memory datablocks, is read + through "block" in the zip internal structure. + + The block_*() functions support extracting the central directory file names + from the datablocks. They are designed to support a growing directory by + automatically continuing once more data has been appended to the linked + datablocks. + + Initialize *block to the head of list. This should only be called once the + list has at least some data in it, i.e. list->first_block is not NULL. */ local void block_init(block_t *block, linkedlist_data *list) { block->node = list->first_block; block->next = block->node->data; @@ -305,9 +306,10 @@ local void block_init(block_t *block, linkedlist_data *list) { } /* Mark *block as bad, with all subsequent reads returning end, even if more -// data is added to the datablocks. This is invoked if the central directory is -// invalid, so there is no longer any point in attempting to interpret it. */ + data is added to the datablocks. This is invoked if the central directory is + invalid, so there is no longer any point in attempting to interpret it. */ local void block_stop(block_t *block) { + block->node = NULL; block->left = 0; block->next = NULL; } @@ -357,7 +359,7 @@ local int block_get(block_t *block) { } /* Return a 16-bit unsigned little-endian value from block, or a negative value -// if the end is reached. */ + if the end is reached. */ local long block_get2(block_t *block) { int low = block_get(block); int high = block_get(block); @@ -367,6 +369,7 @@ local long block_get2(block_t *block) { /* Read up to len bytes from block into buf. Return the number of bytes read. */ local size_t block_read(block_t *block, unsigned char *buf, size_t len) { size_t need = len; + size_t take; while (need) { if (block->left == 0) { /* Get a byte to update and step through the linked list as needed. */ @@ -378,7 +381,7 @@ local size_t block_read(block_t *block, unsigned char *buf, size_t len) { need--; continue; } - size_t take = need > block->left ? block->left : need; + take = need > block->left ? block->left : need; memcpy(buf, block->next, take); block->next += take; block->left -= take; @@ -389,7 +392,7 @@ local size_t block_read(block_t *block, unsigned char *buf, size_t len) { } /* Skip n bytes in block. Return 0 on success or -1 if there are less than n -// bytes to the end. */ + bytes to the end. */ local int block_skip(block_t *block, size_t n) { while (n > block->left) { n -= block->left; @@ -405,9 +408,10 @@ local int block_skip(block_t *block, size_t n) { } /* Process the next central directory record at *block. Return the allocated, -// zero-terminated file name, or NULL for end of input or invalid data. If -// invalid, *block is marked bad. This uses *set for the allocation of memory. */ + zero-terminated file name, or NULL for end of input or invalid data. If + invalid, *block is marked bad. This uses *set for the allocation of memory. */ local char *block_central_name(block_t *block, set_t *set) { + unsigned flen, xlen, clen; char *name = NULL; for (;;) { if (block_end(block)) @@ -421,11 +425,11 @@ local char *block_central_name(block_t *block, set_t *set) { break; /* Go through the remaining fixed-length portion of the record, - // extracting the lengths of the three variable-length fields. */ + extracting the lengths of the three variable-length fields. */ block_skip(block, 24); - unsigned flen = (unsigned)block_get2(block); /* file name length */ - unsigned xlen = (unsigned)block_get2(block); /* extra length */ - unsigned clen = (unsigned)block_get2(block); /* comment length */ + flen = (unsigned)block_get2(block); /* file name length */ + xlen = (unsigned)block_get2(block); /* extra length */ + clen = (unsigned)block_get2(block); /* comment length */ if (block_skip(block, 12) == -1) /* Premature end of the record. */ break; @@ -440,10 +444,11 @@ local char *block_central_name(block_t *block, set_t *set) { /* Check for embedded nuls in the name. */ if (memchr(name, 0, flen) != NULL) { /* This name can never match the zero-terminated name provided to - // zipAlreadyThere(), so we discard it and go back to get another - // name. (Who the heck is putting nuls inside their zip file entry - // names anyway?) */ + zipAlreadyThere(), so we discard it and go back to get another + name. (Who the heck is putting nuls inside their zip file entry + names anyway?) */ set_free(set, name); + name = NULL; continue; } @@ -453,16 +458,19 @@ local char *block_central_name(block_t *block, set_t *set) { } /* Invalid signature or premature end of the central directory record. - // Abandon trying to process the central directory. */ + Abandon trying to process the central directory. */ set_free(set, name); block_stop(block); return NULL; } /* Return 0 if name is not in the central directory so far, 1 if it is, -1 if -// the central directory is invalid, -2 if out of memory, or ZIP_PARAMERROR if -// file is NULL. */ + the central directory is invalid, -2 if out of memory, or ZIP_PARAMERROR if + file is NULL. */ extern int ZEXPORT zipAlreadyThere(zipFile file, char const *name) { + size_t len; + char *copy; + int found; zip64_internal *zip = file; if (zip == NULL) return ZIP_PARAMERROR; @@ -476,14 +484,14 @@ extern int ZEXPORT zipAlreadyThere(zipFile file, char const *name) { } if (!set_ok(&zip->set)) { /* This is the first time here with some central directory content. We - // construct this set of names only on demand. Prepare set and block. */ + construct this set of names only on demand. Prepare set and block. */ set_start(&zip->set); block_init(&zip->block, &zip->central_dir); } /* Update the set of names from the current central directory contents. - // This reads any new central directory records since the last time we were - // here. */ + This reads any new central directory records since the last time we were + here. */ for (;;) { char *there = block_central_name(&zip->block, &zip->set); if (there == NULL) { @@ -496,15 +504,15 @@ extern int ZEXPORT zipAlreadyThere(zipFile file, char const *name) { /* Add there to the set. */ if (set_insert(&zip->set, there)) /* There's already a duplicate in the central directory! We'll just - // let this be and carry on. */ + let this be and carry on. */ set_free(&zip->set, there); } /* Return true if name is in the central directory. */ - size_t len = strlen(name); - char *copy = set_alloc(&zip->set, NULL, len + 1); + len = strlen(name); + copy = set_alloc(&zip->set, NULL, len + 1); memcpy(copy, name, len + 1); - int found = set_found(&zip->set, copy); + found = set_found(&zip->set, copy); set_free(&zip->set, copy); return found; } @@ -512,7 +520,6 @@ extern int ZEXPORT zipAlreadyThere(zipFile file, char const *name) { /****************************************************************************/ -#ifndef NO_ADDFILEINEXISTINGZIP /* =========================================================================== Inputs a long in LSB order to the given file nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T) @@ -574,6 +581,7 @@ local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm) { /****************************************************************************/ +#ifndef NO_ADDFILEINEXISTINGZIP local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int* pi) { unsigned char c; int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); @@ -697,7 +705,7 @@ local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f unsigned char* buf; ZPOS64_T uSizeFile; ZPOS64_T uBackRead; - ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uMaxBack=0xffff+22; /* maximum comment and end-of-central-directory record */ ZPOS64_T uPosFound=0; if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) @@ -733,7 +741,7 @@ local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) break; - for (i=(int)uReadSize-3; (i--)>0;) + for (i=(int)uReadSize-4; i>=0; --i) if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) { @@ -749,74 +757,28 @@ local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f } /* -Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before -the global comment) + Locate the Zip64 end of central directory record using the locator + immediately preceding the end of central directory record at + centralDirPos. */ -local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) { - unsigned char* buf; - ZPOS64_T uSizeFile; - ZPOS64_T uBackRead; - ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ - ZPOS64_T uPosFound=0; +local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, + ZPOS64_T centralDirPos) { + ZPOS64_T uPosFound; uLong uL; ZPOS64_T relativeOffset; - if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + /* The Zip64 locator immediately precedes the end of central directory + record. Checking only there prevents a locator signature in the file + data from overriding the central directory that record refers to. */ + if (centralDirPos < 20) return 0; - uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); - - if (uMaxBack>uSizeFile) - uMaxBack = uSizeFile; - - buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); - if (buf==NULL) - return 0; - - uBackRead = 4; - while (uBackReaduMaxBack) - uBackRead = uMaxBack; - else - uBackRead+=BUFREADCOMMENT; - uReadPos = uSizeFile-uBackRead ; - - uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? - (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); - if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) - break; - - if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) - break; - - for (i=(int)uReadSize-3; (i--)>0;) - { - /* Signature "0x07064b50" Zip64 end of central directory locator */ - if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) - { - uPosFound = uReadPos+(unsigned)i; - break; - } - } - - if (uPosFound!=0) - break; - } - - free(buf); - if (uPosFound == 0) - return 0; - - /* Zip64 end of central directory locator */ + uPosFound = centralDirPos - 20; if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) return 0; - /* the signature, already checked */ - if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK || + uL != 0x07064b50) return 0; /* number of the disk with the start of the zip64 end of central directory */ @@ -856,6 +818,7 @@ local int LoadCentralDirectoryRecord(zip64_internal* pziinit) { ZPOS64_T size_central_dir; /* size of the central directory */ ZPOS64_T offset_central_dir; /* offset of start of central directory */ ZPOS64_T central_pos; + ZPOS64_T central_pos64; uLong uL; uLong number_disk; /* number of the current disk, used for @@ -872,15 +835,15 @@ local int LoadCentralDirectoryRecord(zip64_internal* pziinit) { int hasZIP64Record = 0; - /* check first if we find a ZIP64 record */ - central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream); - if(central_pos > 0) + /* find the end of central directory record, and then a ZIP64 record if + there is one immediately before it */ + central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream); + central_pos64 = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream, + central_pos); + if (central_pos64 > 0) { hasZIP64Record = 1; - } - else if(central_pos == 0) - { - central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream); + central_pos = central_pos64; } /* disable to allow appending to empty ZIP archive @@ -939,7 +902,7 @@ local int LoadCentralDirectoryRecord(zip64_internal* pziinit) { err=ZIP_ERRNO; /* TODO.. - // read the comment from the standard central header. */ + read the comment from the standard central header. */ size_comment = 0; } else @@ -1024,7 +987,9 @@ local int LoadCentralDirectoryRecord(zip64_internal* pziinit) { ZPOS64_T size_central_dir_to_read = size_central_dir; size_t buf_size = SIZEDATA_INDATABLOCK; void* buf_read = (void*)ALLOC(buf_size); - if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) + if (buf_read == NULL) + err=ZIP_INTERNALERROR; + else if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) err=ZIP_ERRNO; while ((size_central_dir_to_read>0) && (err==ZIP_OK)) @@ -1049,6 +1014,11 @@ local int LoadCentralDirectoryRecord(zip64_internal* pziinit) { if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0) err=ZIP_ERRNO; + if (err != ZIP_OK) + { + ZCLOSE64(pziinit->z_filefunc, pziinit->filestream); + } + return err; } @@ -1107,22 +1077,25 @@ extern zipFile ZEXPORT zipOpen3(const void *pathname, int append, zipcharpc* glo err = LoadCentralDirectoryRecord(&ziinit); } - if (globalcomment) - { - *globalcomment = ziinit.globalcomment; - } # endif /* !NO_ADDFILEINEXISTINGZIP*/ if (err != ZIP_OK) { # ifndef NO_ADDFILEINEXISTINGZIP free(ziinit.globalcomment); + free_linkedlist(&(ziinit.central_dir)); # endif /* !NO_ADDFILEINEXISTINGZIP*/ free(zi); + if (globalcomment) + *globalcomment = NULL; return NULL; } else { +# ifndef NO_ADDFILEINEXISTINGZIP + if (globalcomment) + *globalcomment = ziinit.globalcomment; +# endif /* !NO_ADDFILEINEXISTINGZIP*/ *zi = ziinit; return (zipFile)zi; } @@ -1333,10 +1306,12 @@ extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char* filename, c return ZIP_PARAMERROR; if ((comment!=NULL) && (strlen(comment)>0xffff)) return ZIP_PARAMERROR; - /* The extra field length must fit in 16 bits. If the member also requires - // a Zip64 extra block, that will also need to fit within that 16-bit - // length, but that will be checked for later. */ - if ((size_extrafield_local>0xffff) || (size_extrafield_global>0xffff)) + /* The extra field lengths must fit in 16 bits, including a 20-byte + Zip64 sub-field in the local header if zip64 is true. There might + be a Zip64 sub-field needed in the central directory header as + well, but that won't be known until later. */ + if ((size_extrafield_local>(0xffffu-(zip64?20u:0u))) || + (size_extrafield_global>0xffffu)) return ZIP_PARAMERROR; zi = (zip64_internal*)file; @@ -1393,6 +1368,8 @@ extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char* filename, c zi->ci.size_centralExtraFree = 32; /* Extra space we have reserved in case we need to add ZIP64 extra info data */ zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree); + if (zi->ci.central_header == NULL) + return ZIP_INTERNALERROR; zi->ci.size_centralExtra = size_extrafield_global; zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4); @@ -1435,8 +1412,6 @@ extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char* filename, c for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+ size_extrafield_global+i) = *(comment+i); - if (zi->ci.central_header == NULL) - return ZIP_INTERNALERROR; zi->ci.zip64 = zip64; zi->ci.totalCompressedData = 0; @@ -1893,14 +1868,25 @@ extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_si if(datasize > 0) { char* p = NULL; + uLong size_comment; - if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree) + if (zi->ci.size_centralExtra + datasize + 4 > 0xffff) { - /* we cannot write more data to the buffer that we have room for. */ + /* the extra field is now too big with the Zip64 sub-field -- leave + this entry out of the central directory, so that the zip file can be + completed with the remaining entries, if desired */ + free(zi->ci.central_header); + zi->ci.central_header = NULL; + zi->in_opened_file_inzip = 0; return ZIP_BADZIPFILE; } - p = zi->ci.central_header + zi->ci.size_centralheader; + /* Insert the ZIP64 field at the end of the extra field, which is ahead + of the file comment, so move the comment up to make room. */ + size_comment = (unsigned char)zi->ci.central_header[32] | + ((uLong)(unsigned char)zi->ci.central_header[33] << 8); + p = zi->ci.central_header + zi->ci.size_centralheader - size_comment; + memmove(p + datasize + 4, p, size_comment); /* Add Extra Information Header for 'ZIP64 information' */ zip64local_putValue_inmemory(p, 0x0001, 2); /* HeaderID */ @@ -1927,8 +1913,8 @@ extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_si } /* Update how much extra free space we got in the memory buffer - // and increase the centralheader size so the new ZIP64 fields are included - // ( 4 below is the size of HeaderID and DataSize field ) */ + and increase the centralheader size so the new ZIP64 fields are included + ( 4 below is the size of HeaderID and DataSize field ) */ zi->ci.size_centralExtraFree -= datasize + 4; zi->ci.size_centralheader += datasize + 4; @@ -2191,25 +2177,45 @@ extern int ZEXPORT zipClose(zipFile file, const char* global_comment) { extern int ZEXPORT zipRemoveExtraInfoBlock(char* pData, int* dataLen, short sHeader) { char* p = pData; int size = 0; + int remaining; char* pNewHeader; char* pTmp; - short header; - short dataSize; + unsigned header; + unsigned dataSize; + unsigned remove = (unsigned short)sHeader; int retVal = ZIP_OK; if(pData == NULL || dataLen == NULL || *dataLen < 4) return ZIP_PARAMERROR; + remaining = *dataLen; pNewHeader = (char*)ALLOC((unsigned)*dataLen); + if (pNewHeader == NULL) + return ZIP_INTERNALERROR; + pTmp = pNewHeader; - while(p < (pData + *dataLen)) + while(remaining > 0) { - header = *(short*)p; - dataSize = *(((short*)p)+1); + if(remaining < 4) + { + retVal = ZIP_BADZIPFILE; + break; + } + + header = (unsigned)(unsigned char)p[0] | + ((unsigned)(unsigned char)p[1] << 8); + dataSize = (unsigned)(unsigned char)p[2] | + ((unsigned)(unsigned char)p[3] << 8); - if( header == sHeader ) /* Header found. */ + if((int)dataSize > remaining - 4) + { + retVal = ZIP_BADZIPFILE; + break; + } + + if( header == remove ) /* Header found. */ { p += dataSize + 4; /* skip it. do not copy to temp buffer */ } @@ -2217,10 +2223,18 @@ extern int ZEXPORT zipRemoveExtraInfoBlock(char* pData, int* dataLen, short sHea { /* Extra Info block should not be removed, So copy it to the temp buffer. */ memcpy(pTmp, p, dataSize + 4); + pTmp += dataSize + 4; p += dataSize + 4; size += dataSize + 4; } + remaining -= dataSize + 4; + } + + if(retVal != ZIP_OK) + { + free(pNewHeader); + return retVal; } if(size < *dataLen) diff --git a/zlib/contrib/minizip/zip.h b/zlib/contrib/minizip/zip.h index 996244078..d4f31112f 100644 --- a/zlib/contrib/minizip/zip.h +++ b/zlib/contrib/minizip/zip.h @@ -181,9 +181,14 @@ extern int ZEXPORT zipOpenNewFileInZip64(zipFile file, contains the extrafield data for the local header if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global contains the extrafield data for the global header - if comment != NULL, comment contain the comment string - method contain the compression method (0 for store, Z_DEFLATED for deflate) - level contain the level of compression (can be Z_DEFAULT_COMPRESSION) + size_extrafield_local and size_extrafield_global are limited to 65535 by + the format, or less depending on the presence of Zip64 subfields -- + size_extrafield_local needs to leave room for a 20-byte Zip64 subfield if + zip64 is true, and size_extrafield_global needs to leave room for a 12 to + 28 byte Zip64 subfield in case the offset or length exceeds 2^32-1 + if comment != NULL, comment contains the comment string + method contains the compression method (0 for store, Z_DEFLATED for deflate) + level contains the level of compression (can be Z_DEFAULT_COMPRESSION) zip64 is set to 1 if a zip64 extended information block should be added to the local file header. this MUST be '1' if the uncompressed size is >= 0xffffffff. diff --git a/zlib/contrib/pascal/zlibpas.pas b/zlib/contrib/pascal/zlibpas.pas index 603ff82e6..942ffae98 100644 --- a/zlib/contrib/pascal/zlibpas.pas +++ b/zlib/contrib/pascal/zlibpas.pas @@ -10,8 +10,8 @@ interface const - ZLIB_VERSION = '1.3.2'; - ZLIB_VERNUM = $12a0; + ZLIB_VERSION = '1.4'; + ZLIB_VERNUM = $1400; type alloc_func = function(opaque: Pointer; items, size: Integer): Pointer; diff --git a/zlib/crc32.c b/zlib/crc32.c index d9ade5150..32b1d0457 100644 --- a/zlib/crc32.c +++ b/zlib/crc32.c @@ -686,7 +686,7 @@ uLong ZEXPORT crc32_z(uLong crc, const unsigned char FAR *buf, z_size_t len) { #endif /* Initialize the CRC for each braid. */ - crc0 = crc; + crc0 = (z_crc_t)crc; #if N > 1 crc1 = 0; #if N > 2 diff --git a/zlib/deflate.c b/zlib/deflate.c index d7d2c7c1e..1e585aa62 100644 --- a/zlib/deflate.c +++ b/zlib/deflate.c @@ -52,7 +52,7 @@ #include "deflate.h" const char deflate_copyright[] = - " deflate 1.3.2 Copyright 1995-2026 Jean-loup Gailly and Mark Adler "; + " deflate 1.4 Copyright 1995-2026 Jean-loup Gailly and Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -445,7 +445,6 @@ int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, s->status = INIT_STATE; /* to pass state test in deflateReset() */ s->wrap = wrap; - s->gzhead = Z_NULL; s->w_bits = (uInt)windowBits; s->w_size = 1 << s->w_bits; s->w_mask = s->w_size - 1; @@ -568,7 +567,8 @@ int ZEXPORT deflateSetDictionary(z_streamp strm, const Bytef *dictionary, return Z_STREAM_ERROR; s = strm->state; wrap = s->wrap; - if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) + if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead || + (wrap == 0 && (long)s->strstart != s->block_start)) return Z_STREAM_ERROR; /* when using zlib wrappers, compute Adler-32 for provided dictionary */ @@ -671,7 +671,20 @@ int ZEXPORT deflateResetKeep(z_streamp strm) { adler32(0L, Z_NULL, 0); s->last_flush = -2; - _tr_init(s); + s->gzhead = Z_NULL; + + { + /* Retain the hash work done for level 0. */ + uInt matches = s->level == 0 ? s->matches : 0; + _tr_init(s); + s->matches = matches; + } + + /* Keep the window and the hash, but drop what was left unfinished */ + s->block_start = (long)s->strstart; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; return Z_OK; } @@ -683,6 +696,7 @@ local void lm_init(deflate_state *s) { s->window_size = (ulg)2L*s->w_size; CLEAR_HASH(s); + s->matches = 0; /* the hash is clear */ /* Set the default configuration parameters: */ @@ -745,18 +759,23 @@ int ZEXPORT deflateUsed(z_streamp strm, int *bits) { int ZEXPORT deflatePrime(z_streamp strm, int bits, int value) { deflate_state *s; int put; + int need; if (deflateStateCheck(strm)) return Z_STREAM_ERROR; s = strm->state; -#ifdef LIT_MEM - if (bits < 0 || bits > 16 || - (uchf *)s->d_buf < s->pending_out + ((Buf_size + 7) >> 3)) + if (bits < 0 || bits > 16) return Z_BUF_ERROR; -#else - if (bits < 0 || bits > 16 || - s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3)) + if (s->pending_out != s->pending_buf) { + /* move partially flushed pending output to buffer start */ + Bytef *to = s->pending_buf, *from = s->pending_out; + ulg n = s->pending; + while (n--) + *to++ = *from++; + s->pending_out = s->pending_buf; + } + need = (s->bi_valid + bits) >> 3; + if (s->pending_buf_size - s->pending < (ulg)need) return Z_BUF_ERROR; -#endif do { put = Buf_size - s->bi_valid; if (put > bits) @@ -1316,39 +1335,49 @@ int ZEXPORT deflateEnd(z_streamp strm) { */ int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) { #ifdef MAXSEG_64K - (void)dest; (void)source; + if (dest != Z_NULL) + dest->state = Z_NULL; return Z_STREAM_ERROR; #else deflate_state *ds; deflate_state *ss; - - if (deflateStateCheck(source) || dest == Z_NULL) { + if (dest == Z_NULL) + return Z_STREAM_ERROR; + if (deflateStateCheck(source)) { + dest->state = Z_NULL; return Z_STREAM_ERROR; } ss = source->state; - 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; + ds = (deflate_state *) ZALLOC(source, 1, sizeof(deflate_state)); + if (ds == Z_NULL) { + dest->state = Z_NULL; + return Z_MEM_ERROR; + } zmemcpy(ds, ss, sizeof(deflate_state)); - ds->strm = dest; - - ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); - ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); - ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, LIT_BUFS); - + ds->window = (Bytef *) ZALLOC(source, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(source, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(source, ds->hash_size, sizeof(Pos)); + ds->pending_buf = (uchf *) ZALLOC(source, ds->lit_bufsize, LIT_BUFS); if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || ds->pending_buf == Z_NULL) { - deflateEnd (dest); + TRY_FREE(source, ds->pending_buf); + TRY_FREE(source, ds->head); + TRY_FREE(source, ds->prev); + TRY_FREE(source, ds->window); + ZFREE(source, ds); + dest->state = Z_NULL; return Z_MEM_ERROR; } + + /* copy the stream and attach the new state */ + zmemcpy(dest, source, sizeof(z_stream)); + dest->state = (struct internal_state FAR *) ds; + ds->strm = dest; + /* following zmemcpy's do not work for 16-bit MSDOS */ zmemcpy(ds->window, ss->window, ss->high_water); zmemcpy(ds->prev, ss->prev, @@ -1641,7 +1670,10 @@ local void check_match(deflate_state *s, IPos start, IPos match, int length) { /* Same but force premature exit if necessary. */ #define FLUSH_BLOCK(s, last) { \ FLUSH_BLOCK_ONLY(s, last); \ - if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ + if (s->strm->avail_out == 0) { \ + if (!(last)) return need_more; \ + if (s->pending != 0 || s->wrap != 0) return finish_started; \ + } \ } /* Maximum stored block length in deflate format (not including header). */ @@ -1676,7 +1708,7 @@ local block_state deflate_stored(deflate_state *s, int flush) { * possible. If flushing, copy the remaining available input to next_out as * stored blocks, if there is enough space. */ - int last = 0; + int last = 0, all; unsigned len, left, have; unsigned used = s->strm->avail_in; do { @@ -1691,11 +1723,14 @@ local block_state deflate_stored(deflate_state *s, int flush) { /* maximum stored block length that will fit in avail_out: */ have = s->strm->avail_out - have; left = (unsigned)(s->strstart - s->block_start); /* window bytes */ - if (len > (ulg)left + s->strm->avail_in) + if (left < len && s->strm->avail_in < len - left) len = left + s->strm->avail_in; /* limit len to the input */ if (len > have) len = have; /* limit len to the output */ + /* all is true if len is all of the available input */ + all = len >= left && len - left == s->strm->avail_in; + /* If the stored block would be less than min_block in length, or if * unable to copy all of the available input when flushing, then try * copying to the window and the pending buffer instead. Also don't @@ -1703,13 +1738,13 @@ local block_state deflate_stored(deflate_state *s, int flush) { */ if (len < min_block && ((len == 0 && flush != Z_FINISH) || flush == Z_NO_FLUSH || - len != left + s->strm->avail_in)) + !all)) break; /* Make a dummy stored block in pending to get the header bytes, * including any pending bits. This also updates the debugging counts. */ - last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0; + last = flush == Z_FINISH && all ? 1 : 0; _tr_stored_block(s, (char *)0, 0L, last); /* Replace the lengths in the dummy stored block with len. */ @@ -2014,7 +2049,8 @@ local block_state deflate_slow(deflate_state *s, int flush) { 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, (int)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); diff --git a/zlib/gzguts.h b/zlib/gzguts.h index 266305deb..df4b0d670 100644 --- a/zlib/gzguts.h +++ b/zlib/gzguts.h @@ -92,8 +92,10 @@ # define vsnprintf _vsnprintf # endif # endif -# elif !defined(__STDC_VERSION__) || __STDC_VERSION__-0 < 199901L -/* Otherwise if C89/90, assume no C99 snprintf() or vsnprintf() */ +# elif (!defined(__STDC_VERSION__) || __STDC_VERSION__-0 < 199901L) && \ + (!defined(__cplusplus) || __cplusplus < 201103L) +/* Otherwise if C89/90 (and not C++11 or later), assume no C99 snprintf() or + vsnprintf() */ # ifndef NO_snprintf # define NO_snprintf # endif @@ -128,14 +130,28 @@ # include # define zstrerror() gz_strwinerror((DWORD)GetLastError()) #else +# include # ifndef NO_STRERROR -# include # define zstrerror() strerror(errno) # else # define zstrerror() "stdio error (consult errno)" # endif #endif +#ifdef EAGAIN +# ifdef EWOULDBLOCK +# define BLOCKED(e) ((e) == EAGAIN || (e) == EWOULDBLOCK) +# else +# define BLOCKED(e) ((e) == EAGAIN) +# endif +#else +# ifdef EWOULDBLOCK +# define BLOCKED(e) ((e) == EWOULDBLOCK) +# else +# define BLOCKED(e) (0) +# endif +#endif + /* provide prototypes for these when building zlib without LFS */ #if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); @@ -214,3 +230,10 @@ char ZLIB_INTERNAL *gz_strwinerror(DWORD error); (possible z_off64_t types off_t, off64_t, and long are all signed) */ unsigned ZLIB_INTERNAL gz_intmax(void); #define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) + +/* largest value representable in z_off64_t */ +#ifndef CHAR_BIT +# define CHAR_BIT 8 +#endif +#define GZ_OFF_MAX \ + ((((z_off64_t)1 << (sizeof(z_off64_t) * CHAR_BIT - 2)) - 1) * 2 + 1) diff --git a/zlib/gzlib.c b/zlib/gzlib.c index 7a37a96cf..c3b3efc27 100644 --- a/zlib/gzlib.c +++ b/zlib/gzlib.c @@ -68,9 +68,9 @@ char ZLIB_INTERNAL *gz_strwinerror(DWORD error) { /* Reset gzip file state */ local void gz_reset(gz_statep state) { state->x.have = 0; /* no output data available */ + state->past = 0; /* have not read past end yet */ if (state->mode == GZ_READ) { /* for reading ... */ 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 */ } @@ -88,9 +88,7 @@ local gzFile gz_open(const void *path, int fd, const char *mode) { gz_statep state; z_size_t len; int oflag = 0; -#ifdef O_EXCL int exclusive = 0; -#endif /* check input */ if (path == NULL || mode == NULL) @@ -136,11 +134,9 @@ local gzFile gz_open(const void *path, int fd, const char *mode) { oflag |= O_CLOEXEC; break; #endif -#ifdef O_EXCL case 'x': exclusive = 1; break; -#endif case 'f': state->strategy = Z_FILTERED; break; @@ -196,10 +192,21 @@ local gzFile gz_open(const void *path, int fd, const char *mode) { /* 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) */ +#ifndef O_EXCL + if (exclusive && state->mode != GZ_READ && fd < 0) { + /* exclusive creation request can't be honored -- fail out */ + free(state); + return NULL; + } +#endif + /* save the path name for error messages */ #ifdef WIDECHAR - if (fd == -2) + if (fd == -2) { len = wcstombs(NULL, path, 0); + if (len == (z_size_t)-1) + len = 0; /* not representable in the current locale */ + } else #endif len = strlen((const char *)path); @@ -210,9 +217,7 @@ local gzFile gz_open(const void *path, int fd, const char *mode) { } #ifdef WIDECHAR if (fd == -2) { - if (len) - wcstombs(state->path, path, len + 1); - else + if (len == 0 || wcstombs(state->path, path, len + 1) != len) *(state->path) = 0; } else @@ -221,7 +226,7 @@ local gzFile gz_open(const void *path, int fd, const char *mode) { #if !defined(NO_snprintf) && !defined(NO_vsnprintf) (void)snprintf(state->path, len + 1, "%s", (const char *)path); #else - strcpy(state->path, path); + strcpy(state->path, (const char *)path); #endif } @@ -255,9 +260,9 @@ local gzFile gz_open(const void *path, int fd, const char *mode) { if (oflag & O_NONBLOCK) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); #endif -#ifdef O_CLOEXEC +#if defined(O_CLOEXEC) && defined(FD_CLOEXEC) if (oflag & O_CLOEXEC) - fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | O_CLOEXEC); + fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); #endif state->fd = fd; } @@ -299,7 +304,7 @@ gzFile ZEXPORT gzdopen(int fd, const char *mode) { char *path; /* identifier for error messages */ gzFile gz; - if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) + if (fd < 0 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) return NULL; #if !defined(NO_snprintf) && !defined(NO_vsnprintf) (void)snprintf(path, 7 + 3 * sizeof(int), "", fd); @@ -366,7 +371,7 @@ int ZEXPORT gzrewind(gzFile file) { /* -- see zlib.h -- */ z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence) { unsigned n; - z_off64_t ret; + z_off64_t ret, pos; gz_statep state; /* get internal structure and check integrity */ @@ -384,18 +389,19 @@ z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence) { if (whence != SEEK_SET && whence != SEEK_CUR) return -1; - /* normalize offset to a SEEK_CUR specification */ - if (whence == SEEK_SET) - offset -= state->x.pos; - else { - offset += state->past ? 0 : state->skip; - state->skip = 0; - } + /* compute the absolute position */ + pos = whence == SEEK_SET ? 0 : + state->x.pos + (state->past ? 0 : state->skip); + if (offset > GZ_OFF_MAX - pos) + return -1; /* would overflow z_off64_t */ + if (offset < -pos) + return -1; /* before start of file */ + pos += offset; /* if within raw area while reading, just go there */ - if (state->mode == GZ_READ && state->how == COPY && - state->x.pos + offset >= 0) { - ret = LSEEK(state->fd, offset - (z_off64_t)state->x.have, SEEK_CUR); + if (state->mode == GZ_READ && state->how == COPY) { + ret = LSEEK(state->fd, pos - state->x.pos - (z_off64_t)state->x.have, + SEEK_CUR); if (ret == -1) return -1; state->x.have = 0; @@ -404,20 +410,18 @@ z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence) { state->skip = 0; gz_error(state, Z_OK, NULL); state->strm.avail_in = 0; - state->x.pos += offset; - return state->x.pos; + state->x.pos = pos; + return pos; } - /* calculate skip amount, rewinding if needed for back seek when reading */ - if (offset < 0) { + /* rewind if needed for back seek when reading */ + if (pos < state->x.pos) { if (state->mode != GZ_READ) /* writing -- can't go backwards */ return -1; - offset += state->x.pos; - if (offset < 0) /* before start of file! */ - return -1; - if (gzrewind(file) == -1) /* rewind, then skip to offset */ + if (gzrewind(file) == -1) /* rewind, then skip to pos */ return -1; } + offset = pos - state->x.pos; /* if reading, skip what's in output buffer (one less gzgetc() check) */ if (state->mode == GZ_READ) { @@ -431,7 +435,7 @@ z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence) { /* request skip (if not zero) */ state->skip = offset; - return state->x.pos + offset; + return pos; } /* -- see zlib.h -- */ @@ -560,10 +564,6 @@ void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg) { state->msg = NULL; } - /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ - if (err != Z_OK && err != Z_BUF_ERROR && !state->again) - state->x.have = 0; - /* set error code, and if no message, then done */ state->err = err; if (msg == NULL) diff --git a/zlib/gzread.c b/zlib/gzread.c index 45dd4dbfa..5359bb69c 100644 --- a/zlib/gzread.c +++ b/zlib/gzread.c @@ -33,7 +33,7 @@ local int gz_load(gz_statep state, unsigned char *buf, unsigned len, *have += (unsigned)ret; } while (*have < len); if (ret < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK) { + if (BLOCKED(errno)) { state->again = 1; if (*have != 0) return 0; @@ -125,6 +125,13 @@ local int gz_look(gz_statep state) { 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) { + /* wait for input before committing to another gzip member */ + if (state->junk == 0 && strm->avail_in == 0) { + if (gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) + return 0; + } inflateReset(strm); state->how = GZIP; state->junk = state->junk != -1; @@ -153,7 +160,7 @@ local int gz_look(gz_statep state) { strm->next_in[2] == 8 && strm->next_in[3] < 32) { inflateReset(strm); state->how = GZIP; - state->junk = 1; + state->junk = 0; state->direct = 0; return 0; } @@ -248,6 +255,11 @@ local int gz_decomp(gz_statep state) { local int gz_fetch(gz_statep state) { z_streamp strm = &(state->strm); + /* after a serious error, only what is already in the output buffer is + delivered -- don't try to decompress any more */ + if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again) + return -1; + do { switch(state->how) { case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ @@ -276,32 +288,46 @@ local int gz_fetch(gz_statep state) { return 0; } +/* Apply as much of a pending skip request as the output already available in + state->x allows. */ +local void gz_skip_have(gz_statep state) { + unsigned n; + + 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; + state->skip -= n; +} + /* 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 */ do { /* skip over whatever is in output buffer */ - if (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; - state->skip -= n; - } + if (state->x.have) + gz_skip_have(state); /* output buffer empty -- return if we're at the end of the input */ - else if (state->eof && state->strm.avail_in == 0) + else if (state->eof && state->strm.avail_in == 0) { + if (state->how == GZIP && state->err == Z_OK) + gz_error(state, Z_BUF_ERROR, "unexpected end of file"); + state->skip = 0; + state->past = 1; break; + } /* need more data to skip -- load up output buffer */ else { - /* get more output, looking for header if required */ - if (gz_fetch(state) == -1) + /* get more output, looking for header if required. If the fetch + stalled but provided some output, consume it before returning + so that x.have > 0 always implies the data is at the current + logical position (x.pos), as assumed by the gzgetc() fast path + in zlib.h and gzread.c */ + if (gz_fetch(state) == -1 && state->x.have == 0) return -1; } } while (state->skip); @@ -349,8 +375,11 @@ local z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) { } /* output buffer empty -- return if we're at the end of the input */ - else if (state->eof && state->strm.avail_in == 0) + else if (state->eof && state->strm.avail_in == 0) { + if (state->how == GZIP && state->err == Z_OK) + gz_error(state, Z_BUF_ERROR, "unexpected end of file"); break; + } /* need output data -- for small len or new stream load up our output buffer, so that gzgetc() can be fast */ @@ -403,15 +432,21 @@ int ZEXPORT gzread(gzFile file, voidp buf, unsigned len) { if (state->mode != GZ_READ) return -1; - /* check that there was no (serious) error */ - if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again) + /* check that there was no (serious) error -- if there was, deliver any + data read before the error until it is exhausted, and only then return + the error */ + if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again && + state->x.have == 0) return -1; - gz_error(state, Z_OK, NULL); + if (state->again) + 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) */ + with an error (this avoids a flaw in the interface) -- keep a pending + serious error, which is the one the caller needs to see */ if ((int)len < 0) { - gz_error(state, Z_STREAM_ERROR, "request does not fit in an int"); + if (state->err == Z_OK || state->err == Z_BUF_ERROR) + gz_error(state, Z_STREAM_ERROR, "request does not fit in an int"); return -1; } @@ -448,15 +483,22 @@ z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, if (state->mode != GZ_READ) return 0; - /* check that there was no (serious) error */ - if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again) + /* check that there was no (serious) error -- if there was, deliver any + data read before the error until it is exhausted, and only then return + the error */ + if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again && + state->x.have == 0) return 0; - gz_error(state, Z_OK, NULL); + if (state->again) + gz_error(state, Z_OK, NULL); - /* compute bytes to read -- error on overflow */ + /* compute bytes to read -- error on overflow, keeping a pending serious + error, which is the one the caller needs to see */ len = nitems * size; if (size && len / size != nitems) { - gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); + if (state->err == Z_OK || state->err == Z_BUF_ERROR) + gz_error(state, Z_STREAM_ERROR, + "request does not fit in a size_t"); return 0; } @@ -484,10 +526,14 @@ int ZEXPORT gzgetc(gzFile file) { if (state->mode != GZ_READ) return -1; - /* check that there was no (serious) error */ - if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again) + /* check that there was no (serious) error -- if there was, deliver any + data read before the error until it is exhausted, and only then return + the error, as the gzgetc() macro does */ + if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again && + state->x.have == 0) return -1; - gz_error(state, Z_OK, NULL); + if (state->again) + gz_error(state, Z_OK, NULL); /* try output buffer (no need to check for skip request) */ if (state->x.have) { @@ -519,10 +565,15 @@ int ZEXPORT gzungetc(int c, gzFile file) { if (state->how == LOOK && state->x.have == 0) (void)gz_look(state); - /* check that there was no (serious) error */ - if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again) + /* check that there was no (serious) error -- a character can still be + pushed back after one, since it is data that was read before the + error, and it will be returned before the error is signaled -- but only + if there is an output buffer to put it in */ + if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again && + state->size == 0) return -1; - gz_error(state, Z_OK, NULL); + if (state->again) + gz_error(state, Z_OK, NULL); /* process a skip request */ if (state->skip && gz_skip(state) == -1) @@ -544,7 +595,8 @@ int ZEXPORT gzungetc(int c, gzFile file) { /* if no room, give up (must have already done a gzungetc()) */ if (state->x.have == (state->size << 1)) { - gz_error(state, Z_DATA_ERROR, "out of room to push characters"); + if (state->err == Z_OK || state->err == Z_BUF_ERROR) + gz_error(state, Z_DATA_ERROR, "out of room to push characters"); return -1; } @@ -580,10 +632,14 @@ char * ZEXPORT gzgets(gzFile file, char *buf, int len) { if (state->mode != GZ_READ) return NULL; - /* check that there was no (serious) error */ - if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again) + /* check that there was no (serious) error -- if there was, deliver any + data read before the error until it is exhausted, and only then return + the error */ + if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again && + state->x.have == 0) return NULL; - gz_error(state, Z_OK, NULL); + if (state->again) + gz_error(state, Z_OK, NULL); /* process a skip request */ if (state->skip && gz_skip(state) == -1) @@ -595,8 +651,9 @@ char * ZEXPORT gzgets(gzFile file, char *buf, int len) { left = (unsigned)len - 1; if (left) do { /* assure that something is in the output buffer */ - if (state->x.have == 0 && gz_fetch(state) == -1) - break; /* error */ + if (state->x.have == 0 && gz_fetch(state) == -1 && + state->x.have == 0) + break; /* error, and nothing left to return */ if (state->x.have == 0) { /* end of file */ state->past = 1; /* read past end */ break; /* return what we have */ @@ -620,7 +677,7 @@ char * ZEXPORT gzgets(gzFile file, char *buf, int len) { /* 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) + if (buf == str && len > 1) return NULL; buf[0] = 0; return str; @@ -637,8 +694,10 @@ int ZEXPORT gzdirect(gzFile file) { /* if the state is not known, but we can find out, then do so (this is mainly for right after a gzopen() or gzdopen()) */ - if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) + if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) { (void)gz_look(state); + gz_skip_have(state); /* apply skip to current buffer */ + } /* return 1 if transparent, 0 if processing a gzip stream */ return state->direct == 1; diff --git a/zlib/gzwrite.c b/zlib/gzwrite.c index 13a3700a8..32560fe0b 100644 --- a/zlib/gzwrite.c +++ b/zlib/gzwrite.c @@ -41,8 +41,8 @@ local int gz_init(gz_statep state) { gz_error(state, Z_MEM_ERROR, "out of memory"); return -1; } - strm->next_in = NULL; } + strm->next_in = NULL; /* mark state as initialized */ state->size = state->want; @@ -79,7 +79,7 @@ local int gz_comp(gz_statep state, int flush) { put = strm->avail_in > max ? max : strm->avail_in; writ = (int)write(state->fd, strm->next_in, put); if (writ < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK) + if (BLOCKED(errno)) state->again = 1; gz_error(state, Z_ERRNO, zstrerror()); return -1; @@ -114,7 +114,7 @@ local int gz_comp(gz_statep state, int flush) { (unsigned)(strm->next_out - state->x.next); writ = (int)write(state->fd, state->x.next, put); if (writ < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK) + if (BLOCKED(errno)) state->again = 1; gz_error(state, Z_ERRNO, zstrerror()); return -1; @@ -156,6 +156,11 @@ local int gz_zero(gz_statep state) { unsigned n; z_streamp strm = &(state->strm); + /* allocate memory if this is the first time through -- the input buffer + must exist before it is zeroed below */ + if (state->size == 0 && gz_init(state) == -1) + return -1; + /* consume whatever's left in the input buffer */ if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) return -1; @@ -175,8 +180,14 @@ local int gz_zero(gz_statep state) { n -= strm->avail_in; state->x.pos += n; state->skip -= n; - if (ret == -1) + if (ret == -1) { + /* discard any unconsumed zero fill -- it was not yet accounted + for in state->skip, so it will be generated again when the + operation is retried */ + strm->avail_in = 0; + strm->next_in = state->in; return -1; + } } while (state->skip); return 0; } @@ -242,9 +253,13 @@ local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) { n -= state->strm.avail_in; state->x.pos += n; len -= n; - if (ret == -1) + if (ret == -1) { + state->strm.avail_in = 0; + state->strm.next_in = state->in; return state->again ? put - len : 0; + } } while (len); + state->strm.next_in = state->in; } /* input was all buffered or compressed */ @@ -371,9 +386,10 @@ int ZEXPORT gzputs(gzFile file, const char *s) { 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 (((!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 @@ -383,7 +399,8 @@ local int gz_vacate(gz_statep state) { z_streamp strm; strm = &(state->strm); - if (strm->next_in + strm->avail_in <= state->in + state->size) + if (strm->next_in == NULL || + strm->next_in + strm->avail_in <= state->in + state->size) return 0; (void)gz_comp(state, Z_NO_FLUSH); if (strm->avail_in == 0) { @@ -443,6 +460,7 @@ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) { 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"); + return state->err; } if (!state->again) return state->err; @@ -478,6 +496,14 @@ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) { /* write out buffer if more than half is occupied */ ret = gz_vacate(state); + if (ret) { + /* discard unwritten formatted output */ + strm->avail_in -= (unsigned)len; + state->x.pos -= len; + if (state->again) + gz_error(state, Z_BUF_ERROR, "stalled write on gzprintf"); + return state->err; + } if (state->err && !state->again) return state->err; return len; @@ -551,6 +577,7 @@ int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3, 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"); + return state->err; } if (!state->again) return state->err; @@ -591,6 +618,14 @@ int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3, /* write out buffer if more than half is occupied */ ret = gz_vacate(state); + if (ret) { + /* discard unwritten formatted output */ + strm->avail_in -= (unsigned)len; + state->x.pos -= len; + if (state->again) + gz_error(state, Z_BUF_ERROR, "stalled write on gzprintf"); + return state->err; + } if (state->err && !state->again) return state->err; return (int)len; diff --git a/zlib/infback.c b/zlib/infback.c index e6443feb4..ac96ba109 100644 --- a/zlib/infback.c +++ b/zlib/infback.c @@ -423,8 +423,6 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, /* use inflate_fast() if we have enough input and output */ if (have >= 6 && left >= 258) { RESTORE(); - if (state->whave < state->wsize) - state->whave = state->wsize - left; inflate_fast(strm, state->wsize); LOAD(); break; diff --git a/zlib/inflate.c b/zlib/inflate.c index 5f5d4922b..1aed58453 100644 --- a/zlib/inflate.c +++ b/zlib/inflate.c @@ -127,6 +127,14 @@ int ZEXPORT inflateReset(z_streamp strm) { if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; + if (state->wbits != state->reqbits) { + if (state->window != Z_NULL) { + ZFREE(strm, state->window); + state->window = Z_NULL; + } + state->wbits = state->reqbits; + } + state->wrap = state->reqwrap; state->wsize = 0; state->whave = 0; state->wnext = 0; @@ -165,8 +173,8 @@ int ZEXPORT inflateReset2(z_streamp strm, int windowBits) { } /* update state and reset the rest of it */ - state->wrap = wrap; - state->wbits = (unsigned)windowBits; + state->reqwrap = state->wrap = wrap; + state->reqbits = state->wbits = (unsigned)windowBits; return inflateReset(strm); } @@ -537,13 +545,13 @@ int ZEXPORT inflate(z_streamp strm, int flush) { } DROPBITS(4); len = BITS(4) + 8; - if (state->wbits == 0) - state->wbits = len; - if (len > 15 || len > state->wbits) { + if (len > 15 || (state->wbits != 0 && len > state->wbits)) { strm->msg = (z_const char *)"invalid window size"; state->mode = BAD; break; } + if (state->wbits == 0) + state->wbits = len; state->dmax = 1U << len; state->flags = 0; /* indicate zlib header */ Tracev((stderr, "inflate: zlib header ok\n")); @@ -700,6 +708,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) { case DICT: if (state->havedict == 0) { RESTORE(); + strm->total_in += in - strm->avail_in; return Z_NEED_DICT; } strm->adler = state->check = adler32(0L, Z_NULL, 0); @@ -912,7 +921,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) { state->mode = LEN; /* fallthrough */ case LEN: - if (have >= 6 && left >= 258) { + if (have >= 6 && left >= 258 && bits < 8) { RESTORE(); inflate_fast(strm, out); LOAD(); @@ -1191,7 +1200,8 @@ int ZEXPORT inflateSetDictionary(z_streamp strm, const Bytef *dictionary, int ret; /* check state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + if (inflateStateCheck(strm) || dictionary == Z_NULL) + return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (state->wrap != 0 && state->mode != DICT) return Z_STREAM_ERROR; @@ -1296,15 +1306,23 @@ int ZEXPORT inflateSync(z_streamp strm) { /* return no joy or set up to restart inflate() on a new block */ if (state->have != 4) return Z_DATA_ERROR; - if (state->flags == -1) - state->wrap = 0; /* if no header yet, treat as raw */ - else - state->wrap &= ~4; /* no point in computing a check value now */ flags = state->flags; in = strm->total_in; out = strm->total_out; inflateReset(strm); strm->total_in = in; strm->total_out = out; state->flags = flags; + if (flags == -1) + state->wrap = 0; /* if no header yet, treat as raw */ + else + state->wrap &= ~4; /* no point in computing a check value now */ + if (state->wbits == 0) { + /* we never got to see a header for the window size -- set to max */ + if (state->window != Z_NULL) { + ZFREE(strm, state->window); + state->window = Z_NULL; + } + state->wbits = 15; + } state->mode = TYPE; return Z_OK; } @@ -1331,14 +1349,21 @@ int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) { unsigned char FAR *window; /* check input */ - if (inflateStateCheck(source) || dest == Z_NULL) + if (dest == Z_NULL) return Z_STREAM_ERROR; + if (inflateStateCheck(source)) { + dest->state = Z_NULL; + return Z_STREAM_ERROR; + } state = (struct inflate_state FAR *)source->state; /* allocate space */ copy = (struct inflate_state FAR *) ZALLOC(source, 1, sizeof(struct inflate_state)); - if (copy == Z_NULL) return Z_MEM_ERROR; + if (copy == Z_NULL) { + dest->state = Z_NULL; + return Z_MEM_ERROR; + } zmemzero(copy, sizeof(struct inflate_state)); window = Z_NULL; if (state->window != Z_NULL) { @@ -1346,6 +1371,7 @@ int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) { ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); if (window == Z_NULL) { ZFREE(source, copy); + dest->state = Z_NULL; return Z_MEM_ERROR; } } @@ -1391,6 +1417,10 @@ int ZEXPORT inflateValidate(z_streamp strm, int check) { state->wrap |= 4; else state->wrap &= ~4; + if (check && state->reqwrap) + state->reqwrap |= 4; + else + state->reqwrap &= ~4; return Z_OK; } diff --git a/zlib/inflate.h b/zlib/inflate.h index f758e0dcc..e7dfc8e62 100644 --- a/zlib/inflate.h +++ b/zlib/inflate.h @@ -85,6 +85,7 @@ struct inflate_state { int last; /* true if processing last block */ int wrap; /* bit 0 true for zlib, bit 1 true for gzip, bit 2 true to validate check value */ + int reqwrap; /* requested wrap */ int havedict; /* true if dictionary provided */ int flags; /* gzip header method and flags, 0 if zlib, or -1 if raw or no header yet */ @@ -93,7 +94,8 @@ struct inflate_state { unsigned long total; /* protected copy of output count */ gz_headerp head; /* where to save gzip header information */ /* sliding window */ - unsigned wbits; /* log base 2 of requested window size */ + unsigned reqbits; /* requested log base 2 of window size */ + unsigned wbits; /* current log base 2 of window size */ unsigned wsize; /* window size or zero if not using window */ unsigned whave; /* valid bytes in the window */ unsigned wnext; /* window write index */ diff --git a/zlib/inftrees.c b/zlib/inftrees.c index dcbc64e05..0fb8570b0 100644 --- a/zlib/inftrees.c +++ b/zlib/inftrees.c @@ -23,7 +23,7 @@ #define MAXBITS 15 const char inflate_copyright[] = - " inflate 1.3.2 Copyright 1995-2026 Mark Adler "; + " inflate 1.4 Copyright 1995-2026 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -71,7 +71,7 @@ int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, 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, 199, 75}; + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 71, 77}; 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, diff --git a/zlib/inftrees.h b/zlib/inftrees.h index 84d053697..20eb2c03b 100644 --- a/zlib/inftrees.h +++ b/zlib/inftrees.h @@ -46,8 +46,14 @@ typedef struct { inflate_table() calls in inflate.c and infback.c. If the root table size is changed, then these maximum sizes would be need to be recalculated and updated. */ -#define ENOUGH_LENS 852 -#define ENOUGH_DISTS 592 +#ifndef PKZIP_BUG_WORKAROUND +# define ENOUGH_LENS 852 +# define ENOUGH_DISTS 592 +#else +/* That workaround permits 288 literal/length codes and 32 distance codes. */ +# define ENOUGH_LENS 854 +# define ENOUGH_DISTS 594 +#endif #define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) /* Type of code to build for inflate_table() */ diff --git a/zlib/qnx/package.qpg b/zlib/qnx/package.qpg index 82d65f4bb..cdfd124f0 100644 --- a/zlib/qnx/package.qpg +++ b/zlib/qnx/package.qpg @@ -25,10 +25,10 @@ - - - - + + + + @@ -63,7 +63,7 @@ - 1.3.2 + 1.4 Medium Stable diff --git a/zlib/test/infcover.c b/zlib/test/infcover.c index f1ad0f912..6a928a6f5 100644 --- a/zlib/test/infcover.c +++ b/zlib/test/infcover.c @@ -298,7 +298,7 @@ local void inf(char *hex, char *what, unsigned step, int win, unsigned len, mem_done(&strm, what); return; } - out = malloc(len); assert(out != NULL); + out = malloc(len ? len : 1); assert(out != NULL); if (win == 47) { head.extra = out; head.extra_max = len; @@ -361,6 +361,9 @@ local void cover_support(void) ret = inflatePrime(&strm, -1, 0); assert(ret == Z_OK); ret = inflateSetDictionary(&strm, Z_NULL, 0); assert(ret == Z_STREAM_ERROR); + ret = inflateReset2(&strm, -15); assert(ret == Z_OK); + ret = inflateSetDictionary(&strm, Z_NULL, 1); + assert(ret == Z_STREAM_ERROR); ret = inflateEnd(&strm); assert(ret == Z_OK); mem_done(&strm, "prime"); diff --git a/zlib/test/minigzip.c b/zlib/test/minigzip.c index 40da8736f..968220b76 100644 --- a/zlib/test/minigzip.c +++ b/zlib/test/minigzip.c @@ -37,6 +37,9 @@ #ifdef USE_MMAP # include # include +# ifndef MAP_FAILED +# define MAP_FAILED ((void *)-1) +# endif # include #endif @@ -337,7 +340,7 @@ static int gz_compress_mmap(FILE *in, gzFile out) { int len; int err; int ifd = fileno(in); - caddr_t buf; /* mmap'ed buffer for the entire input file */ + void *buf; /* mmap'ed buffer for the entire input file */ off_t buf_len; /* length of the input file */ struct stat sb; @@ -347,8 +350,8 @@ static int gz_compress_mmap(FILE *in, gzFile out) { if (buf_len <= 0) return Z_ERRNO; /* Now do the actual mmap: */ - buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0); - if (buf == (caddr_t)(-1)) return Z_ERRNO; + buf = mmap(NULL, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0); + if (buf == MAP_FAILED) return Z_ERRNO; /* Compress the whole file at once: */ len = gzwrite(out, (char *)buf, (unsigned)buf_len); diff --git a/zlib/treebuild.xml b/zlib/treebuild.xml index cd7d7a587..5f82ba667 100644 --- a/zlib/treebuild.xml +++ b/zlib/treebuild.xml @@ -1,6 +1,6 @@ - - + + zip compression library diff --git a/zlib/trees.c b/zlib/trees.c index 8e4da01e9..ae906655b 100644 --- a/zlib/trees.c +++ b/zlib/trees.c @@ -227,7 +227,7 @@ local void gen_codes(ct_data *tree, int max_code, ushf *bl_count) { tree[n].Code = (ush)bi_reverse(next_code[len]++, len); Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", - n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len] - 1)); + n, (isgraph(n & 0xff) ? n : ' '), len, tree[n].Code, next_code[len] - 1)); } } diff --git a/zlib/uncompr.c b/zlib/uncompr.c index 2195e7855..16a04ba27 100644 --- a/zlib/uncompr.c +++ b/zlib/uncompr.c @@ -33,8 +33,8 @@ int ZEXPORT uncompress2_z(Bytef *dest, z_size_t *destLen, const Bytef *source, const uInt max = (uInt)-1; z_size_t len, left; - if (sourceLen == NULL || (*sourceLen > 0 && source == NULL) || - destLen == NULL || (*destLen > 0 && dest == NULL)) + if (sourceLen == Z_NULL || (*sourceLen > 0 && source == Z_NULL) || + destLen == Z_NULL || (*destLen > 0 && dest == Z_NULL)) return Z_STREAM_ERROR; len = *sourceLen; diff --git a/zlib/win32/Makefile.msc b/zlib/win32/Makefile.msc index 9c6515360..d4cccdf92 100644 --- a/zlib/win32/Makefile.msc +++ b/zlib/win32/Makefile.msc @@ -45,7 +45,7 @@ $(IMPLIB): $(SHAREDLIB) $(SHAREDLIB): $(TOP)/win32/zlib.def $(OBJS) $(OBJA) zlib1.res $(LD) $(LDFLAGS) -def:$(TOP)/win32/zlib.def -dll -implib:$(IMPLIB) \ - -out:$@ -base:0x5A4C0000 $(OBJS) $(OBJA) zlib1.res + -out:$@ $(OBJS) $(OBJA) zlib1.res if exist $@.manifest \ mt -nologo -manifest $@.manifest -outputresource:$@;2 diff --git a/zlib/win32/README-WIN32.txt b/zlib/win32/README-WIN32.txt index 48c9120ae..155942b68 100644 --- a/zlib/win32/README-WIN32.txt +++ b/zlib/win32/README-WIN32.txt @@ -1,6 +1,6 @@ ZLIB DATA COMPRESSION LIBRARY -zlib 1.3.2 is a general purpose data compression library. All the code is +zlib 1.4 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 https://datatracker.ietf.org/doc/html/rfc1951 (zlib format), rfc1951.txt @@ -22,7 +22,7 @@ asking for help. Manifest: -The package zlib-1.3.2-win32-x86.zip will contain the following files: +The package zlib-1.4-win32-x86.zip will contain the following files: README-WIN32.txt This document ChangeLog Changes since previous zlib packages diff --git a/zlib/zconf.h b/zlib/zconf.h index 5860f2ea4..625a84705 100644 --- a/zlib/zconf.h +++ b/zlib/zconf.h @@ -501,6 +501,10 @@ typedef uLong FAR uLongf; #if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 # define Z_LFS64 +#elif defined(_WIN32) && !defined(__CYGWIN__) && !defined(__BORLANDC__) && \ + !defined(UNDER_CE) && (defined(__MINGW32__) || !defined(__GNUC__)) +# define Z_LFS64 /* native Windows has 64-bit file offsets */ +# define Z_WINLFS #endif #if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) @@ -518,7 +522,7 @@ typedef uLong FAR uLongf; #endif #ifndef z_off_t -# define z_off_t long long +# define z_off_t long #endif #if !defined(_WIN32) && defined(Z_LARGE64) @@ -533,6 +537,11 @@ typedef uLong FAR uLongf; # define z_off64_t z_off_t #endif +#if defined(Z_WINLFS) && defined(Z_WANT64) && !defined(Z_SOLO) +# undef z_off_t +# define z_off_t z_off64_t +#endif + /* MVS linker does not support external names larger than 8 bytes */ #if defined(__MVS__) #pragma map(deflateInit_,"DEIN") diff --git a/zlib/zconf.h.cmakein b/zlib/zconf.h.cmakein index 7248d547e..a27eeabbe 100644 --- a/zlib/zconf.h.cmakein +++ b/zlib/zconf.h.cmakein @@ -505,6 +505,10 @@ typedef uLong FAR uLongf; #if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 # define Z_LFS64 +#elif defined(_WIN32) && !defined(__CYGWIN__) && !defined(__BORLANDC__) && \ + !defined(UNDER_CE) && (defined(__MINGW32__) || !defined(__GNUC__)) +# define Z_LFS64 /* native Windows has 64-bit file offsets */ +# define Z_WINLFS #endif #if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) @@ -522,7 +526,7 @@ typedef uLong FAR uLongf; #endif #ifndef z_off_t -# define z_off_t long long +# define z_off_t long #endif #if !defined(_WIN32) && defined(Z_LARGE64) @@ -537,6 +541,11 @@ typedef uLong FAR uLongf; # define z_off64_t z_off_t #endif +#if defined(Z_WINLFS) && defined(Z_WANT64) && !defined(Z_SOLO) +# undef z_off_t +# define z_off_t z_off64_t +#endif + /* MVS linker does not support external names larger than 8 bytes */ #if defined(__MVS__) #pragma map(deflateInit_,"DEIN") diff --git a/zlib/zconf.h.in b/zlib/zconf.h.in index 5860f2ea4..625a84705 100644 --- a/zlib/zconf.h.in +++ b/zlib/zconf.h.in @@ -501,6 +501,10 @@ typedef uLong FAR uLongf; #if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 # define Z_LFS64 +#elif defined(_WIN32) && !defined(__CYGWIN__) && !defined(__BORLANDC__) && \ + !defined(UNDER_CE) && (defined(__MINGW32__) || !defined(__GNUC__)) +# define Z_LFS64 /* native Windows has 64-bit file offsets */ +# define Z_WINLFS #endif #if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) @@ -518,7 +522,7 @@ typedef uLong FAR uLongf; #endif #ifndef z_off_t -# define z_off_t long long +# define z_off_t long #endif #if !defined(_WIN32) && defined(Z_LARGE64) @@ -533,6 +537,11 @@ typedef uLong FAR uLongf; # define z_off64_t z_off_t #endif +#if defined(Z_WINLFS) && defined(Z_WANT64) && !defined(Z_SOLO) +# undef z_off_t +# define z_off_t z_off64_t +#endif + /* MVS linker does not support external names larger than 8 bytes */ #if defined(__MVS__) #pragma map(deflateInit_,"DEIN") diff --git a/zlib/zlib.3 b/zlib/zlib.3 index 70d5f1809..d6922c405 100644 --- a/zlib/zlib.3 +++ b/zlib/zlib.3 @@ -1,4 +1,4 @@ -.TH ZLIB 3 "17 Feb 2026" +.TH ZLIB 3 "4 Nov 2026" .SH NAME zlib \- compression/decompression library .SH SYNOPSIS @@ -105,7 +105,7 @@ before asking for help. Send questions and/or comments to zlib@gzip.org, or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). .SH AUTHORS AND LICENSE -Version 1.3.2 +Version 1.4 .LP Copyright (C) 1995-2026 Jean-loup Gailly and Mark Adler .LP diff --git a/zlib/zlib.3.pdf b/zlib/zlib.3.pdf index 0ec7c6ab29746a9190c33ef9a51e1eade8497227..a6e6c41ec172ece24394c3666b37999192a12721 100644 GIT binary patch delta 17792 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 WNh~S>Cp05N0|N^#RaIAiH!c7L<08xe delta 23769 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 + is set to Z_NULL with dest otherwise unchanged, so that deflateEnd(dest) can + be called safely, though dest is not a usable stream. */ ZEXTERN int ZEXPORT deflateReset(z_streamp strm); @@ -769,17 +771,17 @@ 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 - deflateInit2(), and after deflateSetHeader(), if used. This would be used - to allocate an output buffer for deflation in a single pass, and so would be - called before deflate(). If that first deflate() call is provided the - sourceLen input bytes, an output buffer allocated to the size returned by - deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed - 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 + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader() or deflateSetDictionary(), if + used. This would be used to allocate an output buffer for deflation in a + single pass, and so would be called before deflate(). If that first + deflate() call is provided the sourceLen input bytes, an output buffer + allocated to the size returned by deflateBound(), and the flush value + Z_FINISH, then deflate() is guaranteed 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. + + deflateBound_z() is the same, but takes and returns a size_t length. Note that a long is 32 bits on Windows. */ @@ -789,7 +791,7 @@ ZEXTERN int ZEXPORT deflatePending(z_streamp strm, /* deflatePending() returns the number of bytes and bits of output that have been generated, but not yet provided in the available output. The bytes not - provided would be due to the available output space having being consumed. + provided would be due to the available output space having been consumed. The number of bits of output not provided are between 0 and 7, where they await more bits to join them in order to fill out a full byte. If pending or bits are Z_NULL, then those values are not set. @@ -869,8 +871,7 @@ ZEXTERN int ZEXPORT inflateInit2(z_streamp strm, instead. windowBits must be greater than or equal to the windowBits value provided to deflateInit2() while compressing, or it must be equal to 15 if deflateInit2() was not used. If a compressed stream with a larger window - size is given as input, inflate() will return with the error code - Z_DATA_ERROR instead of trying to allocate a larger window. + size is given as input, inflate() may return with a Z_DATA_ERROR. windowBits can also be zero to request that inflate use the window size in the zlib header of the compressed stream. @@ -980,7 +981,9 @@ ZEXTERN int ZEXPORT inflateCopy(z_streamp dest, inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. + destination. If inflateCopy fails and dest is not Z_NULL, then dest->state + is set to Z_NULL with dest otherwise unchanged, so that inflateEnd(dest) can + be called safely, though dest is not a usable stream. */ ZEXTERN int ZEXPORT inflateReset(z_streamp strm); @@ -1095,9 +1098,10 @@ ZEXTERN int ZEXPORT inflateGetHeader(z_streamp strm, 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. + Though take care that none of the fields were truncated before so using it, + lest havoc ensue. 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 @@ -1394,8 +1398,8 @@ ZEXTERN gzFile ZEXPORT gzopen(const char *path, const char *mode); errno can be checked to determine if the reason gzopen failed was that the 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 + return NULL and errno will be EAGAIN or EWOULDBLOCK. 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. @@ -1501,9 +1505,12 @@ ZEXTERN z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, gzfread() returns the number of full items read of size size, or zero if the end of the file was reached and a full item could not be read, or if there was an error. gzerror() must be consulted if zero is returned in - order to determine 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 read, zero is returned, and the error state is set to Z_STREAM_ERROR. + order to determine if there was an error. If some data was read before an + error, then that data is returned until exhausted, after which the next call + will return zero and gzerror() will report the error. If the multiplication + of size and nitems overflows, i.e. the product does not fit in a z_size_t, + then nothing is read, zero is returned, and the error state is set to + Z_STREAM_ERROR. 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 @@ -1569,7 +1576,7 @@ ZEXTERN int ZEXPORTVA gzprintf(); 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. + the non-blocking write destination. The operation can be retried. */ ZEXTERN int ZEXPORT gzputs(gzFile file, const char *s); @@ -1677,7 +1684,9 @@ ZEXTERN z_off_t ZEXPORT gzseek(gzFile file, gzseek returns the resulting offset location as measured in bytes from the beginning of the uncompressed stream, or -1 in case of error, in particular if the file is opened for writing and the new starting position - would be before the current position. + would be before the current position, or if the resulting position would + not be representable in the offset type. If gzseek returns -1, the stream + position is unchanged. */ ZEXTERN int ZEXPORT gzrewind(gzFile file); @@ -1778,7 +1787,8 @@ ZEXTERN const char * ZEXPORT gzerror(gzFile file, int *errnum); 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. + code. The error is reported by gzerror() as soon as it is detected, which + may be before all of the data read prior to the error has been returned. The application must not modify the returned string. Future calls to this function may invalidate the previously returned string. If file is @@ -1976,7 +1986,8 @@ ZEXTERN int ZEXPORT gzgetc_(gzFile file); /* backward compatibility */ * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if * both are true, the application gets the *64 functions, and the regular * functions are changed to 64 bits) -- in case these are set on systems - * without large file support, _LFS64_LARGEFILE must also be true + * without large file support, _LFS64_LARGEFILE must also be true, except on + * native Windows, where 64-bit offsets are always available */ #ifdef Z_LARGE64 ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); @@ -1998,6 +2009,15 @@ ZEXTERN int ZEXPORT gzgetc_(gzFile file); /* backward compatibility */ # define z_crc32_combine z_crc32_combine64 # define z_crc32_combine_gen z_crc32_combine_gen64 # else +# ifdef Z_ACT_PREFIX_SET +# undef gzopen +# undef gzseek +# undef gztell +# undef gzoffset +# undef adler32_combine +# undef crc32_combine +# undef crc32_combine_gen +# endif # define gzopen gzopen64 # define gzseek gzseek64 # define gztell gztell64 @@ -2033,7 +2053,7 @@ ZEXTERN int ZEXPORT gzgetc_(gzFile file); /* backward compatibility */ #endif /* !Z_SOLO */ -/* undocumented functions */ +/* undocumented functions (not part of the zlib API) */ ZEXTERN const char * ZEXPORT zError(int); ZEXTERN int ZEXPORT inflateSyncPoint(z_streamp); ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table(void); diff --git a/zlib/zlib.pc.cmakein b/zlib/zlib.pc.cmakein index a392727c5..c8edaf65d 100644 --- a/zlib/zlib.pc.cmakein +++ b/zlib/zlib.pc.cmakein @@ -1,8 +1,8 @@ prefix=@CMAKE_INSTALL_PREFIX@ -exec_prefix=@CMAKE_INSTALL_PREFIX@ -libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ -sharedlibdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ -includedir=${exec_prefix}/@CMAKE_INSTALL_INCLUDEDIR@ +exec_prefix=${prefix} +libdir=@pc_libdir@ +sharedlibdir=${libdir} +includedir=@pc_includedir@ Name: zlib Description: zlib compression library diff --git a/zlib/zutil.c b/zlib/zutil.c index 4ea02a9c3..6c01021df 100644 --- a/zlib/zutil.c +++ b/zlib/zutil.c @@ -171,7 +171,6 @@ int ZLIB_INTERNAL zmemcmp(const void FAR *s1, const void FAR *s2, z_size_t n) { void ZLIB_INTERNAL zmemzero(void FAR *b, z_size_t len) { uchf *p = b; - if (len == 0) return; while (len) { *p++ = 0; len--; @@ -228,7 +227,11 @@ voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { } else { buf = farmalloc(bsize + 16L); } - if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + if (buf == NULL) return NULL; + if (next_ptr >= MAX_PTR) { + farfree(buf); + return NULL; + } table[next_ptr].org_ptr = buf; /* Normalize the pointer to seg:0 */