diff --git a/deps/zlib/CMakeLists.txt b/deps/zlib/CMakeLists.txt index f90e719ef4d34c..b569804ace0882 100644 --- a/deps/zlib/CMakeLists.txt +++ b/deps/zlib/CMakeLists.txt @@ -1,25 +1,75 @@ -cmake_minimum_required(VERSION 2.4.4...3.15.0) -set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) +cmake_minimum_required(VERSION 3.12...3.31) + +project( + zlib + LANGUAGES C + VERSION 1.3.2.1 + HOMEPAGE_URL "https://zlib.net/" + DESCRIPTION "a general-purpose lossless data-compression library") + +# ============================================================================ +# CPack +# ============================================================================ +set(CPACK_PACKAGE_VENDOR "zlib-Project") +set(CPACK_PACKAGE_DESCRIPTION_FILE ${zlib_SOURCE_DIR}/README) +set(CPACK_RESOURCE_FILE_LICENSE ${zlib_SOURCE_DIR}/LICENSE) +set(CPACK_RESOURCE_FILE_README ${zlib_SOURCE_DIR}/README) + +# ============================================================================ +# configuration +# ============================================================================ + +option(ZLIB_BUILD_TESTING "Enable Zlib Examples as tests" ON) +option(ZLIB_BUILD_SHARED "Enable building zlib shared library" ON) +option(ZLIB_BUILD_STATIC "Enable building zlib static library" ON) +option(ZLIB_INSTALL "Enable installation of zlib" ON) +option(ZLIB_PREFIX "prefix for all types and library functions, see zconf.h.in" + OFF) +mark_as_advanced(ZLIB_PREFIX) + +get_property(IS_MULTI GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + +if(NOT DEFINED CMAKE_BUILD_TYPE AND NOT IS_MULTI) + message(STATUS "No CMAKE_BUILD_TYPE set -- using Release") + set(CMAKE_BUILD_TYPE Release) +endif(NOT DEFINED CMAKE_BUILD_TYPE AND NOT IS_MULTI) -project(zlib C) - -set(VERSION "1.3.1") - -set(INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation directory for executables") -set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation directory for libraries") -set(INSTALL_INC_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "Installation directory for headers") -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") - -include(CheckTypeSize) +include(CheckCSourceCompiles) include(CheckFunctionExists) include(CheckIncludeFile) -include(CheckCSourceCompiles) -enable_testing() - -check_include_file(sys/types.h HAVE_SYS_TYPES_H) -check_include_file(stdint.h HAVE_STDINT_H) -check_include_file(stddef.h HAVE_STDDEF_H) +include(CMakePackageConfigHelpers) +include(CheckTypeSize) +include(CPack) +include(GNUInstallDirs) + +set(CPACK_INCLUDED TRUE) + +if(NOT ZLIB_CONF_WRITTEN) + set(Z_PREFIX ${ZLIB_PREFIX}) + set(CONF_OUT_FILE ${zlib_BINARY_DIR}/zconf.h.cmakein) + file(READ ${zlib_SOURCE_DIR}/zconf.h ZCONF_CONTENT LIMIT 245) + file(WRITE ${CONF_OUT_FILE} ${ZCONF_CONTENT}) + file(APPEND ${CONF_OUT_FILE} "#cmakedefine Z_PREFIX 1\n") + file(APPEND ${CONF_OUT_FILE} "#cmakedefine HAVE_STDARG_H 1\n") + file(APPEND ${CONF_OUT_FILE} "#cmakedefine HAVE_UNISTD_H 1\n") + file(READ ${zlib_SOURCE_DIR}/zconf.h ZCONF_CONTENT OFFSET 244) + set(FIRST_ITEM TRUE) + + foreach(item IN LISTS ZCONF_CONTENT) + if(FIRST_ITEM) + string(APPEND OUT_CONTENT ${item}) + set(FIRST_ITEM FALSE) + else(FIRST_ITEM) + string(APPEND OUT_CONTENT "\;" ${item}) + endif(FIRST_ITEM) + endforeach(item IN LISTS ${ZCONF_CONTENT}) + + file(APPEND ${CONF_OUT_FILE} ${OUT_CONTENT}) + set(ZLIB_CONF_WRITTEN + TRUE + CACHE BOOL "zconf.h.cmakein was created") + mark_as_advanced(ZLIB_CONF_WRITTEN) +endif(NOT ZLIB_CONF_WRITTEN) option(ENABLE_SIMD_OPTIMIZATIONS "Enable all SIMD optimizations" OFF) option(ENABLE_SIMD_AVX512 "Enable SIMD AXV512 optimizations" OFF) @@ -98,79 +148,58 @@ if (ENABLE_SIMD_OPTIMIZATIONS) # when we have a newer compiler available. SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --target=riscv64-unknown-linux-gnu -march=rv64gcv -Xclang -target-feature -Xclang +unaligned-scalar-mem") endif() - endif() # # Check to see if we have large file support # set(CMAKE_REQUIRED_DEFINITIONS -D_LARGEFILE64_SOURCE=1) -# We add these other definitions here because CheckTypeSize.cmake -# in CMake 2.4.x does not automatically do so and we want -# compatibility with CMake 2.4.x. -if(HAVE_SYS_TYPES_H) - list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_SYS_TYPES_H) -endif() -if(HAVE_STDINT_H) - list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDINT_H) -endif() -if(HAVE_STDDEF_H) - list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDDEF_H) -endif() check_type_size(off64_t OFF64_T) -if(HAVE_OFF64_T) - add_definitions(-D_LARGEFILE64_SOURCE=1) -endif() -set(CMAKE_REQUIRED_DEFINITIONS) # clear variable +unset(CMAKE_REQUIRED_DEFINITIONS) # clear variable # # Check for fseeko # check_function_exists(fseeko HAVE_FSEEKO) -if(NOT HAVE_FSEEKO) - add_definitions(-DNO_FSEEKO) -endif() + +# +# Check for stdarg.h +# +check_include_file(stdarg.h HAVE_STDARG_H) # # Check for unistd.h # -check_include_file(unistd.h Z_HAVE_UNISTD_H) +check_include_file(unistd.h HAVE_UNISTD_H) +# +# Check visibility attribute is supported +# if(MSVC) - set(CMAKE_DEBUG_POSTFIX "d") - add_definitions(-D_CRT_SECURE_NO_DEPRECATE) - add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) - include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -endif() - -if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) - # If we're doing an out of source build and the user has a zconf.h - # in their source tree... - if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h) - message(STATUS "Renaming") - message(STATUS " ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h") - message(STATUS "to 'zconf.h.included' because this file is included with zlib") - message(STATUS "but CMake generates it automatically in the build directory.") - file(RENAME ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.included) - endif() -endif() - -set(ZLIB_PC ${CMAKE_CURRENT_BINARY_DIR}/zlib.pc) -configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zlib.pc.cmakein - ${ZLIB_PC} @ONLY) -configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.cmakein - ${CMAKE_CURRENT_BINARY_DIR}/zconf.h @ONLY) -include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}) - - -#============================================================================ + set(CMAKE_REQUIRED_FLAGS "-WX") +else(MSVC) + set(CMAKE_REQUIRED_FLAGS "-Werror") +endif(MSVC) + +check_c_source_compiles( + " + #include + static void f(void) __attribute__ ((visibility(\"hidden\"))); + int main(void) {return 0;} + " + HAVE___ATTR__VIS_HIDDEN) + +unset(CMAKE_COMPILE_FLAGS) +set(ZLIB_PC ${zlib_BINARY_DIR}/zlib.pc) +configure_file(${zlib_SOURCE_DIR}/zlib.pc.cmakein ${ZLIB_PC} @ONLY) +configure_file(${zlib_BINARY_DIR}/zconf.h.cmakein ${zlib_BINARY_DIR}/zconf.h) + +# ============================================================================ # zlib -#============================================================================ +# ============================================================================ + +set(ZLIB_PUBLIC_HDRS ${zlib_BINARY_DIR}/zconf.h zlib.h) -set(ZLIB_PUBLIC_HDRS - ${CMAKE_CURRENT_BINARY_DIR}/zconf.h - zlib.h -) set(ZLIB_PRIVATE_HDRS crc32.h deflate.h @@ -180,8 +209,8 @@ set(ZLIB_PRIVATE_HDRS inflate.h inftrees.h trees.h - zutil.h -) + zutil.h) + set(ZLIB_SRCS adler32.c compress.c @@ -197,8 +226,12 @@ set(ZLIB_SRCS inffast.c trees.c uncompr.c - zutil.c -) + zutil.c) + +if(WIN32) + set(zlib_static_suffix "s") + set(CMAKE_DEBUG_POSTFIX "d") +endif(WIN32) #============================================================================ @@ -250,34 +283,6 @@ if (ENABLE_INTEL_QAT_COMPRESSION) add_compile_definitions(QAT_COMPRESSION_ENABLED) endif() -# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION -file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents) -string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*" - "\\1" ZLIB_FULL_VERSION ${_zlib_h_contents}) - -if(MINGW) - # This gets us DLL resource information when compiling on MinGW. - if(NOT CMAKE_RC_COMPILER) - set(CMAKE_RC_COMPILER windres.exe) - endif() - - add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj - COMMAND ${CMAKE_RC_COMPILER} - -D GCC_WINDRES - -I ${CMAKE_CURRENT_SOURCE_DIR} - -I ${CMAKE_CURRENT_BINARY_DIR} - -o ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj - -i ${CMAKE_CURRENT_SOURCE_DIR}/win32/zlib1.rc) - set(ZLIB_DLL_SRCS ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj) -endif(MINGW) - -add_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_DLL_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) -target_include_directories(zlib PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) -add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) -target_include_directories(zlibstatic PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) -set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL) -set_target_properties(zlib PROPERTIES SOVERSION 1) - if (ENABLE_INTEL_QAT_COMPRESSION) target_include_directories(zlib PUBLIC ${QATZPP_INCLUDE_DIRS}) target_link_libraries(zlib ${QATZPP_LIBRARY}) @@ -287,43 +292,150 @@ if (ENABLE_INTEL_QAT_COMPRESSION) target_link_libraries(zlibstatic qat) endif() -if(NOT CYGWIN) - # This property causes shared libraries on Linux to have the full version - # encoded into their final filename. We disable this on Cygwin because - # it causes cygz-${ZLIB_FULL_VERSION}.dll to be created when cygz.dll - # seems to be the default. - # - # This has no effect with MSVC, on that platform the version info for - # the DLL comes from the resource file win32/zlib1.rc - set_target_properties(zlib PROPERTIES VERSION ${ZLIB_FULL_VERSION}) -endif() - -if(UNIX) - # On unix-like platforms the library is almost always called libz - set_target_properties(zlib zlibstatic PROPERTIES OUTPUT_NAME z) - if(NOT APPLE) - set_target_properties(zlib PROPERTIES LINK_FLAGS "-Wl,--version-script,\"${CMAKE_CURRENT_SOURCE_DIR}/zlib.map\"") - endif() -elseif(BUILD_SHARED_LIBS AND WIN32) - # Creates zlib1.dll when building shared library version - set_target_properties(zlib PROPERTIES SUFFIX "1.dll") -endif() - -if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL ) - install(TARGETS zlib zlibstatic - RUNTIME DESTINATION "${INSTALL_BIN_DIR}" - ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" - LIBRARY DESTINATION "${INSTALL_LIB_DIR}" ) -endif() -if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL ) - install(FILES ${ZLIB_PUBLIC_HDRS} DESTINATION "${INSTALL_INC_DIR}") -endif() -if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL ) - install(FILES zlib.3 DESTINATION "${INSTALL_MAN_DIR}/man3") -endif() -if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL ) - install(FILES ${ZLIB_PC} DESTINATION "${INSTALL_PKGCONFIG_DIR}") -endif() +if(ZLIB_BUILD_SHARED) + add_library( + zlib SHARED ${ZLIB_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS} + $<$,$>:win32/zlib1.rc>) + add_library(ZLIB::ZLIB ALIAS zlib) + target_include_directories( + zlib + PUBLIC $ + $ + $) + target_compile_definitions( + zlib + PRIVATE ZLIB_BUILD + $<$:NO_FSEEKO> + $<$:HAVE_HIDDEN> + $<$:_CRT_SECURE_NO_DEPRECATE> + $<$:_CRT_NONSTDC_NO_DEPRECATE> + PUBLIC $<$:_LARGEFILE64_SOURCE=1>) + set(INSTALL_VERSION ${zlib_VERSION}) + + if(NOT CYGWIN) + set_target_properties(zlib PROPERTIES SOVERSION ${zlib_VERSION_MAJOR} + VERSION ${INSTALL_VERSION}) + endif(NOT CYGWIN) + + set_target_properties( + zlib + PROPERTIES DEFINE_SYMBOL ZLIB_DLL + EXPORT_NAME ZLIB + OUTPUT_NAME z) + if(UNIX + AND NOT APPLE + AND NOT (CMAKE_SYSTEM_NAME STREQUAL AIX) + AND NOT (CMAKE_SYSTEM_NAME STREQUAL SunOS)) + # On unix-like platforms the library is almost always called libz + set_target_properties( + zlib + PROPERTIES LINK_FLAGS + "-Wl,--version-script,\"${zlib_SOURCE_DIR}/zlib.map\"") + endif( + UNIX + AND NOT APPLE + AND NOT (CMAKE_SYSTEM_NAME STREQUAL AIX) + AND NOT (CMAKE_SYSTEM_NAME STREQUAL SunOS)) +endif(ZLIB_BUILD_SHARED) + +if(ZLIB_BUILD_STATIC) + add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_PUBLIC_HDRS} + ${ZLIB_PRIVATE_HDRS}) + add_library(ZLIB::ZLIBSTATIC ALIAS zlibstatic) + target_include_directories( + zlibstatic + PUBLIC $ + $ + $) + target_compile_definitions( + zlibstatic + PRIVATE ZLIB_BUILD + $<$:NO_FSEEKO> + $<$:HAVE_HIDDEN> + $<$:_CRT_SECURE_NO_DEPRECATE> + $<$:_CRT_NONSTDC_NO_DEPRECATE> + PUBLIC $<$:_LARGEFILE64_SOURCE=1>) + set_target_properties( + zlibstatic PROPERTIES EXPORT_NAME ZLIBSTATIC OUTPUT_NAME + z${zlib_static_suffix}) +endif(ZLIB_BUILD_STATIC) + +if(ZLIB_INSTALL) + if(ZLIB_BUILD_SHARED) + install( + TARGETS zlib + COMPONENT Runtime + EXPORT zlibSharedExport + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") + install( + EXPORT zlibSharedExport + FILE ZLIB-shared.cmake + NAMESPACE ZLIB:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/zlib) + + if(MSVC) + install( + FILES $ + COMPONENT Runtime + DESTINATION ${CMAKE_INSTALL_BINDIR} + CONFIGURATIONS Debug OR RelWithDebInfo + OPTIONAL) + endif(MSVC) + endif(ZLIB_BUILD_SHARED) + + if(ZLIB_BUILD_STATIC) + install( + TARGETS zlibstatic + COMPONENT Development + EXPORT zlibStaticExport + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") + install( + EXPORT zlibStaticExport + FILE ZLIB-static.cmake + NAMESPACE ZLIB:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/zlib) + endif(ZLIB_BUILD_STATIC) + + configure_package_config_file( + ${zlib_SOURCE_DIR}/zlibConfig.cmake.in + ${zlib_BINARY_DIR}/ZLIBConfig.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/zlib) + + write_basic_package_version_file( + "${zlib_BINARY_DIR}/ZLIBConfigVersion.cmake" + VERSION "${zlib_VERSION}" + COMPATIBILITY AnyNewerVersion) + + install(FILES ${zlib_BINARY_DIR}/ZLIBConfig.cmake + ${zlib_BINARY_DIR}/ZLIBConfigVersion.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/zlib) + install( + FILES ${ZLIB_PUBLIC_HDRS} + COMPONENT Development + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") + install( + FILES zlib.3 + COMPONENT Docs + DESTINATION "${CMAKE_INSTALL_MANDIR}/man3") + install( + FILES LICENSE + doc/algorithm.txt + doc/crc-doc.1.0.pdf + doc/rfc1950.txt + doc/rfc1951.txt + doc/rfc1952.txt + doc/txtvsbin.txt + COMPONENT Docs + DESTINATION "${CMAKE_INSTALL_DOCDIR}/zlib") + install( + FILES ${ZLIB_PC} + COMPONENT Development + DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") +endif(ZLIB_INSTALL) #============================================================================ # Benchmarker diff --git a/deps/zlib/LICENSE b/deps/zlib/LICENSE index 8aca25d8c7a133..b7a69d058e6166 100644 --- a/deps/zlib/LICENSE +++ b/deps/zlib/LICENSE @@ -1,19 +1,22 @@ -version 1.2.12, March 27th, 2022 +Copyright notice: -Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler + (C) 1995-2026 Jean-loup Gailly and Mark Adler -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: -1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. -2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu diff --git a/deps/zlib/README b/deps/zlib/README new file mode 100644 index 00000000000000..e28388bfefa982 --- /dev/null +++ b/deps/zlib/README @@ -0,0 +1,115 @@ +ZLIB DATA COMPRESSION LIBRARY + +zlib 1.3.2.1 is a general purpose data compression library. All the code is +thread safe (though see the FAQ for caveats). The data format used by the zlib +library is described by RFCs (Request for Comments) 1950 to 1952 at +https://datatracker.ietf.org/doc/html/rfc1950 (zlib format), rfc1951 (deflate +format) and rfc1952 (gzip format). + +All functions of the compression library are documented in the file zlib.h +(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example +of the library is given in the file test/example.c which also tests that +the library is working correctly. Another example is given in the file +test/minigzip.c. The compression library itself is composed of all source +files in the root directory. + +To compile all files and run the test program, follow the instructions given at +the top of Makefile.in. In short "./configure; make test", and if that goes +well, "make install" should work for most flavors of Unix. For Windows, use +one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use +make_vms.com. + +Questions about zlib should be sent to , or to Gilles Vollant + for the Windows DLL version. The zlib home page is +https://zlib.net/ . Before reporting a problem, please check this site to +verify that you have the latest version of zlib; otherwise get the latest +version and check whether the problem still exists or not. + +PLEASE read the zlib FAQ https://zlib.net/zlib_faq.html before asking for help. + +Mark Nelson wrote an article about zlib for the Jan. 1997 +issue of Dr. Dobb's Journal; a copy of the article is available at +https://zlib.net/nelson/ . + +The changes made in version 1.3.2.1 are documented in the file ChangeLog. + +Unsupported third party contributions are provided in directory contrib/ . + +zlib is available in Java using the java.util.zip package. Follow the API +Documentation link at: https://docs.oracle.com/search/?q=java.util.zip . + +A Perl interface to zlib and bzip2 written by Paul Marquess +can be found at https://github.com/pmqs/IO-Compress . + +A Python interface to zlib written by A.M. Kuchling is +available in Python 1.5 and later versions, see +https://docs.python.org/3/library/zlib.html . + +zlib is built into tcl: https://wiki.tcl-lang.org/page/zlib . + +An experimental package to read and write files in .zip format, written on top +of zlib by Gilles Vollant , is available in the +contrib/minizip directory of zlib. + + +Notes for some targets: + +- For Windows DLL versions, please see win32/DLL_FAQ.txt + +- For 64-bit Irix, deflate.c must be compiled without any optimization. With + -O, one libpng test fails. The test works in 32 bit mode (with the -n32 + compiler flag). The compiler bug has been reported to SGI. + +- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works + when compiled with cc. + +- On Digital Unix 4.0D (formerly OSF/1) on AlphaServer, the cc option -std1 is + necessary to get gzprintf working correctly. This is done by configure. + +- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with + other compilers. Use "make test" to check your compiler. + +- For PalmOs, see https://palmzlib.sourceforge.net/ + + +Acknowledgments: + + The deflate format used by zlib was defined by Phil Katz. The deflate and + zlib specifications were written by L. Peter Deutsch. Thanks to all the + people who reported problems and suggested various improvements in zlib; they + are too numerous to cite here. + +Copyright notice: + + (C) 1995-2026 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* receiving +lengthy legal documents to sign. The sources are provided for free but without +warranty of any kind. The library has been entirely written by Jean-loup +Gailly and Mark Adler; it does not include third-party code. We make all +contributions to and distributions of this project solely in our personal +capacity, and are not conveying any rights to any intellectual property of +any third parties. + +If you redistribute modified sources, we would appreciate that you include in +the file ChangeLog history information documenting your changes. Please read +the FAQ for more information on the distribution of modified source versions. diff --git a/deps/zlib/README.chromium b/deps/zlib/README.chromium index b98a65addb10e6..232ef66aeb2b44 100644 --- a/deps/zlib/README.chromium +++ b/deps/zlib/README.chromium @@ -1,10 +1,10 @@ Name: zlib Short Name: zlib URL: https://github.com/madler/zlib -Version: 1.3.1 -Revision: 51b7f2abdade71cd9bb0e7a373ef2610ec6f9daf +Version: 1.3.2 +Revision: 09a1572aa624e5ddb6c075dc013880de70b1b9b9 Update Mechanism: Manual (https://crbug.com/422348588) -CPEPrefix: cpe:/a:zlib:zlib:1.3.1 +CPEPrefix: cpe:/a:zlib:zlib:1.3.2 Security Critical: yes Shipped: yes License: Zlib @@ -33,6 +33,6 @@ Local Modifications: - Plus the changes in 'patches' folder. - Code in contrib/ other than contrib/minizip was added to match zlib's contributor layout. - - In sync with 1.3.1 official release + - In sync with 1.3.2 official release - ZIP reader modified to allow for progress callbacks during extraction. - ZIP reader modified to add detection of AES encrypted content. diff --git a/deps/zlib/chromeconf.h b/deps/zlib/chromeconf.h index 5b91c86442105a..77f0e29e0d6b76 100644 --- a/deps/zlib/chromeconf.h +++ b/deps/zlib/chromeconf.h @@ -45,16 +45,20 @@ #define adler32_z Cr_z_adler32_z #define compress Cr_z_compress #define compress2 Cr_z_compress2 +#define compress_z Cr_z_compress_z +#define compress2_z Cr_z_compress2_z #define compressBound Cr_z_compressBound +#define compressBound_z Cr_z_compressBound_z #define crc32 Cr_z_crc32 #define crc32_combine Cr_z_crc32_combine #define crc32_combine64 Cr_z_crc32_combine64 -#define crc32_combine_gen64 Cr_z_crc32_combine_gen64 #define crc32_combine_gen Cr_z_crc32_combine_gen +#define crc32_combine_gen64 Cr_z_crc32_combine_gen64 #define crc32_combine_op Cr_z_crc32_combine_op #define crc32_z Cr_z_crc32_z #define deflate Cr_z_deflate #define deflateBound Cr_z_deflateBound +#define deflateBound_z Cr_z_deflateBound_z #define deflateCopy Cr_z_deflateCopy #define deflateEnd Cr_z_deflateEnd #define deflateGetDictionary Cr_z_deflateGetDictionary @@ -70,6 +74,7 @@ #define deflateSetDictionary Cr_z_deflateSetDictionary #define deflateSetHeader Cr_z_deflateSetHeader #define deflateTune Cr_z_deflateTune +#define deflateUsed Cr_z_deflateUsed #define deflate_copyright Cr_z_deflate_copyright #define get_crc_table Cr_z_get_crc_table #define gz_error Cr_z_gz_error @@ -135,8 +140,11 @@ #define inflate_copyright Cr_z_inflate_copyright #define inflate_fast Cr_z_inflate_fast #define inflate_table Cr_z_inflate_table +#define inflate_fixed Cr_z_inflate_fixed #define uncompress Cr_z_uncompress #define uncompress2 Cr_z_uncompress2 +#define uncompress_z Cr_z_uncompress_z +#define uncompress2_z Cr_z_uncompress2_z #define zError Cr_z_zError #define zcalloc Cr_z_zcalloc #define zcfree Cr_z_zcfree diff --git a/deps/zlib/compress.c b/deps/zlib/compress.c index 0f11a27c28a691..e3a7516e4f9954 100644 --- a/deps/zlib/compress.c +++ b/deps/zlib/compress.c @@ -1,5 +1,5 @@ /* compress.c -- compress a memory buffer - * Copyright (C) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler + * Copyright (C) 1995-2026 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -18,13 +18,19 @@ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, Z_STREAM_ERROR if the level parameter is invalid. + + The _z versions of the functions take size_t length arguments. */ -int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source, - uLong sourceLen, int level) { +int ZEXPORT compress2_z(Bytef *dest, z_size_t *destLen, const Bytef *source, + z_size_t sourceLen, int level) { z_stream stream; int err; const uInt max = (uInt)-1; - uLong left; + z_size_t left; + + if ((sourceLen > 0 && source == NULL) || + destLen == NULL || (*destLen > 0 && dest == NULL)) + return Z_STREAM_ERROR; left = *destLen; *destLen = 0; @@ -43,23 +49,36 @@ int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source, do { if (stream.avail_out == 0) { - stream.avail_out = left > (uLong)max ? max : (uInt)left; + stream.avail_out = left > (z_size_t)max ? max : (uInt)left; left -= stream.avail_out; } if (stream.avail_in == 0) { - stream.avail_in = sourceLen > (uLong)max ? max : (uInt)sourceLen; + stream.avail_in = sourceLen > (z_size_t)max ? max : + (uInt)sourceLen; sourceLen -= stream.avail_in; } err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH); } while (err == Z_OK); - *destLen = stream.total_out; + *destLen = (z_size_t)(stream.next_out - dest); deflateEnd(&stream); return err == Z_STREAM_END ? Z_OK : err; } - +int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source, + uLong sourceLen, int level) { + int ret; + z_size_t got = *destLen; + ret = compress2_z(dest, &got, source, sourceLen, level); + *destLen = (uLong)got; + return ret; +} /* =========================================================================== */ +int ZEXPORT compress_z(Bytef *dest, z_size_t *destLen, const Bytef *source, + z_size_t sourceLen) { + return compress2_z(dest, destLen, source, sourceLen, + Z_DEFAULT_COMPRESSION); +} int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen) { return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); @@ -69,9 +88,10 @@ int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source, If the default memLevel or windowBits for deflateInit() is changed, then this function needs to be updated. */ -uLong ZEXPORT compressBound(uLong sourceLen) { - sourceLen = sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13; +z_size_t ZEXPORT compressBound_z(z_size_t sourceLen) { + z_size_t bound = sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13; + /* FIXME(cavalcantii): usage of CRC32 Castagnoli as a hash function * for the hash table of symbols used for compression has a side effect * where for compression level [4, 5] it will increase the output buffer size @@ -80,6 +100,11 @@ uLong ZEXPORT compressBound(uLong sourceLen) { * the expected output size by 0.8% (i.e. 8x more than the worst scenario). * See: http://crbug.com/990489 */ - sourceLen += sourceLen >> 7; // Equivalent to 1.0078125 - return sourceLen; + bound += bound >> 7; // Equivalent to 1.0078125 + + return bound < sourceLen ? (z_size_t)-1 : bound; +} +uLong ZEXPORT compressBound(uLong sourceLen) { + z_size_t bound = compressBound_z(sourceLen); + return (uLong)bound != bound ? (uLong)-1 : (uLong)bound; } diff --git a/deps/zlib/contrib/minizip/Makefile b/deps/zlib/contrib/minizip/Makefile index b3e050a0416c00..07c1f4855f1d54 100644 --- a/deps/zlib/contrib/minizip/Makefile +++ b/deps/zlib/contrib/minizip/Makefile @@ -1,12 +1,8 @@ -CC?=cc -CFLAGS := -O $(CFLAGS) -I../.. +CPPFLAGS = -I../.. UNZ_OBJS = miniunz.o unzip.o ioapi.o ../../libz.a ZIP_OBJS = minizip.o zip.o ioapi.o ../../libz.a -.c.o: - $(CC) -c $(CFLAGS) $*.c - all: miniunz minizip miniunz.o: miniunz.c unzip.h iowin32.h @@ -18,10 +14,10 @@ iowin32.o: iowin32.c iowin32.h ioapi.h mztools.o: mztools.c unzip.h miniunz: $(UNZ_OBJS) - $(CC) $(CFLAGS) -o $@ $(UNZ_OBJS) + ${CC} ${LDFLAGS} -o $@ $(UNZ_OBJS) minizip: $(ZIP_OBJS) - $(CC) $(CFLAGS) -o $@ $(ZIP_OBJS) + ${CC} ${LDFLAGS} -o $@ $(ZIP_OBJS) test: miniunz minizip @rm -f test.* diff --git a/deps/zlib/contrib/minizip/README.chromium b/deps/zlib/contrib/minizip/README.chromium index 0299a7e331f9ee..78cbd20018b1ad 100644 --- a/deps/zlib/contrib/minizip/README.chromium +++ b/deps/zlib/contrib/minizip/README.chromium @@ -1,8 +1,8 @@ Name: ZIP file API for reading file entries in a ZIP archive Short Name: minizip URL: https://github.com/madler/zlib/tree/master/contrib/minizip -Version: 1.3.1.1 -Revision: ef24c4c7502169f016dcd2a26923dbaf3216748c +Version: 1.3.2 +Revision: 09a1572aa624e5ddb6c075dc013880de70b1b9b9 Update Mechanism: Manual License: Zlib License File: //third_party/zlib/LICENSE @@ -40,3 +40,6 @@ Local Modifications: large CRX files). 0018-support-prefixed-zip64.patch +- Added stricter parsing for zip64 candidates to avoid an issue where a zip64 + could be embedded in a non-zip64 zip. + 0019-fix-zip64-in-zip.patch diff --git a/deps/zlib/contrib/minizip/crypt.h b/deps/zlib/contrib/minizip/crypt.h index f4b93b78dc31cc..dd548938a4fdf7 100644 --- a/deps/zlib/contrib/minizip/crypt.h +++ b/deps/zlib/contrib/minizip/crypt.h @@ -1,9 +1,6 @@ /* crypt.h -- base code for crypt/uncrypt ZIPfile - - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant + Copyright (C) 1998-2026 Gilles Vollant This code is a modified version of crypting code in Infozip distribution @@ -23,7 +20,7 @@ This code support the "Traditional PKWARE Encryption". The new AES encryption added on Zip format by Winzip (see the page - http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong + https://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong Encryption is not supported. */ @@ -50,7 +47,7 @@ static int update_keys(unsigned long* pkeys, const z_crc_t* pcrc_32_tab, int c) (*(pkeys+1)) += (*(pkeys+0)) & 0xff; (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; { - register int keyshift = (int)((*(pkeys+1)) >> 24); + int keyshift = (int)((*(pkeys+1)) >> 24); (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); } return c; @@ -106,7 +103,7 @@ static unsigned crypthead(const char* passwd, /* password string */ */ if (++calls == 1) { - srand((unsigned)(time(NULL) ^ ZCR_SEED2)); + srand((unsigned)time(NULL) ^ ZCR_SEED2); } init_keys(passwd, pkeys, pcrc_32_tab); for (n = 0; n < RAND_HEAD_LEN-2; n++) diff --git a/deps/zlib/contrib/minizip/ioapi.c b/deps/zlib/contrib/minizip/ioapi.c index a38881dca90a23..a8554667a1c403 100644 --- a/deps/zlib/contrib/minizip/ioapi.c +++ b/deps/zlib/contrib/minizip/ioapi.c @@ -1,10 +1,10 @@ /* ioapi.h -- IO base function header for compress/uncompress .zip - part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + part of the MiniZip project - ( https://www.winimage.com/zLibDll/minizip.html ) - Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + Copyright (C) 1998-2026 Gilles Vollant (minizip) ( https://www.winimage.com/zLibDll/minizip.html ) Modifications for Zip64 support - Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + Copyright (C) 2009-2010 Mathias Svensson ( https://result42.com ) For more info read MiniZip_info.txt @@ -14,8 +14,8 @@ #define _CRT_SECURE_NO_WARNINGS #endif -#if defined(__APPLE__) || defined(__Fuchsia__) || defined(IOAPI_NO_64) || defined(__HAIKU__) || defined(MINIZIP_FOPEN_NO_64) -// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions +#if defined(__APPLE__) || defined(__Fuchsia__) || defined(IOAPI_NO_64) || defined(__HAIKU__) || defined(MINIZIP_FOPEN_NO_64) || (defined(__ANDROID_API__) && __ANDROID_API__ < 24) +/* In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions */ #define FOPEN_FUNC(filename, mode) fopen(filename, mode) #define FTELLO_FUNC(stream) ftello(stream) #define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin) diff --git a/deps/zlib/contrib/minizip/ioapi.h b/deps/zlib/contrib/minizip/ioapi.h index f3b193d8030575..a5211239ea2ac5 100644 --- a/deps/zlib/contrib/minizip/ioapi.h +++ b/deps/zlib/contrib/minizip/ioapi.h @@ -1,10 +1,10 @@ /* ioapi.h -- IO base function header for compress/uncompress .zip - part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + part of the MiniZip project - ( https://www.winimage.com/zLibDll/minizip.html ) - Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + Copyright (C) 1998-2026 Gilles Vollant (minizip) ( https://www.winimage.com/zLibDll/minizip.html ) Modifications for Zip64 support - Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + Copyright (C) 2009-2010 Mathias Svensson ( https://result42.com ) For more info read MiniZip_info.txt @@ -21,10 +21,10 @@ #ifndef ZLIBIOAPI64_H #define ZLIBIOAPI64_H -#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__)) +#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. + /* 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.*/ #ifndef __USE_FILE_OFFSET64 #define __USE_FILE_OFFSET64 @@ -161,8 +161,8 @@ typedef struct zlib_filefunc64_32_def_s #define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) #define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) -//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) -//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode)) +/*#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) */ +/*#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode)) */ #define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream)) #define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream)) diff --git a/deps/zlib/contrib/minizip/iowin32.c b/deps/zlib/contrib/minizip/iowin32.c index 393c98676f0eff..8a72423f90b9e2 100644 --- a/deps/zlib/contrib/minizip/iowin32.c +++ b/deps/zlib/contrib/minizip/iowin32.c @@ -1,11 +1,10 @@ /* iowin32.c -- IO base function header for compress/uncompress .zip - Version 1.1, February 14h, 2010 - part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + part of the MiniZip project - ( https://www.winimage.com/zLibDll/minizip.html ) - Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + Copyright (C) 1998-2026 Gilles Vollant (minizip) ( https://www.winimage.com/zLibDll/minizip.html ) Modifications for Zip64 support - Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + Copyright (C) 2009-2010 Mathias Svensson ( https://result42.com ) For more info read MiniZip_info.txt diff --git a/deps/zlib/contrib/minizip/iowin32.h b/deps/zlib/contrib/minizip/iowin32.h index a23a65d4331d93..65be627016401c 100644 --- a/deps/zlib/contrib/minizip/iowin32.h +++ b/deps/zlib/contrib/minizip/iowin32.h @@ -1,11 +1,10 @@ /* iowin32.h -- IO base function header for compress/uncompress .zip - Version 1.1, February 14h, 2010 - part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + part of the MiniZip project - ( https://www.winimage.com/zLibDll/minizip.html ) - Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + Copyright (C) 1998-2026 Gilles Vollant (minizip) ( https://www.winimage.com/zLibDll/minizip.html ) Modifications for Zip64 support - Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + Copyright (C) 2009-2010 Mathias Svensson ( https://result42.com ) For more info read MiniZip_info.txt diff --git a/deps/zlib/contrib/minizip/miniunz.c b/deps/zlib/contrib/minizip/miniunz.c index f4ad16bdd377ba..e8a5c726c4c720 100644 --- a/deps/zlib/contrib/minizip/miniunz.c +++ b/deps/zlib/contrib/minizip/miniunz.c @@ -1,15 +1,14 @@ /* miniunz.c - Version 1.1, February 14h, 2010 - sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + sample part of the MiniZip project - ( https://www.winimage.com/zLibDll/minizip.html ) - Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + Copyright (C) 1998-2026 Gilles Vollant (minizip) ( https://www.winimage.com/zLibDll/minizip.html ) Modifications of Unzip for Zip64 Copyright (C) 2007-2008 Even Rouault Modifications for Zip64 support on both zip and unzip - Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + Copyright (C) 2009-2010 Mathias Svensson ( https://result42.com ) */ #if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__)) && (!defined(__ANDROID_API__)) @@ -151,7 +150,7 @@ static int makedir(const char *newdir) { printf("Error allocating memory\n"); return UNZ_INTERNALERROR; } - strcpy(buffer,newdir); + memcpy(buffer,newdir,len+1); if (buffer[len-1] == '/') { buffer[len-1] = '\0'; @@ -187,7 +186,7 @@ static int makedir(const char *newdir) { static void do_banner(void) { printf("MiniUnz 1.1, demo of zLib + Unz package written by Gilles Vollant\n"); - printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n"); + printf("more info at https://www.winimage.com/zLibDll/unzip.html\n\n"); } static void do_help(void) { @@ -235,7 +234,7 @@ static int do_list(unzFile uf) { err = unzGetGlobalInfo64(uf,&gi); if (err!=UNZ_OK) - printf("error %d with zipfile in unzGetGlobalInfo \n",err); + printf("error %d with zipfile in unzGetGlobalInfo\n",err); printf(" Length Method Size Ratio Date Time CRC-32 Name\n"); printf(" ------ ------ ---- ----- ---- ---- ------ ----\n"); for (i=0;i 0xffff) { entriesZip = 0xffff; @@ -282,6 +282,12 @@ extern int ZEXPORT unzRepair(const char* file, const char* fileOut, const char* } } } else { + if (fpOutCD != NULL) + fclose(fpOutCD); + if (fpZip != NULL) + fclose(fpZip); + if (fpOut != NULL) + fclose(fpOut); err = Z_STREAM_ERROR; } return err; diff --git a/deps/zlib/contrib/minizip/skipset.h b/deps/zlib/contrib/minizip/skipset.h index 5e648b9d234899..ec4d4ab4dc48cc 100644 --- a/deps/zlib/contrib/minizip/skipset.h +++ b/deps/zlib/contrib/minizip/skipset.h @@ -1,5 +1,5 @@ -// skipset.h -- set operations using a skiplist -// Copyright (C) 2024 Mark Adler +/* 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 @@ -50,20 +50,20 @@ // 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()) +// - set_rand() returns 32 random bits (seeded by set_start()) */ #ifndef SKIPSET_H #define SKIPSET_H -#include // realloc(), free(), NULL, size_t -#include // ptrdiff_t -#include // jmp_buf, longjmp() -#include // ENOMEM -#include // time(), clock() -#include // assert.h -#include "ints.h" // i16_t, ui32_t, ui64_t +#include /* realloc(), free(), NULL, size_t */ +#include /* ptrdiff_t */ +#include /* jmp_buf, longjmp() */ +#include /* ENOMEM */ +#include /* time(), clock() */ +#include /* assert.h */ +#include "ints.h" /* i16_t, ui32_t, ui64_t */ -// Structures and functions below noted as "--private--" should not be used by +/* 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. @@ -73,18 +73,23 @@ // *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. +// --private-- Random number generator state. */ typedef struct { - ui64_t state; // 64-bit generator state - ui64_t inc; // 63-bit sequence id + 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. +/* --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) { gen->inc = (seq << 1) | 1; gen->state = (seed + gen->inc) * 6364136223846793005ULL + gen->inc; } -// Return 32 random bits, advancing the state *gen. +/* Start a unique random number sequence using bits from noise sources. */ +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) { ui64_t state = gen->state; gen->state = state * 6364136223846793005ULL + gen->inc; @@ -92,40 +97,40 @@ ui32_t set_rand(set_rand_t *gen) { int rot = state >> 59; return (mix >> rot) | (mix << ((-rot) & 31)); } -// End of PCG32 code. +/* End of PCG32 code. */ -// --private-- Linked-list node. +/* --private-- Linked-list node. */ typedef struct set_node_s set_node_t; struct set_node_s { - set_key_t key; // the key (not used for head or path) - i16_t size; // number of allocated pointers in right[] - i16_t fill; // number of pointers in right[] filled in - set_node_t **right; // pointer for each level, each to the right + set_key_t key; /* the key (not used for head or path) */ + i16_t size; /* number of allocated pointers in right[] */ + i16_t fill; /* number of pointers in right[] filled in */ + set_node_t **right; /* pointer for each level, each to the right */ }; -// A set. The application sets env, may use gen with set_rand(), and may read -// allocs and memory. The remaining variables are --private-- . +/* A set. The application sets env, may use gen with set_rand(), and may read +// 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() - set_node_t *node; // node under construction, in case of longjmp() - i16_t depth; // maximum depth of the skiplist - ui64_t ran; // a precious trove of random bits - set_rand_t gen; // random number generator state - jmp_buf env; // setjmp() environment for allocation errors + set_node_t *head; /* skiplist head -- no key, just links */ + set_node_t *path; /* right[] is path to key from set_found() */ + set_node_t *node; /* node under construction, in case of longjmp() */ + i16_t depth; /* maximum depth of the skiplist */ + ui64_t ran; /* a precious trove of random bits */ + set_rand_t gen; /* random number generator state */ + 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 allocs; /* number of allocations */ + size_t memory; /* total amount of allocated memory (>= requests) */ #endif } set_t; -// Memory allocation and deallocation. set_alloc(set, ptr, size) returns a +/* 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. +// 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. +/* Track the number of allocations and the total backing memory size. */ # if defined(_WIN32) # include # define SET_ALLOC_SIZE(ptr) _msize(ptr) @@ -162,7 +167,7 @@ void set_free(set_t *set, void *ptr) { } } #else -// Without tracking. +/* Without tracking. */ void *set_alloc(set_t *set, void *ptr, size_t size) { void *mem = realloc(ptr, size); if (mem == NULL) @@ -175,16 +180,17 @@ void set_free(set_t *set, void *ptr) { } #endif -// --private-- Grow node's array right[] as needed to be able to hold at least +/* --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. +// 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) { if (node->size < want) { int more = node->size ? node->size : 1; while (more < want) more <<= 1; - node->right = set_alloc(set, node->right, more * sizeof(set_node_t *)); + node->right = set_alloc(set, node->right, + (size_t)more * sizeof(set_node_t *)); node->size = (i16_t)more; } int i; @@ -194,7 +200,7 @@ void set_grow(set_t *set, set_node_t *node, int want, int fill) { node->fill = (i16_t)want; } -// --private-- Return a new node. key is left uninitialized. +/* --private-- Return a new node. key is left uninitialized. */ set_node_t *set_node(set_t *set) { set_node_t *node = set_alloc(set, NULL, sizeof(set_node_t)); node->size = 0; @@ -203,11 +209,11 @@ set_node_t *set_node(set_t *set) { return node; } -// --private-- Free the list linked from head, along with the keys. +/* --private-- Free the list linked from head, along with the keys. */ 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 + set_node_t *next = step->right[0]; /* save link to next node */ set_drop(set, step->key); set_free(set, step->right); set_free(set, step); @@ -215,59 +221,58 @@ void set_sweep(set_t *set) { } } -// Initialize a new set. set->env must be initialized using setjmp() before +/* 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(). +// can be used to free the set's memory after a longjmp(). */ void set_start(set_t *set) { #ifdef SET_TRACK set->allocs = 0; set->memory = 0; #endif - set->head = set->path = set->node = NULL; // in case set_node() fails + 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 - *(unsigned char *)&set->head->key = 137; // set id + set_grow(set, set->head, 1, 1); /* one link back to head for an empty set */ + *(unsigned char *)&set->head->key = 137; /* set id */ set->depth = 0; - set_seed(&set->gen, ((ui64_t)(ptrdiff_t)set << 32) ^ - ((ui64_t)time(NULL) << 12) ^ clock(), 0); + set_uniq(&set->gen, set); set->ran = 1; } -// 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. +/* 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) { return set->head != NULL && set->head->right != NULL && *(unsigned char *)&set->head->key == 137; } -// 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(). +/* 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) { assert(set_ok(set) && "improper use"); - // Free all the keys and their nodes. + /* 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. + /* 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. */ set->head->right[0] = set->head; set->head->fill = 1; set->path->fill = 0; set->depth = 0; } -// Done using the set -- free all allocations. The only operation on *set +/* 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(). +// on any allocation failure, including during a set_start(). */ void set_end(set_t *set) { if (set->head != NULL) { - // Empty the set and free the head node. + /* Empty the set and free the head node. */ if (set->head->right != NULL) { set_sweep(set); set_free(set, set->head->right); @@ -276,13 +281,13 @@ void set_end(set_t *set) { set->head = NULL; } if (set->path != NULL) { - // Free the path work area. + /* Free the path work area. */ set_free(set, set->path->right); set_free(set, set->path); set->path = NULL; } if (set->node != NULL) { - // Free the node that was under construction when longjmp() hit. + /* Free the node that was under construction when longjmp() hit. */ set_drop(set, set->node->key); set_free(set, set->node->right); set_free(set, set->node); @@ -290,12 +295,12 @@ 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(). +/* 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) { assert(set_ok(set) && "improper use"); - // Start at depth and work down and right as determined by key comparisons. + /* 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; set_grow(set, set->path, i + 1, 0); @@ -306,25 +311,25 @@ int set_found(set_t *set, set_key_t key) { set->path->right[i] = here; } while (i--); - // See if the key matches. + /* See if the key matches. */ here = here->right[0]; 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. +/* 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) { assert(set_ok(set) && "improper use"); if (set_found(set, key)) - // That key is already in the set. + /* That key is already in the set. */ return 1; - // Randomly generate a new level-- level 0 with probability 1/2, 1 with - // probability 1/4, 2 with probability 1/8, etc. + /* 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; for (;;) { if (set->ran == 1) - // Ran out. Get another 32 random bits. + /* Ran out. Get another 32 random bits. */ set->ran = set_rand(&set->gen) | (1ULL << 32); int bit = set->ran & 1; set->ran >>= 1; @@ -335,14 +340,14 @@ int set_insert(set_t *set, set_key_t key) { level++; } if (level > set->depth) { - // The maximum depth is now deeper. Update the structures. + /* The maximum depth is now deeper. Update the structures. */ set_grow(set, set->path, level + 1, 1); set_grow(set, set->head, level + 1, 1); set->depth = (i16_t)level; } - // Make a new node for the provided key, and insert it in the lists up to - // and including level. + /* Make a new node for the provided key, and insert it in the lists up to + // and including level. */ set->node = set_node(set); set->node->key = key; set_grow(set, set->node, level + 1, 0); @@ -357,5 +362,5 @@ int set_insert(set_t *set, set_key_t key) { #else #error ** another skiplist set already created here -// Would need to implement a prefix in order to support multiple sets. +/* Would need to implement a prefix in order to support multiple sets. */ #endif diff --git a/deps/zlib/contrib/minizip/unzip.c b/deps/zlib/contrib/minizip/unzip.c index b77b787ccc0dbe..0264f7ac570f7d 100644 --- a/deps/zlib/contrib/minizip/unzip.c +++ b/deps/zlib/contrib/minizip/unzip.c @@ -1,14 +1,13 @@ /* unzip.c -- IO for uncompress .zip files using zlib - Version 1.1, February 14h, 2010 - part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + part of the MiniZip project - ( https://www.winimage.com/zLibDll/minizip.html ) - Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + Copyright (C) 1998-2026 Gilles Vollant (minizip) ( https://www.winimage.com/zLibDll/minizip.html ) Modifications of Unzip for Zip64 Copyright (C) 2007-2008 Even Rouault Modifications for Zip64 support on both zip and unzip - Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + Copyright (C) 2009-2010 Mathias Svensson ( https://result42.com ) For more info read MiniZip_info.txt @@ -69,6 +68,9 @@ #include #include +#ifdef ZLIB_DLL +# undef ZLIB_DLL +#endif #include "zlib.h" #include "unzip.h" @@ -112,7 +114,7 @@ const char unz_copyright[] = - " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; + " unzip 1.01 Copyright 1998-2004 Gilles Vollant - https://www.winimage.com/zLibDll/minizip.html"; /* unz_file_info64_internal contain internal info about a file in zipfile*/ typedef struct unz_file_info64_internal_s @@ -444,12 +446,28 @@ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) break; - for (i=(int)uReadSize-3; (i--)>0;) + /* Search for the non-zip64 EoCDR and confirm zip64 EoCDL is 20 bytes + earlier. This avoids false positives if the file is a non-zip64 zip + but contains an uncompressed zip64 near its end. Note: zip64 EoCDL is + 20 bytes long. */ + for (i=(int)uReadSize-3; (i--)>20;) + // End of central directory record signature (PK\5\6) if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && - ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) { - uPosFound = uReadPos+(unsigned)i; - break; + // Zip64 end of central directory locator signature (PK\6\7) + if (((*(buf+i-20))==0x50) && ((*(buf+i+1-20))==0x4b) && + ((*(buf+i+2-20))==0x06) && ((*(buf+i+3-20))==0x07)) + { + uPosFound = uReadPos+(unsigned)i-20; + break; + } + else + { + /* This is a non-zip64 zip; abandon the search. */ + free(buf); + return CENTRALDIRINVALID; + } } if (uPosFound!=CENTRALDIRINVALID) @@ -744,6 +762,7 @@ extern unzFile ZEXPORT unzOpen2_64(const void *path, { zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def; + zlib_filefunc64_32_def_fill.zopen32_file = NULL; zlib_filefunc64_32_def_fill.ztell32_file = NULL; zlib_filefunc64_32_def_fill.zseek32_file = NULL; return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 1); @@ -840,6 +859,9 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file, uLong uL; uLong uFileNameCrc; + file_info.size_utf8_filename = 0; + file_info.utf8_filename[0] = '\0'; + if (file==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; @@ -904,7 +926,7 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file, if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) err=UNZ_ERRNO; - // relative offset of local header + /* relative offset of local header */ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) err=UNZ_ERRNO; file_info_internal.offset_curfile = uL; @@ -940,7 +962,7 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file, lSeek -= file_info.size_filename; } - // Read extrafield + /* Read extrafield */ if ((err==UNZ_OK) && (extraField!=NULL)) { ZPOS64_T uSizeRead ; @@ -971,7 +993,7 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file, { uLong acc = 0; - // since lSeek now points to after the extra field we need to move back + /* since lSeek now points to after the extra field we need to move back */ lSeek -= file_info.size_file_extra; if (lSeek!=0) @@ -1048,48 +1070,34 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file, } else { - uLong uCrc, fileNameSize; + uLong uCrc, utf8FileNameSize; if (unz64local_getLong(&s->z_filefunc, s->filestream, &uCrc) != UNZ_OK) { err = UNZ_ERRNO; } - fileNameSize = dataSize - (1 + 4); /* 1 for version, 4 for uCrc */ + utf8FileNameSize = dataSize - (1 + 4); /* 1 for version, 4 for uCrc */ /* Check CRC against file name in the header. */ if (uCrc != uFileNameCrc) { - if (ZSEEK64(s->z_filefunc, s->filestream, fileNameSize, ZLIB_FILEFUNC_SEEK_CUR) != 0) + if (ZSEEK64(s->z_filefunc, s->filestream, utf8FileNameSize, ZLIB_FILEFUNC_SEEK_CUR) != 0) { err = UNZ_ERRNO; } } else { - file_info.size_filename = fileNameSize; - - char szCurrentFileName[UINT16_MAX] = {0}; + file_info.size_utf8_filename = utf8FileNameSize; - if (file_info.size_filename > 0) + if (file_info.size_utf8_filename > 0) { - if (ZREAD64(s->z_filefunc, s->filestream, szCurrentFileName, file_info.size_filename) != file_info.size_filename) + if (ZREAD64(s->z_filefunc, s->filestream, file_info.utf8_filename, file_info.size_utf8_filename) != file_info.size_utf8_filename) { err = UNZ_ERRNO; } } - - if (szFileName != NULL) - { - if (fileNameBufferSize <= file_info.size_filename) - { - memcpy(szFileName, szCurrentFileName, fileNameBufferSize); - } - else - { - memcpy(szFileName, szCurrentFileName, file_info.size_filename); - szFileName[file_info.size_filename] = '\0'; - } - } + file_info.utf8_filename[file_info.size_utf8_filename] = '\0'; } } } @@ -1192,6 +1200,9 @@ extern int ZEXPORT unzGetCurrentFileInfo(unzFile file, pfile_info->compressed_size = (uLong)file_info64.compressed_size; pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size; + pfile_info->size_utf8_filename = file_info64.size_utf8_filename; + memcpy(pfile_info->utf8_filename, file_info64.utf8_filename, file_info64.size_utf8_filename + 1); + } return err; } @@ -1671,10 +1682,10 @@ extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64(unzFile file) { file_in_zip64_read_info_s* pfile_in_zip_read_info; s=(unz64_s*)file; if (file==NULL) - return 0; //UNZ_PARAMERROR; + return 0; /* UNZ_PARAMERROR; */ pfile_in_zip_read_info=s->pfile_in_zip_read; if (pfile_in_zip_read_info==NULL) - return 0; //UNZ_PARAMERROR; + return 0; /* UNZ_PARAMERROR; */ return pfile_in_zip_read_info->pos_in_zipfile + pfile_in_zip_read_info->byte_before_the_zipfile; } @@ -1838,7 +1849,7 @@ extern int ZEXPORT unzReadCurrentFile(unzFile file, voidp buf, unsigned len) { if (err!=BZ_OK) break; #endif - } // end Z_BZIP2ED + } /* end Z_BZIP2ED */ else { ZPOS64_T uTotalOutBefore,uTotalOutAfter; @@ -2081,7 +2092,7 @@ extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) { unz64_s* s; if (file==NULL) - return 0; //UNZ_PARAMERROR; + return 0; /* UNZ_PARAMERROR; */ s=(unz64_s*)file; if (!s->current_file_ok) return 0; @@ -2095,7 +2106,7 @@ extern uLong ZEXPORT unzGetOffset(unzFile file) { ZPOS64_T offset64; if (file==NULL) - return 0; //UNZ_PARAMERROR; + return 0; /* UNZ_PARAMERROR; */ offset64 = unzGetOffset64(file); return (uLong)offset64; } diff --git a/deps/zlib/contrib/minizip/unzip.h b/deps/zlib/contrib/minizip/unzip.h index ceb614e7832b4d..05efa64ea477ee 100644 --- a/deps/zlib/contrib/minizip/unzip.h +++ b/deps/zlib/contrib/minizip/unzip.h @@ -1,14 +1,13 @@ /* unzip.h -- IO for uncompress .zip files using zlib - Version 1.1, February 14h, 2010 - part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + part of the MiniZip project - ( https://www.winimage.com/zLibDll/minizip.html ) - Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + Copyright (C) 1998-2026 Gilles Vollant (minizip) ( https://www.winimage.com/zLibDll/minizip.html ) Modifications of Unzip for Zip64 Copyright (C) 2007-2008 Even Rouault Modifications for Zip64 support on both zip and unzip - Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + Copyright (C) 2009-2010 Mathias Svensson ( https://result42.com ) For more info read MiniZip_info.txt @@ -43,6 +42,8 @@ #ifndef _unz64_H #define _unz64_H +#include + #ifdef __cplusplus extern "C" { #endif @@ -70,6 +71,8 @@ typedef unzFile__ *unzFile; typedef voidp unzFile; #endif +extern const char unz_copyright[]; + #define UNZ_OK (0) #define UNZ_END_OF_LIST_OF_FILE (-100) @@ -127,6 +130,10 @@ typedef struct unz_file_info64_s uLong external_fa; /* external file attributes 4 bytes */ tm_unz tmu_date; + + /* Info-ZIP Unicode Path Extra Field */ + char utf8_filename[UINT16_MAX + 1]; /* UTF-8 Filename, null terminated */ + uLong size_utf8_filename; /* Length, excluding null terminator */ } unz_file_info64; typedef struct unz_file_info_s @@ -148,6 +155,10 @@ typedef struct unz_file_info_s uLong external_fa; /* external file attributes 4 bytes */ tm_unz tmu_date; + + /* Info-ZIP Unicode Path Extra Field */ + char utf8_filename[UINT16_MAX + 1]; /* UTF-8 Filename, null terminated */ + uLong size_utf8_filename; /* Length, excluding null terminator */ } unz_file_info; extern int ZEXPORT unzStringFileNameCompare(const char* fileName1, diff --git a/deps/zlib/contrib/minizip/zip.c b/deps/zlib/contrib/minizip/zip.c index 93d2612e29a030..31005c51b06224 100644 --- a/deps/zlib/contrib/minizip/zip.c +++ b/deps/zlib/contrib/minizip/zip.c @@ -1,11 +1,10 @@ /* zip.c -- IO on .zip files using zlib - Version 1.1, February 14h, 2010 - part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + part of the MiniZip project - ( https://www.winimage.com/zLibDll/minizip.html ) - Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + Copyright (C) 1998-2026 Gilles Vollant (minizip) ( https://www.winimage.com/zLibDll/minizip.html ) Modifications for Zip64 support - Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + Copyright (C) 2009-2010 Mathias Svensson ( https://result42.com ) For more info read MiniZip_info.txt @@ -29,6 +28,9 @@ #ifndef ZLIB_CONST # define ZLIB_CONST #endif +#ifdef ZLIB_DLL +# undef ZLIB_DLL +#endif #include "zlib.h" #include "zip.h" @@ -52,7 +54,7 @@ #endif #ifndef Z_BUFSIZE -#define Z_BUFSIZE (64*1024) //(16384) +#define Z_BUFSIZE (64*1024) /* (16384) */ #endif #ifndef Z_MAXFILENAMEINZIP @@ -71,7 +73,7 @@ /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ -// NOT sure that this work on ALL platform +/* NOT sure that this work on ALL platform */ #define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32)) #ifndef SEEK_CUR @@ -93,7 +95,7 @@ # define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif #endif -const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; +const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - https://www.winimage.com/zLibDll/minizip.html"; #define SIZEDATA_INDATABLOCK (4096-(4*4)) @@ -125,16 +127,16 @@ typedef struct linkedlist_data_s } linkedlist_data; -// zipAlreadyThere() set functions for a set of zero-terminated strings, and -// a block_t type for reading the central directory datablocks. +/* zipAlreadyThere() set functions for a set of zero-terminated strings, and +// a block_t type for reading the central directory datablocks. */ typedef char *set_key_t; #define set_cmp(a, b) strcmp(a, b) #define set_drop(s, k) set_free(s, k) #include "skipset.h" typedef struct { - unsigned char *next; // next byte in datablock data - size_t left; // number of bytes left in data (at least) - linkedlist_datablock_internal *node; // current datablock + unsigned char *next; /* next byte in datablock data */ + size_t left; /* number of bytes left in data (at least) */ + linkedlist_datablock_internal *node; /* current datablock */ } block_t; @@ -189,9 +191,9 @@ typedef struct char *globalcomment; #endif - // Support for zipAlreadyThere(). - set_t set; // set for detecting name collisions - block_t block; // block for reading the central directory + /* Support for zipAlreadyThere(). */ + set_t set; /* set for detecting name collisions */ + block_t block; /* block for reading the central directory */ } zip64_internal; @@ -283,7 +285,7 @@ local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) return ZIP_OK; } -// zipAlreadyThere() operations. "set" in the zip internal structure keeps the +/* 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 @@ -295,81 +297,82 @@ local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) // 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. +// 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; block->left = block->node->filled_in_this_block; } -// Mark *block as bad, with all subsequent reads returning end, even if more +/* 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. +// invalid, so there is no longer any point in attempting to interpret it. */ local void block_stop(block_t *block) { block->left = 0; block->next = NULL; } -// Return true if *block has reached the end of the data in the datablocks. +/* Return true if *block has reached the end of the data in the datablocks. */ local int block_end(block_t *block) { linkedlist_datablock_internal *node = block->node; if (node == NULL) - // This block was previously terminated with extreme prejudice. + /* This block was previously terminated with extreme prejudice. */ return 1; if (block->next < node->data + node->filled_in_this_block) - // There are more bytes to read in the current datablock. + /* There are more bytes to read in the current datablock. */ return 0; while (node->next_datablock != NULL) { if (node->filled_in_this_block != 0) - // There are some bytes in a later datablock. + /* There are some bytes in a later datablock. */ return 0; node = node->next_datablock; } - // Reached the end of the list of datablocks. There's nothing. + /* Reached the end of the list of datablocks. There's nothing. */ return 1; } -// Return one byte from *block, or -1 if the end is reached. +/* Return one byte from *block, or -1 if the end is reached. */ local int block_get(block_t *block) { while (block->left == 0) { if (block->node == NULL) - // We've been marked bad. Return end. + /* We've been marked bad. Return end. */ return -1; - // Update left in case more was filled in since we were last here. + /* Update left in case more was filled in since we were last here. */ block->left = block->node->filled_in_this_block - - (block->next - block->node->data); + (size_t)(block->next - block->node->data); if (block->left != 0) - // There was indeed more data appended in the current datablock. + /* There was indeed more data appended in the current datablock. */ break; if (block->node->next_datablock == NULL) - // No more data here, and there is no next datablock. At the end. + /* No more data here, and there is no next datablock. At the end. */ return -1; - // Try the next datablock for more data. + /* Try the next datablock for more data. */ block->node = block->node->next_datablock; block->next = block->node->data; block->left = block->node->filled_in_this_block; } - // We have a byte to return. + /* We have a byte to return. */ block->left--; return *block->next++; } -// Return a 16-bit unsigned little-endian value from block, or a negative value -// if the end is reached. +/* Return a 16-bit unsigned little-endian value from block, or a negative value +// if the end is reached. */ local long block_get2(block_t *block) { - long got = block_get(block); - return got | ((unsigned long)block_get(block) << 8); + int low = block_get(block); + int high = block_get(block); + return low < 0 || high < 0 ? -1 : low | ((long)high << 8); } -// Read up to len bytes from block into buf. Return the number of bytes read. +/* 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; while (need) { if (block->left == 0) { - // Get a byte to update and step through the linked list as needed. + /* Get a byte to update and step through the linked list as needed. */ int got = block_get(block); if (got == -1) - // Reached the end. + /* Reached the end. */ break; *buf++ = (unsigned char)got; need--; @@ -382,11 +385,11 @@ local size_t block_read(block_t *block, unsigned char *buf, size_t len) { buf += take; need -= take; } - return len - need; // return the number of bytes copied + return len - need; /* return the number of bytes copied */ } -// Skip n bytes in block. Return 0 on success or -1 if there are less than n -// bytes to the end. +/* Skip n bytes in block. Return 0 on success or -1 if there are less than n +// bytes to the end. */ local int block_skip(block_t *block, size_t n) { while (n > block->left) { n -= block->left; @@ -401,106 +404,106 @@ local int block_skip(block_t *block, size_t n) { return 0; } -// Process the next central directory record at *block. Return the allocated, +/* 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. +// invalid, *block is marked bad. This uses *set for the allocation of memory. */ local char *block_central_name(block_t *block, set_t *set) { char *name = NULL; for (;;) { if (block_end(block)) - // At the end of the central directory (so far). + /* At the end of the central directory (so far). */ return NULL; - // Check for a central directory record signature. + /* Check for a central directory record signature. */ if (block_get2(block) != (CENTRALHEADERMAGIC & 0xffff) || block_get2(block) != (CENTRALHEADERMAGIC >> 16)) - // Incorrect signature. + /* Incorrect signature. */ break; - // Go through the remaining fixed-length portion of the record, - // extracting the lengths of the three variable-length fields. + /* Go through the remaining fixed-length portion of the record, + // extracting the lengths of the three variable-length fields. */ block_skip(block, 24); - unsigned flen = block_get2(block); // file name length - unsigned xlen = block_get2(block); // extra field length - unsigned clen = block_get2(block); // comment field length + 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 */ if (block_skip(block, 12) == -1) - // Premature end of the record. + /* Premature end of the record. */ break; - // Extract the name and skip over the extra and comment fields. + /* Extract the name and skip over the extra and comment fields. */ name = set_alloc(set, NULL, flen + 1); if (block_read(block, (unsigned char *)name, flen) < flen || block_skip(block, xlen + clen) == -1) - // Premature end of the record. + /* Premature end of the record. */ break; - // Check for embedded nuls in the name. + /* Check for embedded nuls in the name. */ if (memchr(name, 0, flen) != NULL) { - // This name can never match the zero-terminated name provided to + /* 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?) + // names anyway?) */ set_free(set, name); continue; } - // All good. Return the zero-terminated file name. + /* All good. Return the zero-terminated file name. */ name[flen] = 0; return name; } - // Invalid signature or premature end of the central directory record. - // Abandon trying to process the central directory. + /* Invalid signature or premature end of the central directory record. + // 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 +/* 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. +// file is NULL. */ extern int ZEXPORT zipAlreadyThere(zipFile file, char const *name) { zip64_internal *zip = file; if (zip == NULL) return ZIP_PARAMERROR; if (zip->central_dir.first_block == NULL) - // No central directory yet, so no, name isn't there. + /* No central directory yet, so no, name isn't there. */ return 0; if (setjmp(zip->set.env)) { - // Memory allocation failure. + /* Memory allocation failure. */ set_end(&zip->set); return -2; } 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. + /* This is the first time here with some central directory content. We + // 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. + /* 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. + // here. */ for (;;) { char *there = block_central_name(&zip->block, &zip->set); if (there == NULL) { if (zip->block.next == NULL) - // The central directory is invalid. + /* The central directory is invalid. */ return -1; break; } - // Add there to the set. + /* 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. + /* There's already a duplicate in the central directory! We'll just + // let this be and carry on. */ set_free(&zip->set, there); } - // Return true if name is in the central directory. + /* Return true if name is in the central directory. */ size_t len = strlen(name); char *copy = set_alloc(&zip->set, NULL, len + 1); - strcpy(copy, name); + memcpy(copy, name, len + 1); int found = set_found(&zip->set, copy); set_free(&zip->set, copy); return found; @@ -792,7 +795,7 @@ local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib for (i=(int)uReadSize-3; (i--)>0;) { - // Signature "0x07064b50" Zip64 end of central directory locator + /* 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; @@ -840,7 +843,7 @@ local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) return 0; - if (uL != 0x06064b50) // signature of 'Zip64 end of central directory' + if (uL != 0x06064b50) /* signature of 'Zip64 end of central directory' */ return 0; return relativeOffset; @@ -869,7 +872,7 @@ local int LoadCentralDirectoryRecord(zip64_internal* pziinit) { int hasZIP64Record = 0; - // check first if we find a ZIP64 record + /* check first if we find a ZIP64 record */ central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream); if(central_pos > 0) { @@ -935,13 +938,13 @@ local int LoadCentralDirectoryRecord(zip64_internal* pziinit) { if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK) err=ZIP_ERRNO; - // TODO.. - // read the comment from the standard central header. + /* TODO.. + // read the comment from the standard central header. */ size_comment = 0; } else { - // Read End of central Directory info + /* Read End of central Directory info */ if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) err=ZIP_ERRNO; @@ -1084,7 +1087,7 @@ extern zipFile ZEXPORT zipOpen3(const void *pathname, int append, zipcharpc* glo ziinit.number_entry = 0; ziinit.add_position_when_writing_offset = 0; init_linkedlist(&(ziinit.central_dir)); - memset(&ziinit.set, 0, sizeof(set_t)); // make sure set appears dormant + memset(&ziinit.set, 0, sizeof(set_t)); /* make sure set appears dormant */ @@ -1100,7 +1103,7 @@ extern zipFile ZEXPORT zipOpen3(const void *pathname, int append, zipcharpc* glo ziinit.globalcomment = NULL; if (append == APPEND_STATUS_ADDINZIP) { - // Read and Cache Central Directory Records + /* Read and Cache Central Directory Records */ err = LoadCentralDirectoryRecord(&ziinit); } @@ -1141,6 +1144,7 @@ extern zipFile ZEXPORT zipOpen2_64(const void *pathname, int append, zipcharpc* { zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def; + zlib_filefunc64_32_def_fill.zopen32_file = NULL; zlib_filefunc64_32_def_fill.ztell32_file = NULL; zlib_filefunc64_32_def_fill.zseek32_file = NULL; return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); @@ -1184,7 +1188,7 @@ local int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt s if (err==ZIP_OK) err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4); - // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later + /* CRC / Compressed size / Uncompressed size will be filled in later and rewritten later */ if (err==ZIP_OK) err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */ if (err==ZIP_OK) @@ -1228,13 +1232,13 @@ local int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt s if ((err==ZIP_OK) && (zi->ci.zip64)) { - // write the Zip64 extended info + /* write the Zip64 extended info */ short HeaderID = 1; short DataSize = 16; ZPOS64_T CompressedSize = 0; ZPOS64_T UncompressedSize = 0; - // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file) + /* Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file) */ zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream); err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)HeaderID,2); @@ -1247,6 +1251,46 @@ local int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt s return err; } +/* Return the length of the UTF-8 code at str[0..len-1] in [1..4], or negative + if there is no valid UTF-8 code there. If negative, it is minus the number + of bytes examined in order to determine it was bad. Or if minus the return + code is one less than len, then at least one more byte than provided would + be needed to complete the code. */ +local int utf8len(unsigned char const *str, size_t len) { + return + len == 0 ? -1 : /* empty input */ + str[0] < 0x80 ? 1 : /* good one-byte */ + str[0] < 0xc0 ? -1 : /* bad first byte */ + len < 2 || (str[1] >> 6) != 2 ? -2 : /* missing or bad 2nd byte */ + str[0] < 0xc2 ? -2 : /* overlong code */ + str[0] < 0xe0 ? 2 : /* good two-byte */ + len < 3 || (str[2] >> 6) != 2 ? -3 : /* missing or bad 3rd byte */ + str[0] == 0xe0 && str[1] < 0xa0 ? -3 : /* overlong code */ + str[0] < 0xf0 ? 3 : /* good three-byte */ + len < 4 || (str[3] >> 6) != 2 ? -4 : /* missing or bad 4th byte */ + str[0] == 0xf0 && str[1] < 0x90 ? -4 : /* overlong code */ + str[0] < 0xf4 || + (str[0] == 0xf4 && str[1] < 0x90) ? 4 : /* good four-byte */ + -4; /* code > 0x10ffff */ +} + +/* Return true if str[0..len-1] is valid UTF-8 *and* it contains at least one + code of two or more bytes. This is used to determine whether or not to set + bit 11 in the zip header flags. */ +local int isutf8(char const *str, size_t len) { + int utf8 = 0; + while (len) { + int code = utf8len((unsigned char const *)str, len); + if (code < 0) + return 0; + if (code > 1) + utf8 = 1; + str += code; + len -= (unsigned)code; + } + return utf8; +} + /* NOTE. When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped @@ -1284,14 +1328,14 @@ extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char* filename, c return ZIP_PARAMERROR; #endif - // The filename and comment length must fit in 16 bits. + /* The filename and comment length must fit in 16 bits. */ if ((filename!=NULL) && (strlen(filename)>0xffff)) 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 + /* 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. + // length, but that will be checked for later. */ if ((size_extrafield_local>0xffff) || (size_extrafield_global>0xffff)) return ZIP_PARAMERROR; @@ -1333,6 +1377,9 @@ extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char* filename, c zi->ci.flag |= 6; if (password != NULL) zi->ci.flag |= 1; + if (isutf8(filename, size_filename) && + (size_comment == 0 || isutf8(comment, size_comment))) + zi->ci.flag |= (1 << 11); zi->ci.crc32 = 0; zi->ci.method = method; @@ -1343,7 +1390,7 @@ extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char* filename, c zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream); zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment; - zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data + 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); @@ -1438,7 +1485,7 @@ extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char* filename, c else if(zi->ci.method == Z_BZIP2ED) { #ifdef HAVE_BZIP2 - // Init BZip stuff here + /* Init BZip stuff here */ zi->ci.bstream.bzalloc = 0; zi->ci.bstream.bzfree = 0; zi->ci.bstream.opaque = (voidpf)0; @@ -1640,7 +1687,7 @@ extern int ZEXPORT zipWriteInFileInZip(zipFile file, const void* buf, unsigned i if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) { uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32; -// uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32; +/* uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32; */ err=BZ2_bzCompress(&zi->ci.bstream, BZ_RUN); zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ; @@ -1698,7 +1745,7 @@ extern int ZEXPORT zipWriteInFileInZip(zipFile file, const void* buf, unsigned i zi->ci.pos_in_buffered_data += copy_this; } } - }// while(...) + }/* while(...) */ } return err; @@ -1804,7 +1851,7 @@ extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_si compressed_size += zi->ci.crypt_header_size; # endif - // update Current Item crc and sizes, + /* update Current Item crc and sizes, */ if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff) { /*version Made by*/ @@ -1822,7 +1869,7 @@ extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_si else zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/ - /// set internal file attributes field + /* set internal file attributes field */ if (zi->ci.stream.data_type == Z_ASCII) zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2); @@ -1831,15 +1878,15 @@ extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_si else zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/ - // Add ZIP64 extra info field for uncompressed size + /* Add ZIP64 extra info field for uncompressed size */ if(uncompressed_size >= 0xffffffff) datasize += 8; - // Add ZIP64 extra info field for compressed size + /* Add ZIP64 extra info field for compressed size */ if(compressed_size >= 0xffffffff) datasize += 8; - // Add ZIP64 extra info field for relative offset to local file header of current file + /* Add ZIP64 extra info field for relative offset to local file header of current file */ if(zi->ci.pos_local_header >= 0xffffffff) datasize += 8; @@ -1849,16 +1896,16 @@ extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_si if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree) { - // we cannot write more data to the buffer that we have room for. + /* we cannot write more data to the buffer that we have room for. */ return ZIP_BADZIPFILE; } p = zi->ci.central_header + zi->ci.size_centralheader; - // Add Extra Information Header for 'ZIP64 information' - zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID + /* Add Extra Information Header for 'ZIP64 information' */ + zip64local_putValue_inmemory(p, 0x0001, 2); /* HeaderID */ p += 2; - zip64local_putValue_inmemory(p, datasize, 2); // DataSize + zip64local_putValue_inmemory(p, datasize, 2); /* DataSize */ p += 2; if(uncompressed_size >= 0xffffffff) @@ -1879,13 +1926,13 @@ extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_si p += 8; } - // Update how much extra free space we got in the memory buffer + /* 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 ) + // ( 4 below is the size of HeaderID and DataSize field ) */ zi->ci.size_centralExtraFree -= datasize + 4; zi->ci.size_centralheader += datasize + 4; - // Update the extra info size field + /* Update the extra info size field */ zi->ci.size_centralExtra += datasize + 4; zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2); } @@ -1897,7 +1944,7 @@ extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_si if (err==ZIP_OK) { - // Update the LocalFileHeader with the new values. + /* Update the LocalFileHeader with the new values. */ ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); @@ -1911,7 +1958,7 @@ extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_si { if(zi->ci.pos_zip64extrainfo > 0) { - // Update the size in the ZIP64 extended field. + /* Update the size in the ZIP64 extended field. */ if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0) err = ZIP_ERRNO; @@ -1922,7 +1969,7 @@ extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_si err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8); } else - err = ZIP_BADZIPFILE; // Caller passed zip64 = 0, so no room for zip64 info -> fatal + err = ZIP_BADZIPFILE; /* Caller passed zip64 = 0, so no room for zip64 info -> fatal */ } else { @@ -1976,7 +2023,7 @@ local int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4); if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ? + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); /* why ZPOS64_T of this ? */ if (err==ZIP_OK) /* version made by */ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); @@ -2023,7 +2070,7 @@ local int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centr { { if(zi->number_entry >= 0xFFFF) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); /* use value in ZIP64 record */ else err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); } @@ -2032,7 +2079,7 @@ local int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centr if (err==ZIP_OK) /* total number of entries in the central dir */ { if(zi->number_entry >= 0xFFFF) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); /* use value in ZIP64 record */ else err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); } @@ -2112,7 +2159,7 @@ extern int ZEXPORT zipClose(zipFile file, const char* global_comment) { } free_linkedlist(&(zi->central_dir)); - set_end(&zi->set); // set was zeroed, so this is safe + set_end(&zi->set); /* set was zeroed, so this is safe */ pos = centraldir_pos_inzip - zi->add_position_when_writing_offset; if(pos >= 0xffffffff || zi->number_entry >= 0xFFFF) @@ -2162,13 +2209,13 @@ extern int ZEXPORT zipRemoveExtraInfoBlock(char* pData, int* dataLen, short sHea header = *(short*)p; dataSize = *(((short*)p)+1); - if( header == sHeader ) // Header found. + if( header == sHeader ) /* Header found. */ { - p += dataSize + 4; // skip it. do not copy to temp buffer + p += dataSize + 4; /* skip it. do not copy to temp buffer */ } else { - // Extra Info block should not be removed, So copy it to the temp buffer. + /* Extra Info block should not be removed, So copy it to the temp buffer. */ memcpy(pTmp, p, dataSize + 4); p += dataSize + 4; size += dataSize + 4; @@ -2178,14 +2225,14 @@ extern int ZEXPORT zipRemoveExtraInfoBlock(char* pData, int* dataLen, short sHea if(size < *dataLen) { - // clean old extra info block. + /* clean old extra info block. */ memset(pData,0, *dataLen); - // copy the new extra info block over the old + /* copy the new extra info block over the old */ if(size > 0) memcpy(pData, pNewHeader, size); - // set the new extra info size + /* set the new extra info size */ *dataLen = size; retVal = ZIP_OK; diff --git a/deps/zlib/contrib/minizip/zip.h b/deps/zlib/contrib/minizip/zip.h index 1f7f0b263d4f9b..9962440781d4a9 100644 --- a/deps/zlib/contrib/minizip/zip.h +++ b/deps/zlib/contrib/minizip/zip.h @@ -1,11 +1,10 @@ /* zip.h -- IO on .zip files using zlib - Version 1.1, February 14h, 2010 - part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + part of the MiniZip project - ( https://www.winimage.com/zLibDll/minizip.html ) - Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + Copyright (C) 1998-2026 Gilles Vollant (minizip) ( https://www.winimage.com/zLibDll/minizip.html ) Modifications for Zip64 support - Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + Copyright (C) 2009-2010 Mathias Svensson ( https://result42.com ) For more info read MiniZip_info.txt @@ -44,7 +43,7 @@ extern "C" { #endif -//#define HAVE_BZIP2 +/* #define HAVE_BZIP2 */ #ifndef _ZLIB_H #include "zlib.h" @@ -69,6 +68,8 @@ typedef zipFile__ *zipFile; typedef voidp zipFile; #endif +extern const char zip_copyright[]; + #define ZIP_OK (0) #define ZIP_EOF (0) #define ZIP_ERRNO (Z_ERRNO) diff --git a/deps/zlib/contrib/optimizations/inffast_chunk.c b/deps/zlib/contrib/optimizations/inffast_chunk.c index b1db452c2e7232..3c93da05114d35 100644 --- a/deps/zlib/contrib/optimizations/inffast_chunk.c +++ b/deps/zlib/contrib/optimizations/inffast_chunk.c @@ -1,5 +1,5 @@ /* inffast_chunk.c -- fast decoding - * Copyright (C) 1995-2017 Mark Adler + * Copyright (C) 1995-2026 Mark Adler * Copyright 2023 The Chromium Authors * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -226,7 +226,7 @@ void ZLIB_INTERNAL inflate_fast_chunk_(z_streamp strm, unsigned start) { dist += (unsigned)hold & ((1U << op) - 1); #ifdef INFLATE_STRICT if (dist > dmax) { - strm->msg = (char *)"invalid distance too far back"; + strm->msg = (z_const char *)"invalid distance too far back"; state->mode = BAD; break; } @@ -240,7 +240,7 @@ void ZLIB_INTERNAL inflate_fast_chunk_(z_streamp strm, unsigned start) { if (op > whave) { if (state->sane) { strm->msg = - (char *)"invalid distance too far back"; + (z_const char *)"invalid distance too far back"; state->mode = BAD; break; } @@ -317,7 +317,7 @@ void ZLIB_INTERNAL inflate_fast_chunk_(z_streamp strm, unsigned start) { goto dodist; } else { - strm->msg = (char *)"invalid distance code"; + strm->msg = (z_const char *)"invalid distance code"; state->mode = BAD; break; } @@ -332,7 +332,7 @@ void ZLIB_INTERNAL inflate_fast_chunk_(z_streamp strm, unsigned start) { break; } else { - strm->msg = (char *)"invalid literal/length code"; + strm->msg = (z_const char *)"invalid literal/length code"; state->mode = BAD; break; } diff --git a/deps/zlib/contrib/optimizations/inflate.c b/deps/zlib/contrib/optimizations/inflate.c index c535c5af0c89ee..3268320e912049 100644 --- a/deps/zlib/contrib/optimizations/inflate.c +++ b/deps/zlib/contrib/optimizations/inflate.c @@ -935,7 +935,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) { while (state->have < 19) state->lens[order[state->have++]] = 0; state->next = state->codes; - state->lencode = (const code FAR *)(state->next); + state->lencode = state->distcode = (const code FAR *)(state->next); state->lenbits = 7; ret = inflate_table(CODES, state->lens, 19, &(state->next), &(state->lenbits), state->work); diff --git a/deps/zlib/contrib/tests/fuzzers/inflate_fuzzer.cc b/deps/zlib/contrib/tests/fuzzers/inflate_fuzzer.cc index d9d62026e42956..938c25121acf95 100644 --- a/deps/zlib/contrib/tests/fuzzers/inflate_fuzzer.cc +++ b/deps/zlib/contrib/tests/fuzzers/inflate_fuzzer.cc @@ -35,6 +35,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } inflate(&stream, Z_NO_FLUSH); + + z_stream copy; + inflateCopy(©, &stream); + inflateEnd(©); + inflateEnd(&stream); return 0; diff --git a/deps/zlib/contrib/tests/utils_unittest.cc b/deps/zlib/contrib/tests/utils_unittest.cc index 7d3772aa05df36..f8cd93c705583b 100644 --- a/deps/zlib/contrib/tests/utils_unittest.cc +++ b/deps/zlib/contrib/tests/utils_unittest.cc @@ -1166,6 +1166,79 @@ TEST(ZlibTest, DeflateBound) { deflateEnd(&stream); } +TEST(ZlibTest, InflateCopySIGILLReproduction) { + z_stream c_stream; + c_stream.zalloc = Z_NULL; + c_stream.zfree = Z_NULL; + c_stream.opaque = Z_NULL; + + // 1. Start with Z_FIXED to set distcode to distfix. + EXPECT_EQ(Z_OK, deflateInit2(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15, + 8, Z_FIXED)); + + std::string data1 = + "Some data for a fixed block. This ensures distcode " + "points to distfix."; + c_stream.next_in = reinterpret_cast(const_cast(data1.data())); + c_stream.avail_in = data1.size(); + + std::vector compressed(4096); + c_stream.next_out = compressed.data(); + c_stream.avail_out = compressed.size(); + + EXPECT_EQ(Z_OK, deflate(&c_stream, Z_SYNC_FLUSH)); + + // 2. Switch to Z_DEFAULT_STRATEGY to trigger dynamic trees in the next block. + EXPECT_EQ(Z_OK, deflateParams(&c_stream, Z_DEFAULT_COMPRESSION, + Z_DEFAULT_STRATEGY)); + + // Feed enough data to ensure a dynamic block is created. + std::string data2; + for (int j = 0; j < 100; ++j) { + data2 += "Much more data that should definitely trigger a dynamic block. " + + std::to_string(j) + " "; + data2 += "Repeated data: abcdefghijklmnopqrstuvwxyz 0123456789. "; + } + c_stream.next_in = reinterpret_cast(const_cast(data2.data())); + c_stream.avail_in = data2.size(); + + EXPECT_EQ(Z_STREAM_END, deflate(&c_stream, Z_FINISH)); + compressed.resize(c_stream.total_out); + EXPECT_EQ(Z_OK, deflateEnd(&c_stream)); + + // 3. Decompress and call inflateCopy at every byte boundary. + for (size_t i = 1; i <= compressed.size(); ++i) { + z_stream d_stream; + d_stream.zalloc = Z_NULL; + d_stream.zfree = Z_NULL; + d_stream.opaque = Z_NULL; + d_stream.next_in = compressed.data(); + d_stream.avail_in = i; + + EXPECT_EQ(Z_OK, inflateInit(&d_stream)); + + std::vector out(1024 * 1024); + d_stream.next_out = out.data(); + d_stream.avail_out = out.size(); + + int ret = inflate(&d_stream, Z_NO_FLUSH); + EXPECT_TRUE(ret == Z_OK || ret == Z_STREAM_END || ret == Z_BUF_ERROR); + + z_stream copy_stream; + copy_stream.zalloc = Z_NULL; + copy_stream.zfree = Z_NULL; + copy_stream.opaque = Z_NULL; + + // This is where the SIGILL crash should happen. + int copy_ret = inflateCopy(©_stream, &d_stream); + if (copy_ret == Z_OK) { + inflateEnd(©_stream); + } + + inflateEnd(&d_stream); + } +} + // TODO(gustavoa): make these tests run standalone. #ifndef CMAKE_STANDALONE_UNITTESTS @@ -1324,8 +1397,9 @@ TEST(ZlibTest, ZipUnicodePathExtra) { ASSERT_EQ(unzGoToFirstFile(uzf), UNZ_OK); ASSERT_EQ(unzGetCurrentFileInfo(uzf, &file_info, long_buf, sizeof(long_buf), nullptr, 0, nullptr, 0), UNZ_OK); - ASSERT_EQ(file_info.size_filename, 14); - ASSERT_EQ(std::string(long_buf), "\xec\x83\x88 \xeb\xac\xb8\xec\x84\x9c.txt"); + ASSERT_EQ(file_info.size_filename, 11); + ASSERT_EQ(file_info.size_utf8_filename, 14); + ASSERT_EQ(std::string(file_info.utf8_filename), "\xec\x83\x88 \xeb\xac\xb8\xec\x84\x9c.txt"); // Even if the file name buffer is too short to hold the whole filename, the // unicode path extra field should get parsed correctly, size_filename set, @@ -1333,17 +1407,49 @@ TEST(ZlibTest, ZipUnicodePathExtra) { ASSERT_EQ(unzGoToFirstFile(uzf), UNZ_OK); ASSERT_EQ(unzGetCurrentFileInfo(uzf, &file_info, short_buf, sizeof(short_buf), nullptr, 0, nullptr, 0), UNZ_OK); - ASSERT_EQ(file_info.size_filename, 14); - ASSERT_EQ(std::string(short_buf, sizeof(short_buf)), "\xec\x83\x88"); + ASSERT_EQ(file_info.size_filename, 11); + ASSERT_EQ(std::string(short_buf, sizeof(short_buf)), "\xc8\xfe\x20"); + ASSERT_EQ(file_info.size_utf8_filename, 14); + ASSERT_EQ(std::string(file_info.utf8_filename), "\xec\x83\x88 \xeb\xac\xb8\xec\x84\x9c.txt"); // Also with a null filename buffer, the unicode path extra field should get // parsed and size_filename set correctly. ASSERT_EQ(unzGoToFirstFile(uzf), UNZ_OK); ASSERT_EQ(unzGetCurrentFileInfo(uzf, &file_info, nullptr, 0, nullptr, 0, nullptr, 0), UNZ_OK); - ASSERT_EQ(file_info.size_filename, 14); + ASSERT_EQ(file_info.size_filename, 11); + ASSERT_EQ(file_info.size_utf8_filename, 14); + ASSERT_EQ(std::string(file_info.utf8_filename), "\xec\x83\x88 \xeb\xac\xb8\xec\x84\x9c.txt"); EXPECT_EQ(unzClose(uzf), UNZ_OK); } +TEST(ZlibTest, Crbug500521311) { + base::FilePath zip_file = TestDataDir().AppendASCII("bug500521311.zip"); + unzFile uzf = unzOpen(zip_file.AsUTF8Unsafe().c_str()); + ASSERT_NE(uzf, nullptr); + + char buf[256]; + unz_file_info file_info; + + // aaaaaa... + ASSERT_EQ(unzGoToFirstFile(uzf), UNZ_OK); + ASSERT_EQ(unzGetCurrentFileInfo(uzf, &file_info, buf, sizeof(buf), + nullptr, 0, nullptr, 0), UNZ_OK); + EXPECT_EQ(std::string(file_info.utf8_filename), + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); + + // The Unicode Path Extra Field in the first Local File Header could + // previously cause unzGoToNextFile() to advance the wrong amount, + // potentially skipping a central directory entry. + ASSERT_EQ(unzGoToNextFile(uzf), UNZ_OK); + + // evil.exe + ASSERT_EQ(unzGetCurrentFileInfo(uzf, &file_info, buf, sizeof(buf), + nullptr, 0, nullptr, 0), UNZ_OK); + EXPECT_EQ(std::string(buf), "evil.exe"); + EXPECT_EQ(unzGoToNextFile(uzf), UNZ_END_OF_LIST_OF_FILE); + EXPECT_EQ(unzClose(uzf), UNZ_OK); +} + #endif diff --git a/deps/zlib/crc32.c b/deps/zlib/crc32.c index 204aa1ad0c445a..2ec5ab5cebef36 100644 --- a/deps/zlib/crc32.c +++ b/deps/zlib/crc32.c @@ -1,5 +1,5 @@ /* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995-2022 Mark Adler + * Copyright (C) 1995-2026 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h * * This interleaved implementation of a CRC makes use of pipelined multiple @@ -24,13 +24,20 @@ # include # ifndef DYNAMIC_CRC_TABLE # define DYNAMIC_CRC_TABLE -# endif /* !DYNAMIC_CRC_TABLE */ -#endif /* MAKECRCH */ +# endif +#endif +#ifdef DYNAMIC_CRC_TABLE +# define Z_ONCE +#endif #include "deflate.h" #include "cpu_features.h" #include "zutil.h" /* for Z_U4, Z_U8, z_crc_t, and FAR definitions */ +#ifdef HAVE_S390X_VX +# include "contrib/crc32vx/crc32_vx_hooks.h" +#endif + #if defined(CRC32_SIMD_SSE42_PCLMUL) || defined(CRC32_ARMV8_CRC32) #include "crc32_simd.h" #endif @@ -105,8 +112,8 @@ #endif /* If available, use the ARM processor CRC32 instruction. */ -#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8 \ - && defined(USE_CANONICAL_ARMV8_CRC32) +#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && \ + defined(W) && W == 8 && defined(USE_CANONICAL_ARMV8_CRC32) # define ARMCRC32_CANONICAL_ZLIB #endif @@ -159,10 +166,10 @@ local z_word_t byte_swap(z_word_t word) { Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial, reflected. For speed, this requires that a not be zero. */ -local z_crc_t multmodp(z_crc_t a, z_crc_t b) { - z_crc_t m, p; +local uLong multmodp(uLong a, uLong b) { + uLong m, p; - m = (z_crc_t)1 << 31; + m = (uLong)1 << 31; p = 0; for (;;) { if (a & m) { @@ -178,12 +185,12 @@ local z_crc_t multmodp(z_crc_t a, z_crc_t b) { /* Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been - initialized. + initialized. n must not be negative. */ -local z_crc_t x2nmodp(z_off64_t n, unsigned k) { - z_crc_t p; +local uLong x2nmodp(z_off64_t n, unsigned k) { + uLong p; - p = (z_crc_t)1 << 31; /* x^0 == 1 */ + p = (uLong)1 << 31; /* x^0 == 1 */ while (n) { if (n & 1) p = multmodp(x2n_table[k & 31], p); @@ -211,83 +218,8 @@ local z_crc_t FAR crc_table[256]; local void write_table64(FILE *, const z_word_t FAR *, int); #endif /* MAKECRCH */ -/* - Define a once() function depending on the availability of atomics. If this is - compiled with DYNAMIC_CRC_TABLE defined, and if CRCs will be computed in - multiple threads, and if atomics are not available, then get_crc_table() must - be called to initialize the tables and must return before any threads are - allowed to compute or combine CRCs. - */ - -/* Definition of once functionality. */ -typedef struct once_s once_t; - -/* Check for the availability of atomics. */ -#if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \ - !defined(__STDC_NO_ATOMICS__) - -#include - -/* Structure for once(), which must be initialized with ONCE_INIT. */ -struct once_s { - atomic_flag begun; - atomic_int done; -}; -#define ONCE_INIT {ATOMIC_FLAG_INIT, 0} - -/* - Run the provided init() function exactly once, even if multiple threads - invoke once() at the same time. The state must be a once_t initialized with - ONCE_INIT. - */ -local void once(once_t *state, void (*init)(void)) { - if (!atomic_load(&state->done)) { - if (atomic_flag_test_and_set(&state->begun)) - while (!atomic_load(&state->done)) - ; - else { - init(); - atomic_store(&state->done, 1); - } - } -} - -#else /* no atomics */ - -/* Structure for once(), which must be initialized with ONCE_INIT. */ -struct once_s { - volatile int begun; - volatile int done; -}; -#define ONCE_INIT {0, 0} - -/* Test and set. Alas, not atomic, but tries to minimize the period of - vulnerability. */ -local int test_and_set(int volatile *flag) { - int was; - - was = *flag; - *flag = 1; - return was; -} - -/* Run the provided init() function once. This is not thread-safe. */ -local void once(once_t *state, void (*init)(void)) { - if (!state->done) { - if (test_and_set(&state->begun)) - while (!state->done) - ; - else { - init(); - state->done = 1; - } - } -} - -#endif - /* State for once(). */ -local once_t made = ONCE_INIT; +local z_once_t made = Z_ONCE_INIT; /* Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: @@ -333,7 +265,7 @@ local void make_crc_table(void) p = (z_crc_t)1 << 30; /* x^1 */ x2n_table[0] = p; for (n = 1; n < 32; n++) - x2n_table[n] = p = multmodp(p, p); + x2n_table[n] = p = (z_crc_t)multmodp(p, p); #ifdef W /* initialize the braiding tables -- needs x2n_table[] */ @@ -536,11 +468,11 @@ local void braid(z_crc_t ltl[][256], z_word_t big[][256], int n, int w) { int k; z_crc_t i, p, q; for (k = 0; k < w; k++) { - p = x2nmodp((n * w + 3 - k) << 3, 0); + p = (z_crc_t)x2nmodp((n * w + 3 - k) << 3, 0); ltl[k][0] = 0; big[w - 1 - k][0] = 0; for (i = 1; i < 256; i++) { - ltl[k][i] = q = multmodp(i << 24, p); + ltl[k][i] = q = (z_crc_t)multmodp(i << 24, p); big[w - 1 - k][i] = byte_swap(q); } } @@ -555,7 +487,7 @@ local void braid(z_crc_t ltl[][256], z_word_t big[][256], int n, int w) { */ const z_crc_t FAR * ZEXPORT get_crc_table(void) { #ifdef DYNAMIC_CRC_TABLE - once(&made, make_crc_table); + z_once(&made, make_crc_table); #endif /* DYNAMIC_CRC_TABLE */ return (const z_crc_t FAR *)crc_table; } @@ -579,9 +511,8 @@ const z_crc_t FAR * ZEXPORT get_crc_table(void) { #define Z_BATCH_ZEROS 0xa10d3d0c /* computed from Z_BATCH = 3990 */ #define Z_BATCH_MIN 800 /* fewest words in a final batch */ -unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, - z_size_t len) { - z_crc_t val; +uLong ZEXPORT crc32_z(uLong crc, const unsigned char FAR *buf, z_size_t len) { + uLong val; z_word_t crc1, crc2; const z_word_t *word; z_word_t val0, val1, val2; @@ -592,7 +523,7 @@ unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, if (buf == Z_NULL) return 0; #ifdef DYNAMIC_CRC_TABLE - once(&made, make_crc_table); + z_once(&made, make_crc_table); #endif /* DYNAMIC_CRC_TABLE */ /* Pre-condition the CRC */ @@ -647,7 +578,7 @@ unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, } word += 3 * last; num -= 3 * last; - val = x2nmodp(last, 6); + val = x2nmodp((int)last, 6); crc = multmodp(val, crc) ^ crc1; crc = multmodp(val, crc) ^ crc2; } @@ -698,8 +629,7 @@ local z_word_t crc_word_big(z_word_t data) { #endif /* ========================================================================= */ -unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, - z_size_t len) { +uLong ZEXPORT crc32_z(uLong crc, const unsigned char FAR *buf, z_size_t len) { /* If no optimizations are enabled, do it as canonical zlib. */ #if !defined(CRC32_SIMD_SSE42_PCLMUL) && !defined(CRC32_ARMV8_CRC32) && \ @@ -770,7 +700,7 @@ unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, #endif /* CRC32_SIMD */ #ifdef DYNAMIC_CRC_TABLE - once(&made, make_crc_table); + z_once(&made, make_crc_table); #endif /* DYNAMIC_CRC_TABLE */ /* Pre-condition the CRC */ crc = (~crc) & 0xffffffff; @@ -1084,8 +1014,11 @@ unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, #endif /* ========================================================================= */ -unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, - uInt len) { +uLong ZEXPORT crc32(uLong crc, const unsigned char FAR *buf, uInt len) { + #ifdef HAVE_S390X_VX + return crc32_z_hook(crc, buf, len); + #endif + /* Some bots compile with optimizations disabled, others will emulate * ARM on x86 and other weird combinations. */ @@ -1126,33 +1059,34 @@ unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, } /* ========================================================================= */ -uLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2) { +uLong ZEXPORT crc32_combine_gen64(z_off64_t len2) { + if (len2 < 0) + return 0; #ifdef DYNAMIC_CRC_TABLE - once(&made, make_crc_table); + z_once(&made, make_crc_table); #endif /* DYNAMIC_CRC_TABLE */ - return multmodp(x2nmodp(len2, 3), crc1) ^ (crc2 & 0xffffffff); + return x2nmodp(len2, 3); } /* ========================================================================= */ -uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2) { - return crc32_combine64(crc1, crc2, (z_off64_t)len2); +uLong ZEXPORT crc32_combine_gen(z_off_t len2) { + return crc32_combine_gen64((z_off64_t)len2); } /* ========================================================================= */ -uLong ZEXPORT crc32_combine_gen64(z_off64_t len2) { -#ifdef DYNAMIC_CRC_TABLE - once(&made, make_crc_table); -#endif /* DYNAMIC_CRC_TABLE */ - return x2nmodp(len2, 3); +uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op) { + if (op == 0) + return 0; + return multmodp(op, crc1 & 0xffffffff) ^ (crc2 & 0xffffffff); } /* ========================================================================= */ -uLong ZEXPORT crc32_combine_gen(z_off_t len2) { - return crc32_combine_gen64((z_off64_t)len2); +uLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2) { + return crc32_combine_op(crc1, crc2, crc32_combine_gen64(len2)); } /* ========================================================================= */ -uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op) { - return multmodp(op, crc1) ^ (crc2 & 0xffffffff); +uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2) { + return crc32_combine64(crc1, crc2, (z_off64_t)len2); } ZLIB_INTERNAL void crc_reset(deflate_state *const s) diff --git a/deps/zlib/deflate.c b/deps/zlib/deflate.c index 872ba79017836b..d95787f286d8a9 100644 --- a/deps/zlib/deflate.c +++ b/deps/zlib/deflate.c @@ -1,5 +1,5 @@ /* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler + * Copyright (C) 1995-2026 Jean-loup Gailly and Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -37,7 +37,7 @@ * REFERENCES * * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". - * Available in http://tools.ietf.org/html/rfc1951 + * Available at https://datatracker.ietf.org/doc/html/rfc1951 * * A description of the Rabin and Karp algorithm is given in the book * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. @@ -69,7 +69,7 @@ #endif const char deflate_copyright[] = - " deflate 1.3.1 Copyright 1995-2024 Jean-loup Gailly and Mark Adler "; + " deflate 1.3.2.1 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 @@ -163,8 +163,8 @@ local const config configuration_table[10] = { #define CLEAR_HASH(s) \ do { \ s->head[s->hash_size - 1] = NIL; \ - zmemzero((Bytef *)s->head, \ - (unsigned)(s->hash_size - 1)*sizeof(*s->head)); \ + zmemzero(s->head, (unsigned)(s->hash_size - 1)*sizeof(*s->head)); \ + s->slid = 0; \ } while (0) /* =========================================================================== @@ -180,6 +180,7 @@ local const config configuration_table[10] = { local void slide_hash(deflate_state *s) { #if defined(DEFLATE_SLIDE_HASH_SSE2) || defined(DEFLATE_SLIDE_HASH_NEON) slide_hash_simd(s->head, s->prev, s->w_size, s->hash_size); + s->slid = 1; return; #endif @@ -193,8 +194,8 @@ local void slide_hash(deflate_state *s) { m = *--p; *p = (Pos)(m >= wsize ? m - wsize : NIL); } while (--n); - n = wsize; #ifndef FASTEST + n = wsize; p = &s->prev[n]; do { m = *--p; @@ -204,6 +205,7 @@ local void slide_hash(deflate_state *s) { */ } while (--n); #endif + s->slid = 1; } /* =========================================================================== @@ -261,7 +263,14 @@ local void fill_window(deflate_state *s) { more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); /* Deal with !@#$% 64K limit: */ +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4127) +#endif if (sizeof(int) <= 2) { +#ifdef _MSC_VER +#pragma warning(pop) +#endif if (more == 0 && s->strstart == 0 && s->lookahead == 0) { more = wsize; @@ -458,6 +467,7 @@ int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); if (s == Z_NULL) return Z_MEM_ERROR; + zmemzero(s, sizeof(deflate_state)); strm->state = (struct internal_state FAR *)s; s->strm = strm; s->status = INIT_STATE; /* to pass state test in deflateReset() */ @@ -763,10 +773,23 @@ int ZEXPORT deflateSetHeader(z_streamp strm, gz_headerp head) { /* ========================================================================= */ int ZEXPORT deflatePending(z_streamp strm, unsigned *pending, int *bits) { if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - if (pending != Z_NULL) - *pending = strm->state->pending; if (bits != Z_NULL) *bits = strm->state->bi_valid; + if (pending != Z_NULL) { + *pending = (unsigned)strm->state->pending; + if (*pending != strm->state->pending) { + *pending = (unsigned)-1; + return Z_BUF_ERROR; + } + } + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateUsed(z_streamp strm, int *bits) { + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; + if (bits != Z_NULL) + *bits = strm->state->bi_used; return Z_OK; } @@ -886,28 +909,34 @@ int ZEXPORT deflateTune(z_streamp strm, int good_length, int max_lazy, * * Shifts are used to approximate divisions, for speed. */ -uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) { +z_size_t ZEXPORT deflateBound_z(z_streamp strm, z_size_t sourceLen) { deflate_state *s; - uLong fixedlen, storelen, wraplen; + z_size_t fixedlen, storelen, wraplen, bound; /* upper bound for fixed blocks with 9-bit literals and length 255 (memLevel == 2, which is the lowest that may not use stored blocks) -- ~13% overhead plus a small constant */ fixedlen = sourceLen + (sourceLen >> 3) + (sourceLen >> 8) + (sourceLen >> 9) + 4; + if (fixedlen < sourceLen) + fixedlen = (z_size_t)-1; /* upper bound for stored blocks with length 127 (memLevel == 1) -- ~4% overhead plus a small constant */ storelen = sourceLen + (sourceLen >> 5) + (sourceLen >> 7) + (sourceLen >> 11) + 7; + if (storelen < sourceLen) + storelen = (z_size_t)-1; - /* if can't get parameters, return larger bound plus a zlib wrapper */ - if (deflateStateCheck(strm)) - return (fixedlen > storelen ? fixedlen : storelen) + 6; + /* if can't get parameters, return larger bound plus a wrapper */ + if (deflateStateCheck(strm)) { + bound = fixedlen > storelen ? fixedlen : storelen; + return bound + 18 < bound ? (z_size_t)-1 : bound + 18; + } /* compute wrapper length */ s = strm->state; - switch (s->wrap) { + switch (s->wrap < 0 ? -s->wrap : s->wrap) { case 0: /* raw deflate */ wraplen = 0; break; @@ -937,24 +966,33 @@ uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) { break; #endif default: /* for compiler happiness */ - wraplen = 6; + wraplen = 18; } /* With Chromium's hashing, s->hash_bits may not correspond to the memLevel, making the computations below incorrect. Return the conservative bound. */ - if (s->chromium_zlib_hash) - return (fixedlen > storelen ? fixedlen : storelen) + wraplen; + if (s->chromium_zlib_hash) { + bound = fixedlen > storelen ? fixedlen : storelen; + return bound + wraplen < bound ? (z_size_t)-1 : bound + wraplen; + } /* if not default parameters, return one of the conservative bounds */ - if (s->w_bits != 15 || s->hash_bits != 8 + 7) - return (s->w_bits <= s->hash_bits && s->level ? fixedlen : storelen) + - wraplen; + if (s->w_bits != 15 || s->hash_bits != 8 + 7) { + bound = s->w_bits <= s->hash_bits && s->level ? fixedlen : + storelen; + return bound + wraplen < bound ? (z_size_t)-1 : bound + wraplen; + } /* default settings: return tight bound for that case -- ~0.03% overhead plus a small constant */ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13 - 6 + wraplen; + bound = sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13 - 6 + wraplen; + return bound < sourceLen ? (z_size_t)-1 : bound; +} +uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) { + z_size_t bound = deflateBound_z(strm, sourceLen); + return (uLong)bound != bound ? (uLong)-1 : (uLong)bound; } /* ========================================================================= @@ -984,8 +1022,8 @@ local void flush_pending(z_streamp strm) { #endif _tr_flush_bits(s); - len = s->pending; - if (len > strm->avail_out) len = strm->avail_out; + len = s->pending > strm->avail_out ? strm->avail_out : + (unsigned)s->pending; if (len == 0) return; zmemcpy(strm->next_out, s->pending_out, len); @@ -1005,8 +1043,8 @@ local void flush_pending(z_streamp strm) { #define HCRC_UPDATE(beg) \ do { \ if (s->gzhead->hcrc && s->pending > (beg)) \ - strm->adler = crc32(strm->adler, s->pending_buf + (beg), \ - s->pending - (beg)); \ + strm->adler = crc32_z(strm->adler, s->pending_buf + (beg), \ + s->pending - (beg)); \ } while (0) /* ========================================================================= */ @@ -1140,8 +1178,8 @@ int ZEXPORT deflate(z_streamp strm, int flush) { put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); } if (s->gzhead->hcrc) - strm->adler = crc32(strm->adler, s->pending_buf, - s->pending); + strm->adler = crc32_z(strm->adler, s->pending_buf, + s->pending); s->gzindex = 0; s->status = EXTRA_STATE; } @@ -1149,9 +1187,9 @@ int ZEXPORT deflate(z_streamp strm, int flush) { if (s->status == EXTRA_STATE) { if (s->gzhead->extra != Z_NULL) { ulg beg = s->pending; /* start of bytes to update crc */ - uInt left = (s->gzhead->extra_len & 0xffff) - s->gzindex; + ulg left = (s->gzhead->extra_len & 0xffff) - s->gzindex; while (s->pending + left > s->pending_buf_size) { - uInt copy = s->pending_buf_size - s->pending; + ulg copy = s->pending_buf_size - s->pending; zmemcpy(s->pending_buf + s->pending, s->gzhead->extra + s->gzindex, copy); s->pending = s->pending_buf_size; @@ -1369,12 +1407,13 @@ int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) { ss = source->state; - zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); + zmemcpy(dest, source, sizeof(z_stream)); ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); if (ds == Z_NULL) return Z_MEM_ERROR; + zmemzero(ds, sizeof(deflate_state)); dest->state = (struct internal_state FAR *) ds; - zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); + zmemcpy(ds, ss, sizeof(deflate_state)); ds->strm = dest; ds->window = (Bytef *) ZALLOC(dest, @@ -1394,22 +1433,22 @@ int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) { return Z_MEM_ERROR; } /* following zmemcpy do not work for 16-bit MSDOS */ - zmemcpy(ds->window, ss->window, - (ds->w_size + WINDOW_PADDING) * 2 * sizeof(Byte)); - zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); - zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); -#ifdef LIT_MEM - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->lit_bufsize * 5); -#else - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); -#endif + zmemcpy(ds->window, ss->window, ss->high_water); + zmemcpy(ds->prev, ss->prev, + (ss->slid || ss->strstart - ss->insert > ds->w_size ? ds->w_size : + ss->strstart - ss->insert) * sizeof(Pos)); + zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + zmemcpy(ds->pending_out, ss->pending_out, ss->pending); #ifdef LIT_MEM ds->d_buf = (ushf *)(ds->pending_buf + (ds->lit_bufsize << 1)); ds->l_buf = ds->pending_buf + (ds->lit_bufsize << 2); + zmemcpy(ds->d_buf, ss->d_buf, ss->sym_next * sizeof(ush)); + zmemcpy(ds->l_buf, ss->l_buf, ss->sym_next); #else ds->sym_buf = ds->pending_buf + ds->lit_bufsize; + zmemcpy(ds->sym_buf, ss->sym_buf, ss->sym_next); #endif ds->l_desc.dyn_tree = ds->dyn_ltree; @@ -1440,9 +1479,9 @@ int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) { */ local uInt longest_match(deflate_state *s, IPos cur_match) { unsigned chain_length = s->max_chain_length;/* max hash chain length */ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ + Bytef *scan = s->window + s->strstart; /* current string */ + Bytef *match; /* matched string */ + int len; /* length of current match */ int best_len = (int)s->prev_length; /* best match length so far */ int nice_match = s->nice_match; /* stop if match long enough */ IPos limit = s->strstart > (IPos)MAX_DIST(s) ? @@ -1457,13 +1496,13 @@ local uInt longest_match(deflate_state *s, IPos cur_match) { /* Compare two bytes at a time. Note: this is not always beneficial. * Try with and without -DUNALIGNED_OK to check. */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; - register ush scan_start = *(ushf*)scan; - register ush scan_end = *(ushf*)(scan + best_len - 1); + Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + ush scan_start = *(ushf*)scan; + ush scan_end = *(ushf*)(scan + best_len - 1); #else - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - register Byte scan_end1 = scan[best_len - 1]; - register Byte scan_end = scan[best_len]; + Bytef *strend = s->window + s->strstart + MAX_MATCH; + Byte scan_end1 = scan[best_len - 1]; + Byte scan_end = scan[best_len]; #endif /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. @@ -1605,10 +1644,10 @@ local uInt longest_match(deflate_state *s, IPos cur_match) { * Optimized version for FASTEST only */ local uInt longest_match(deflate_state *s, IPos cur_match) { - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH; + Bytef *scan = s->window + s->strstart; /* current string */ + Bytef *match; /* matched string */ + int len; /* length of current match */ + Bytef *strend = s->window + s->strstart + MAX_MATCH; /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. * It is easy to get rid of this optimization if necessary. @@ -1668,7 +1707,7 @@ local uInt longest_match(deflate_state *s, IPos cur_match) { local void check_match(deflate_state *s, IPos start, IPos match, int length) { /* check that the match is indeed a match */ Bytef *back = s->window + (int)match, *here = s->window + start; - IPos len = length; + IPos len = (IPos)length; if (match == (IPos)-1) { /* match starts one byte before the current window -- just compare the subsequent length-1 bytes */ @@ -1740,13 +1779,14 @@ local block_state deflate_stored(deflate_state *s, int flush) { * this is 32K. This can be as small as 507 bytes for memLevel == 1. For * large input and output buffers, the stored block size will be larger. */ - unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size); + unsigned min_block = (unsigned)(MIN(s->pending_buf_size - 5, s->w_size)); /* Copy as many min_block or larger stored blocks directly to next_out as * possible. If flushing, copy the remaining available input to next_out as * stored blocks, if there is enough space. */ - unsigned len, left, have, last = 0; + int last = 0; + unsigned len, left, have; unsigned used = s->strm->avail_in; do { /* Set len to the maximum size block that we can copy directly with the @@ -1754,12 +1794,12 @@ local block_state deflate_stored(deflate_state *s, int flush) { * would be copied from what's left in the window. */ len = MAX_STORED; /* maximum deflate stored block length */ - have = (s->bi_valid + 42) >> 3; /* number of header bytes */ + have = ((unsigned)s->bi_valid + 42) >> 3; /* bytes in header */ if (s->strm->avail_out < have) /* need room for header */ break; /* maximum stored block length that will fit in avail_out: */ have = s->strm->avail_out - have; - left = s->strstart - s->block_start; /* bytes left in window */ + left = (unsigned)(s->strstart - s->block_start); /* window bytes */ if (len > (ulg)left + s->strm->avail_in) len = left + s->strm->avail_in; /* limit len to the input */ if (len > have) @@ -1782,10 +1822,10 @@ local block_state deflate_stored(deflate_state *s, int flush) { _tr_stored_block(s, (char *)0, 0L, last); /* Replace the lengths in the dummy stored block with len. */ - s->pending_buf[s->pending - 4] = len; - s->pending_buf[s->pending - 3] = len >> 8; - s->pending_buf[s->pending - 2] = ~len; - s->pending_buf[s->pending - 1] = ~len >> 8; + s->pending_buf[s->pending - 4] = (Bytef)len; + s->pending_buf[s->pending - 3] = (Bytef)(len >> 8); + s->pending_buf[s->pending - 2] = (Bytef)~len; + s->pending_buf[s->pending - 1] = (Bytef)(~len >> 8); /* Write the stored block header bytes. */ flush_pending(s->strm); @@ -1856,8 +1896,10 @@ local block_state deflate_stored(deflate_state *s, int flush) { s->high_water = s->strstart; /* If the last block was written to next_out, then done. */ - if (last) + if (last) { + s->bi_used = 8; return finish_done; + } /* If flushing and all input has been consumed, then done. */ if (flush != Z_NO_FLUSH && flush != Z_FINISH && @@ -1865,7 +1907,7 @@ local block_state deflate_stored(deflate_state *s, int flush) { return block_done; /* Fill the window with any remaining input. */ - have = s->window_size - s->strstart; + have = (unsigned)(s->window_size - s->strstart); if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) { /* Slide the window down. */ s->block_start -= s->w_size; @@ -1892,11 +1934,11 @@ local block_state deflate_stored(deflate_state *s, int flush) { * have enough input for a worthy block, or if flushing and there is enough * room for the remaining input as a stored block in the pending buffer. */ - have = (s->bi_valid + 42) >> 3; /* number of header bytes */ + have = ((unsigned)s->bi_valid + 42) >> 3; /* bytes in header */ /* maximum stored block length that will fit in pending: */ - have = MIN(s->pending_buf_size - have, MAX_STORED); + have = (unsigned)MIN(s->pending_buf_size - have, MAX_STORED); min_block = MIN(have, s->w_size); - left = s->strstart - s->block_start; + left = (unsigned)(s->strstart - s->block_start); if (left >= min_block || ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH && s->strm->avail_in == 0 && left <= have)) { @@ -1909,6 +1951,8 @@ local block_state deflate_stored(deflate_state *s, int flush) { } /* We've done all we can with the available input and output. */ + if (last) + s->bi_used = 8; return last ? finish_started : need_more; } @@ -1975,7 +2019,7 @@ local block_state deflate_fast(deflate_state *s, int flush) { /* longest_match() sets match_start */ } if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->match_start, s->match_length); + check_match(s, s->strstart, s->match_start, (int)s->match_length); _tr_tally_dist(s, s->strstart - s->match_start, s->match_length - MIN_MATCH, bflush); @@ -2118,7 +2162,7 @@ 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, 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); @@ -2226,7 +2270,7 @@ local block_state deflate_rle(deflate_state *s, int flush) { /* Emit match if have run of MIN_MATCH or longer, else emit literal */ if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->strstart - 1, s->match_length); + check_match(s, s->strstart, s->strstart - 1, (int)s->match_length); _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); diff --git a/deps/zlib/deflate.h b/deps/zlib/deflate.h index b699f6b73b3a76..c55fd8f6a07b8c 100644 --- a/deps/zlib/deflate.h +++ b/deps/zlib/deflate.h @@ -1,5 +1,5 @@ /* deflate.h -- internal compression state - * Copyright (C) 1995-2024 Jean-loup Gailly + * Copyright (C) 1995-2026 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -281,6 +281,9 @@ typedef struct internal_state { /* Number of valid bits in bi_buf. All bits above the last valid bit * are always zero. */ + int bi_used; + /* Last number of used bits when going to a byte boundary. + */ ulg high_water; /* High water mark offset in window for initialized bytes -- bytes above @@ -301,6 +304,9 @@ typedef struct internal_state { struct qat_deflate *qat_s; #endif + int slid; + /* True if the hash table has been slid since it was cleared. */ + } FAR deflate_state; /* Output a byte on the stream. diff --git a/deps/zlib/doc/algorithm.txt b/deps/zlib/doc/algorithm.txt new file mode 100644 index 00000000000000..db3668de9ab61c --- /dev/null +++ b/deps/zlib/doc/algorithm.txt @@ -0,0 +1,209 @@ +1. Compression algorithm (deflate) + +The deflation algorithm used by gzip (also zip and zlib) is a variation of +LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in +the input data. The second occurrence of a string is replaced by a +pointer to the previous string, in the form of a pair (distance, +length). Distances are limited to 32K bytes, and lengths are limited +to 258 bytes. When a string does not occur anywhere in the previous +32K bytes, it is emitted as a sequence of literal bytes. (In this +description, `string' must be taken as an arbitrary sequence of bytes, +and is not restricted to printable characters.) + +Literals or match lengths are compressed with one Huffman tree, and +match distances are compressed with another tree. The trees are stored +in a compact form at the start of each block. The blocks can have any +size (except that the compressed data for one block must fit in +available memory). A block is terminated when deflate() determines that +it would be useful to start another block with fresh trees. (This is +somewhat similar to the behavior of LZW-based _compress_.) + +Duplicated strings are found using a hash table. All input strings of +length 3 are inserted in the hash table. A hash index is computed for +the next 3 bytes. If the hash chain for this index is not empty, all +strings in the chain are compared with the current input string, and +the longest match is selected. + +The hash chains are searched starting with the most recent strings, to +favor small distances and thus take advantage of the Huffman encoding. +The hash chains are singly linked. There are no deletions from the +hash chains, the algorithm simply discards matches that are too old. + +To avoid a worst-case situation, very long hash chains are arbitrarily +truncated at a certain length, determined by a runtime option (level +parameter of deflateInit). So deflate() does not always find the longest +possible match but generally finds a match which is long enough. + +deflate() also defers the selection of matches with a lazy evaluation +mechanism. After a match of length N has been found, deflate() searches for +a longer match at the next input byte. If a longer match is found, the +previous match is truncated to a length of one (thus producing a single +literal byte) and the process of lazy evaluation begins again. Otherwise, +the original match is kept, and the next match search is attempted only N +steps later. + +The lazy match evaluation is also subject to a runtime parameter. If +the current match is long enough, deflate() reduces the search for a longer +match, thus speeding up the whole process. If compression ratio is more +important than speed, deflate() attempts a complete second search even if +the first match is already long enough. + +The lazy match evaluation is not performed for the fastest compression +modes (level parameter 1 to 3). For these fast modes, new strings +are inserted in the hash table only when no match was found, or +when the match is not too long. This degrades the compression ratio +but saves time since there are both fewer insertions and fewer searches. + + +2. Decompression algorithm (inflate) + +2.1 Introduction + +The key question is how to represent a Huffman code (or any prefix code) so +that you can decode fast. The most important characteristic is that shorter +codes are much more common than longer codes, so pay attention to decoding the +short codes fast, and let the long codes take longer to decode. + +inflate() sets up a first level table that covers some number of bits of +input less than the length of longest code. It gets that many bits from the +stream, and looks it up in the table. The table will tell if the next +code is that many bits or less and how many, and if it is, it will tell +the value, else it will point to the next level table for which inflate() +grabs more bits and tries to decode a longer code. + +How many bits to make the first lookup is a tradeoff between the time it +takes to decode and the time it takes to build the table. If building the +table took no time (and if you had infinite memory), then there would only +be a first level table to cover all the way to the longest code. However, +building the table ends up taking a lot longer for more bits since short +codes are replicated many times in such a table. What inflate() does is +simply to make the number of bits in the first table a variable, and then +to set that variable for the maximum speed. + +For inflate, which has 286 possible codes for the literal/length tree, the size +of the first table is nine bits. Also the distance trees have 30 possible +values, and the size of the first table is six bits. Note that for each of +those cases, the table ended up one bit longer than the ``average'' code +length, i.e. the code length of an approximately flat code which would be a +little more than eight bits for 286 symbols and a little less than five bits +for 30 symbols. + + +2.2 More details on the inflate table lookup + +Ok, you want to know what this cleverly obfuscated inflate tree actually +looks like. You are correct that it's not a Huffman tree. It is simply a +lookup table for the first, let's say, nine bits of a Huffman symbol. The +symbol could be as short as one bit or as long as 15 bits. If a particular +symbol is shorter than nine bits, then that symbol's translation is duplicated +in all those entries that start with that symbol's bits. For example, if the +symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a +symbol is nine bits long, it appears in the table once. + +If the symbol is longer than nine bits, then that entry in the table points +to another similar table for the remaining bits. Again, there are duplicated +entries as needed. The idea is that most of the time the symbol will be short +and there will only be one table look up. (That's whole idea behind data +compression in the first place.) For the less frequent long symbols, there +will be two lookups. If you had a compression method with really long +symbols, you could have as many levels of lookups as is efficient. For +inflate, two is enough. + +So a table entry either points to another table (in which case nine bits in +the above example are gobbled), or it contains the translation for the symbol +and the number of bits to gobble. Then you start again with the next +ungobbled bit. + +You may wonder: why not just have one lookup table for how ever many bits the +longest symbol is? The reason is that if you do that, you end up spending +more time filling in duplicate symbol entries than you do actually decoding. +At least for deflate's output that generates new trees every several 10's of +kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code +would take too long if you're only decoding several thousand symbols. At the +other extreme, you could make a new table for every bit in the code. In fact, +that's essentially a Huffman tree. But then you spend too much time +traversing the tree while decoding, even for short symbols. + +So the number of bits for the first lookup table is a trade of the time to +fill out the table vs. the time spent looking at the second level and above of +the table. + +Here is an example, scaled down: + +The code being decoded, with 10 symbols, from 1 to 6 bits long: + +A: 0 +B: 10 +C: 1100 +D: 11010 +E: 11011 +F: 11100 +G: 11101 +H: 11110 +I: 111110 +J: 111111 + +Let's make the first table three bits long (eight entries): + +000: A,1 +001: A,1 +010: A,1 +011: A,1 +100: B,2 +101: B,2 +110: -> table X (gobble 3 bits) +111: -> table Y (gobble 3 bits) + +Each entry is what the bits decode as and how many bits that is, i.e. how +many bits to gobble. Or the entry points to another table, with the number of +bits to gobble implicit in the size of the table. + +Table X is two bits long since the longest code starting with 110 is five bits +long: + +00: C,1 +01: C,1 +10: D,2 +11: E,2 + +Table Y is three bits long since the longest code starting with 111 is six +bits long: + +000: F,2 +001: F,2 +010: G,2 +011: G,2 +100: H,2 +101: H,2 +110: I,3 +111: J,3 + +So what we have here are three tables with a total of 20 entries that had to +be constructed. That's compared to 64 entries for a single table. Or +compared to 16 entries for a Huffman tree (six two entry tables and one four +entry table). Assuming that the code ideally represents the probability of +the symbols, it takes on the average 1.25 lookups per symbol. That's compared +to one lookup for the single table, or 1.66 lookups per symbol for the +Huffman tree. + +There, I think that gives you a picture of what's going on. For inflate, the +meaning of a particular symbol is often more than just a letter. It can be a +byte (a "literal"), or it can be either a length or a distance which +indicates a base value and a number of bits to fetch after the code that is +added to the base value. Or it might be the special end-of-block code. The +data structures created in inftrees.c try to encode all that information +compactly in the tables. + + +Jean-loup Gailly Mark Adler +jloup@gzip.org madler@alumni.caltech.edu + + +References: + +[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data +Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3, +pp. 337-343. + +``DEFLATE Compressed Data Format Specification'' available in +https://datatracker.ietf.org/doc/html/rfc1951 diff --git a/deps/zlib/doc/crc-doc.1.0.pdf b/deps/zlib/doc/crc-doc.1.0.pdf new file mode 100644 index 00000000000000..d6942ecc09a3f8 Binary files /dev/null and b/deps/zlib/doc/crc-doc.1.0.pdf differ diff --git a/deps/zlib/doc/rfc1950.txt b/deps/zlib/doc/rfc1950.txt new file mode 100644 index 00000000000000..ce6428a0f2eed4 --- /dev/null +++ b/deps/zlib/doc/rfc1950.txt @@ -0,0 +1,619 @@ + + + + + + +Network Working Group P. Deutsch +Request for Comments: 1950 Aladdin Enterprises +Category: Informational J-L. Gailly + Info-ZIP + May 1996 + + + ZLIB Compressed Data Format Specification version 3.3 + +Status of This Memo + + This memo provides information for the Internet community. This memo + does not specify an Internet standard of any kind. Distribution of + this memo is unlimited. + +IESG Note: + + The IESG takes no position on the validity of any Intellectual + Property Rights statements contained in this document. + +Notices + + Copyright (c) 1996 L. Peter Deutsch and Jean-Loup Gailly + + Permission is granted to copy and distribute this document for any + purpose and without charge, including translations into other + languages and incorporation into compilations, provided that the + copyright notice and this notice are preserved, and that any + substantive changes or deletions from the original are clearly + marked. + + A pointer to the latest version of this and related documentation in + HTML format can be found at the URL + . + +Abstract + + This specification defines a lossless compressed data format. The + data can be produced or consumed, even for an arbitrarily long + sequentially presented input data stream, using only an a priori + bounded amount of intermediate storage. The format presently uses + the DEFLATE compression method but can be easily extended to use + other compression methods. It can be implemented readily in a manner + not covered by patents. This specification also defines the ADLER-32 + checksum (an extension and improvement of the Fletcher checksum), + used for detection of data corruption, and provides an algorithm for + computing it. + + + + +Deutsch & Gailly Informational [Page 1] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + +Table of Contents + + 1. Introduction ................................................... 2 + 1.1. Purpose ................................................... 2 + 1.2. Intended audience ......................................... 3 + 1.3. Scope ..................................................... 3 + 1.4. Compliance ................................................ 3 + 1.5. Definitions of terms and conventions used ................ 3 + 1.6. Changes from previous versions ............................ 3 + 2. Detailed specification ......................................... 3 + 2.1. Overall conventions ....................................... 3 + 2.2. Data format ............................................... 4 + 2.3. Compliance ................................................ 7 + 3. References ..................................................... 7 + 4. Source code .................................................... 8 + 5. Security Considerations ........................................ 8 + 6. Acknowledgements ............................................... 8 + 7. Authors' Addresses ............................................. 8 + 8. Appendix: Rationale ............................................ 9 + 9. Appendix: Sample code ..........................................10 + +1. Introduction + + 1.1. Purpose + + The purpose of this specification is to define a lossless + compressed data format that: + + * Is independent of CPU type, operating system, file system, + and character set, and hence can be used for interchange; + + * Can be produced or consumed, even for an arbitrarily long + sequentially presented input data stream, using only an a + priori bounded amount of intermediate storage, and hence can + be used in data communications or similar structures such as + Unix filters; + + * Can use a number of different compression methods; + + * Can be implemented readily in a manner not covered by + patents, and hence can be practiced freely. + + The data format defined by this specification does not attempt to + allow random access to compressed data. + + + + + + + +Deutsch & Gailly Informational [Page 2] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + 1.2. Intended audience + + This specification is intended for use by implementors of software + to compress data into zlib format and/or decompress data from zlib + format. + + The text of the specification assumes a basic background in + programming at the level of bits and other primitive data + representations. + + 1.3. Scope + + The specification specifies a compressed data format that can be + used for in-memory compression of a sequence of arbitrary bytes. + + 1.4. Compliance + + Unless otherwise indicated below, a compliant decompressor must be + able to accept and decompress any data set that conforms to all + the specifications presented here; a compliant compressor must + produce data sets that conform to all the specifications presented + here. + + 1.5. Definitions of terms and conventions used + + byte: 8 bits stored or transmitted as a unit (same as an octet). + (For this specification, a byte is exactly 8 bits, even on + machines which store a character on a number of bits different + from 8.) See below, for the numbering of bits within a byte. + + 1.6. Changes from previous versions + + Version 3.1 was the first public release of this specification. + In version 3.2, some terminology was changed and the Adler-32 + sample code was rewritten for clarity. In version 3.3, the + support for a preset dictionary was introduced, and the + specification was converted to RFC style. + +2. Detailed specification + + 2.1. Overall conventions + + In the diagrams below, a box like this: + + +---+ + | | <-- the vertical bars might be missing + +---+ + + + + +Deutsch & Gailly Informational [Page 3] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + represents one byte; a box like this: + + +==============+ + | | + +==============+ + + represents a variable number of bytes. + + Bytes stored within a computer do not have a "bit order", since + they are always treated as a unit. However, a byte considered as + an integer between 0 and 255 does have a most- and least- + significant bit, and since we write numbers with the most- + significant digit on the left, we also write bytes with the most- + significant bit on the left. In the diagrams below, we number the + bits of a byte so that bit 0 is the least-significant bit, i.e., + the bits are numbered: + + +--------+ + |76543210| + +--------+ + + Within a computer, a number may occupy multiple bytes. All + multi-byte numbers in the format described here are stored with + the MOST-significant byte first (at the lower memory address). + For example, the decimal number 520 is stored as: + + 0 1 + +--------+--------+ + |00000010|00001000| + +--------+--------+ + ^ ^ + | | + | + less significant byte = 8 + + more significant byte = 2 x 256 + + 2.2. Data format + + A zlib stream has the following structure: + + 0 1 + +---+---+ + |CMF|FLG| (more-->) + +---+---+ + + + + + + + + +Deutsch & Gailly Informational [Page 4] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + (if FLG.FDICT set) + + 0 1 2 3 + +---+---+---+---+ + | DICTID | (more-->) + +---+---+---+---+ + + +=====================+---+---+---+---+ + |...compressed data...| ADLER32 | + +=====================+---+---+---+---+ + + Any data which may appear after ADLER32 are not part of the zlib + stream. + + CMF (Compression Method and flags) + This byte is divided into a 4-bit compression method and a 4- + bit information field depending on the compression method. + + bits 0 to 3 CM Compression method + bits 4 to 7 CINFO Compression info + + CM (Compression method) + This identifies the compression method used in the file. CM = 8 + denotes the "deflate" compression method with a window size up + to 32K. This is the method used by gzip and PNG (see + references [1] and [2] in Chapter 3, below, for the reference + documents). CM = 15 is reserved. It might be used in a future + version of this specification to indicate the presence of an + extra field before the compressed data. + + CINFO (Compression info) + For CM = 8, CINFO is the base-2 logarithm of the LZ77 window + size, minus eight (CINFO=7 indicates a 32K window size). Values + of CINFO above 7 are not allowed in this version of the + specification. CINFO is not defined in this specification for + CM not equal to 8. + + FLG (FLaGs) + This flag byte is divided as follows: + + bits 0 to 4 FCHECK (check bits for CMF and FLG) + bit 5 FDICT (preset dictionary) + bits 6 to 7 FLEVEL (compression level) + + The FCHECK value must be such that CMF and FLG, when viewed as + a 16-bit unsigned integer stored in MSB order (CMF*256 + FLG), + is a multiple of 31. + + + + +Deutsch & Gailly Informational [Page 5] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + FDICT (Preset dictionary) + If FDICT is set, a DICT dictionary identifier is present + immediately after the FLG byte. The dictionary is a sequence of + bytes which are initially fed to the compressor without + producing any compressed output. DICT is the Adler-32 checksum + of this sequence of bytes (see the definition of ADLER32 + below). The decompressor can use this identifier to determine + which dictionary has been used by the compressor. + + FLEVEL (Compression level) + These flags are available for use by specific compression + methods. The "deflate" method (CM = 8) sets these flags as + follows: + + 0 - compressor used fastest algorithm + 1 - compressor used fast algorithm + 2 - compressor used default algorithm + 3 - compressor used maximum compression, slowest algorithm + + The information in FLEVEL is not needed for decompression; it + is there to indicate if recompression might be worthwhile. + + compressed data + For compression method 8, the compressed data is stored in the + deflate compressed data format as described in the document + "DEFLATE Compressed Data Format Specification" by L. Peter + Deutsch. (See reference [3] in Chapter 3, below) + + Other compressed data formats are not specified in this version + of the zlib specification. + + ADLER32 (Adler-32 checksum) + This contains a checksum value of the uncompressed data + (excluding any dictionary data) computed according to Adler-32 + algorithm. This algorithm is a 32-bit extension and improvement + of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073 + standard. See references [4] and [5] in Chapter 3, below) + + Adler-32 is composed of two sums accumulated per byte: s1 is + the sum of all bytes, s2 is the sum of all s1 values. Both sums + are done modulo 65521. s1 is initialized to 1, s2 to zero. The + Adler-32 checksum is stored as s2*65536 + s1 in most- + significant-byte first (network) order. + + + + + + + + +Deutsch & Gailly Informational [Page 6] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + 2.3. Compliance + + A compliant compressor must produce streams with correct CMF, FLG + and ADLER32, but need not support preset dictionaries. When the + zlib data format is used as part of another standard data format, + the compressor may use only preset dictionaries that are specified + by this other data format. If this other format does not use the + preset dictionary feature, the compressor must not set the FDICT + flag. + + A compliant decompressor must check CMF, FLG, and ADLER32, and + provide an error indication if any of these have incorrect values. + A compliant decompressor must give an error indication if CM is + not one of the values defined in this specification (only the + value 8 is permitted in this version), since another value could + indicate the presence of new features that would cause subsequent + data to be interpreted incorrectly. A compliant decompressor must + give an error indication if FDICT is set and DICTID is not the + identifier of a known preset dictionary. A decompressor may + ignore FLEVEL and still be compliant. When the zlib data format + is being used as a part of another standard format, a compliant + decompressor must support all the preset dictionaries specified by + the other format. When the other format does not use the preset + dictionary feature, a compliant decompressor must reject any + stream in which the FDICT flag is set. + +3. References + + [1] Deutsch, L.P.,"GZIP Compressed Data Format Specification", + available in ftp://ftp.uu.net/pub/archiving/zip/doc/ + + [2] Thomas Boutell, "PNG (Portable Network Graphics) specification", + available in ftp://ftp.uu.net/graphics/png/documents/ + + [3] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification", + available in ftp://ftp.uu.net/pub/archiving/zip/doc/ + + [4] Fletcher, J. G., "An Arithmetic Checksum for Serial + Transmissions," IEEE Transactions on Communications, Vol. COM-30, + No. 1, January 1982, pp. 247-252. + + [5] ITU-T Recommendation X.224, Annex D, "Checksum Algorithms," + November, 1993, pp. 144, 145. (Available from + gopher://info.itu.ch). ITU-T X.244 is also the same as ISO 8073. + + + + + + + +Deutsch & Gailly Informational [Page 7] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + +4. Source code + + Source code for a C language implementation of a "zlib" compliant + library is available at ftp://ftp.uu.net/pub/archiving/zip/zlib/. + +5. Security Considerations + + A decoder that fails to check the ADLER32 checksum value may be + subject to undetected data corruption. + +6. Acknowledgements + + Trademarks cited in this document are the property of their + respective owners. + + Jean-Loup Gailly and Mark Adler designed the zlib format and wrote + the related software described in this specification. Glenn + Randers-Pehrson converted this document to RFC and HTML format. + +7. Authors' Addresses + + L. Peter Deutsch + Aladdin Enterprises + 203 Santa Margarita Ave. + Menlo Park, CA 94025 + + Phone: (415) 322-0103 (AM only) + FAX: (415) 322-1734 + EMail: + + + Jean-Loup Gailly + + EMail: + + Questions about the technical content of this specification can be + sent by email to + + Jean-Loup Gailly and + Mark Adler + + Editorial comments on this specification can be sent by email to + + L. Peter Deutsch and + Glenn Randers-Pehrson + + + + + + +Deutsch & Gailly Informational [Page 8] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + +8. Appendix: Rationale + + 8.1. Preset dictionaries + + A preset dictionary is specially useful to compress short input + sequences. The compressor can take advantage of the dictionary + context to encode the input in a more compact manner. The + decompressor can be initialized with the appropriate context by + virtually decompressing a compressed version of the dictionary + without producing any output. However for certain compression + algorithms such as the deflate algorithm this operation can be + achieved without actually performing any decompression. + + The compressor and the decompressor must use exactly the same + dictionary. The dictionary may be fixed or may be chosen among a + certain number of predefined dictionaries, according to the kind + of input data. The decompressor can determine which dictionary has + been chosen by the compressor by checking the dictionary + identifier. This document does not specify the contents of + predefined dictionaries, since the optimal dictionaries are + application specific. Standard data formats using this feature of + the zlib specification must precisely define the allowed + dictionaries. + + 8.2. The Adler-32 algorithm + + The Adler-32 algorithm is much faster than the CRC32 algorithm yet + still provides an extremely low probability of undetected errors. + + The modulo on unsigned long accumulators can be delayed for 5552 + bytes, so the modulo operation time is negligible. If the bytes + are a, b, c, the second sum is 3a + 2b + c + 3, and so is position + and order sensitive, unlike the first sum, which is just a + checksum. That 65521 is prime is important to avoid a possible + large class of two-byte errors that leave the check unchanged. + (The Fletcher checksum uses 255, which is not prime and which also + makes the Fletcher check insensitive to single byte changes 0 <-> + 255.) + + The sum s1 is initialized to 1 instead of zero to make the length + of the sequence part of s2, so that the length does not have to be + checked separately. (Any sequence of zeroes has a Fletcher + checksum of zero.) + + + + + + + + +Deutsch & Gailly Informational [Page 9] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + +9. Appendix: Sample code + + The following C code computes the Adler-32 checksum of a data buffer. + It is written for clarity, not for speed. The sample code is in the + ANSI C programming language. Non C users may find it easier to read + with these hints: + + & Bitwise AND operator. + >> Bitwise right shift operator. When applied to an + unsigned quantity, as here, right shift inserts zero bit(s) + at the left. + << Bitwise left shift operator. Left shift inserts zero + bit(s) at the right. + ++ "n++" increments the variable n. + % modulo operator: a % b is the remainder of a divided by b. + + #define BASE 65521 /* largest prime smaller than 65536 */ + + /* + Update a running Adler-32 checksum with the bytes buf[0..len-1] + and return the updated checksum. The Adler-32 checksum should be + initialized to 1. + + Usage example: + + unsigned long adler = 1L; + + while (read_buffer(buffer, length) != EOF) { + adler = update_adler32(adler, buffer, length); + } + if (adler != original_adler) error(); + */ + unsigned long update_adler32(unsigned long adler, + unsigned char *buf, int len) + { + unsigned long s1 = adler & 0xffff; + unsigned long s2 = (adler >> 16) & 0xffff; + int n; + + for (n = 0; n < len; n++) { + s1 = (s1 + buf[n]) % BASE; + s2 = (s2 + s1) % BASE; + } + return (s2 << 16) + s1; + } + + /* Return the adler32 of the bytes buf[0..len-1] */ + + + + +Deutsch & Gailly Informational [Page 10] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + unsigned long adler32(unsigned char *buf, int len) + { + return update_adler32(1L, buf, len); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Deutsch & Gailly Informational [Page 11] + diff --git a/deps/zlib/doc/rfc1951.txt b/deps/zlib/doc/rfc1951.txt new file mode 100644 index 00000000000000..403c8c722ff24c --- /dev/null +++ b/deps/zlib/doc/rfc1951.txt @@ -0,0 +1,955 @@ + + + + + + +Network Working Group P. Deutsch +Request for Comments: 1951 Aladdin Enterprises +Category: Informational May 1996 + + + DEFLATE Compressed Data Format Specification version 1.3 + +Status of This Memo + + This memo provides information for the Internet community. This memo + does not specify an Internet standard of any kind. Distribution of + this memo is unlimited. + +IESG Note: + + The IESG takes no position on the validity of any Intellectual + Property Rights statements contained in this document. + +Notices + + Copyright (c) 1996 L. Peter Deutsch + + Permission is granted to copy and distribute this document for any + purpose and without charge, including translations into other + languages and incorporation into compilations, provided that the + copyright notice and this notice are preserved, and that any + substantive changes or deletions from the original are clearly + marked. + + A pointer to the latest version of this and related documentation in + HTML format can be found at the URL + . + +Abstract + + This specification defines a lossless compressed data format that + compresses data using a combination of the LZ77 algorithm and Huffman + coding, with efficiency comparable to the best currently available + general-purpose compression methods. The data can be produced or + consumed, even for an arbitrarily long sequentially presented input + data stream, using only an a priori bounded amount of intermediate + storage. The format can be implemented readily in a manner not + covered by patents. + + + + + + + + +Deutsch Informational [Page 1] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + +Table of Contents + + 1. Introduction ................................................... 2 + 1.1. Purpose ................................................... 2 + 1.2. Intended audience ......................................... 3 + 1.3. Scope ..................................................... 3 + 1.4. Compliance ................................................ 3 + 1.5. Definitions of terms and conventions used ................ 3 + 1.6. Changes from previous versions ............................ 4 + 2. Compressed representation overview ............................. 4 + 3. Detailed specification ......................................... 5 + 3.1. Overall conventions ....................................... 5 + 3.1.1. Packing into bytes .................................. 5 + 3.2. Compressed block format ................................... 6 + 3.2.1. Synopsis of prefix and Huffman coding ............... 6 + 3.2.2. Use of Huffman coding in the "deflate" format ....... 7 + 3.2.3. Details of block format ............................. 9 + 3.2.4. Non-compressed blocks (BTYPE=00) ................... 11 + 3.2.5. Compressed blocks (length and distance codes) ...... 11 + 3.2.6. Compression with fixed Huffman codes (BTYPE=01) .... 12 + 3.2.7. Compression with dynamic Huffman codes (BTYPE=10) .. 13 + 3.3. Compliance ............................................... 14 + 4. Compression algorithm details ................................. 14 + 5. References .................................................... 16 + 6. Security Considerations ....................................... 16 + 7. Source code ................................................... 16 + 8. Acknowledgements .............................................. 16 + 9. Author's Address .............................................. 17 + +1. Introduction + + 1.1. Purpose + + The purpose of this specification is to define a lossless + compressed data format that: + * Is independent of CPU type, operating system, file system, + and character set, and hence can be used for interchange; + * Can be produced or consumed, even for an arbitrarily long + sequentially presented input data stream, using only an a + priori bounded amount of intermediate storage, and hence + can be used in data communications or similar structures + such as Unix filters; + * Compresses data with efficiency comparable to the best + currently available general-purpose compression methods, + and in particular considerably better than the "compress" + program; + * Can be implemented readily in a manner not covered by + patents, and hence can be practiced freely; + + + +Deutsch Informational [Page 2] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + * Is compatible with the file format produced by the current + widely used gzip utility, in that conforming decompressors + will be able to read data produced by the existing gzip + compressor. + + The data format defined by this specification does not attempt to: + + * Allow random access to compressed data; + * Compress specialized data (e.g., raster graphics) as well + as the best currently available specialized algorithms. + + A simple counting argument shows that no lossless compression + algorithm can compress every possible input data set. For the + format defined here, the worst case expansion is 5 bytes per 32K- + byte block, i.e., a size increase of 0.015% for large data sets. + English text usually compresses by a factor of 2.5 to 3; + executable files usually compress somewhat less; graphical data + such as raster images may compress much more. + + 1.2. Intended audience + + This specification is intended for use by implementors of software + to compress data into "deflate" format and/or decompress data from + "deflate" format. + + The text of the specification assumes a basic background in + programming at the level of bits and other primitive data + representations. Familiarity with the technique of Huffman coding + is helpful but not required. + + 1.3. Scope + + The specification specifies a method for representing a sequence + of bytes as a (usually shorter) sequence of bits, and a method for + packing the latter bit sequence into bytes. + + 1.4. Compliance + + Unless otherwise indicated below, a compliant decompressor must be + able to accept and decompress any data set that conforms to all + the specifications presented here; a compliant compressor must + produce data sets that conform to all the specifications presented + here. + + 1.5. Definitions of terms and conventions used + + Byte: 8 bits stored or transmitted as a unit (same as an octet). + For this specification, a byte is exactly 8 bits, even on machines + + + +Deutsch Informational [Page 3] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + which store a character on a number of bits different from eight. + See below, for the numbering of bits within a byte. + + String: a sequence of arbitrary bytes. + + 1.6. Changes from previous versions + + There have been no technical changes to the deflate format since + version 1.1 of this specification. In version 1.2, some + terminology was changed. Version 1.3 is a conversion of the + specification to RFC style. + +2. Compressed representation overview + + A compressed data set consists of a series of blocks, corresponding + to successive blocks of input data. The block sizes are arbitrary, + except that non-compressible blocks are limited to 65,535 bytes. + + Each block is compressed using a combination of the LZ77 algorithm + and Huffman coding. The Huffman trees for each block are independent + of those for previous or subsequent blocks; the LZ77 algorithm may + use a reference to a duplicated string occurring in a previous block, + up to 32K input bytes before. + + Each block consists of two parts: a pair of Huffman code trees that + describe the representation of the compressed data part, and a + compressed data part. (The Huffman trees themselves are compressed + using Huffman encoding.) The compressed data consists of a series of + elements of two types: literal bytes (of strings that have not been + detected as duplicated within the previous 32K input bytes), and + pointers to duplicated strings, where a pointer is represented as a + pair . The representation used in the + "deflate" format limits distances to 32K bytes and lengths to 258 + bytes, but does not limit the size of a block, except for + uncompressible blocks, which are limited as noted above. + + Each type of value (literals, distances, and lengths) in the + compressed data is represented using a Huffman code, using one code + tree for literals and lengths and a separate code tree for distances. + The code trees for each block appear in a compact form just before + the compressed data for that block. + + + + + + + + + + +Deutsch Informational [Page 4] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + +3. Detailed specification + + 3.1. Overall conventions In the diagrams below, a box like this: + + +---+ + | | <-- the vertical bars might be missing + +---+ + + represents one byte; a box like this: + + +==============+ + | | + +==============+ + + represents a variable number of bytes. + + Bytes stored within a computer do not have a "bit order", since + they are always treated as a unit. However, a byte considered as + an integer between 0 and 255 does have a most- and least- + significant bit, and since we write numbers with the most- + significant digit on the left, we also write bytes with the most- + significant bit on the left. In the diagrams below, we number the + bits of a byte so that bit 0 is the least-significant bit, i.e., + the bits are numbered: + + +--------+ + |76543210| + +--------+ + + Within a computer, a number may occupy multiple bytes. All + multi-byte numbers in the format described here are stored with + the least-significant byte first (at the lower memory address). + For example, the decimal number 520 is stored as: + + 0 1 + +--------+--------+ + |00001000|00000010| + +--------+--------+ + ^ ^ + | | + | + more significant byte = 2 x 256 + + less significant byte = 8 + + 3.1.1. Packing into bytes + + This document does not address the issue of the order in which + bits of a byte are transmitted on a bit-sequential medium, + since the final data format described here is byte- rather than + + + +Deutsch Informational [Page 5] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + bit-oriented. However, we describe the compressed block format + in below, as a sequence of data elements of various bit + lengths, not a sequence of bytes. We must therefore specify + how to pack these data elements into bytes to form the final + compressed byte sequence: + + * Data elements are packed into bytes in order of + increasing bit number within the byte, i.e., starting + with the least-significant bit of the byte. + * Data elements other than Huffman codes are packed + starting with the least-significant bit of the data + element. + * Huffman codes are packed starting with the most- + significant bit of the code. + + In other words, if one were to print out the compressed data as + a sequence of bytes, starting with the first byte at the + *right* margin and proceeding to the *left*, with the most- + significant bit of each byte on the left as usual, one would be + able to parse the result from right to left, with fixed-width + elements in the correct MSB-to-LSB order and Huffman codes in + bit-reversed order (i.e., with the first bit of the code in the + relative LSB position). + + 3.2. Compressed block format + + 3.2.1. Synopsis of prefix and Huffman coding + + Prefix coding represents symbols from an a priori known + alphabet by bit sequences (codes), one code for each symbol, in + a manner such that different symbols may be represented by bit + sequences of different lengths, but a parser can always parse + an encoded string unambiguously symbol-by-symbol. + + We define a prefix code in terms of a binary tree in which the + two edges descending from each non-leaf node are labeled 0 and + 1 and in which the leaf nodes correspond one-for-one with (are + labeled with) the symbols of the alphabet; then the code for a + symbol is the sequence of 0's and 1's on the edges leading from + the root to the leaf labeled with that symbol. For example: + + + + + + + + + + + +Deutsch Informational [Page 6] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + /\ Symbol Code + 0 1 ------ ---- + / \ A 00 + /\ B B 1 + 0 1 C 011 + / \ D 010 + A /\ + 0 1 + / \ + D C + + A parser can decode the next symbol from an encoded input + stream by walking down the tree from the root, at each step + choosing the edge corresponding to the next input bit. + + Given an alphabet with known symbol frequencies, the Huffman + algorithm allows the construction of an optimal prefix code + (one which represents strings with those symbol frequencies + using the fewest bits of any possible prefix codes for that + alphabet). Such a code is called a Huffman code. (See + reference [1] in Chapter 5, references for additional + information on Huffman codes.) + + Note that in the "deflate" format, the Huffman codes for the + various alphabets must not exceed certain maximum code lengths. + This constraint complicates the algorithm for computing code + lengths from symbol frequencies. Again, see Chapter 5, + references for details. + + 3.2.2. Use of Huffman coding in the "deflate" format + + The Huffman codes used for each alphabet in the "deflate" + format have two additional rules: + + * All codes of a given bit length have lexicographically + consecutive values, in the same order as the symbols + they represent; + + * Shorter codes lexicographically precede longer codes. + + + + + + + + + + + + +Deutsch Informational [Page 7] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + We could recode the example above to follow this rule as + follows, assuming that the order of the alphabet is ABCD: + + Symbol Code + ------ ---- + A 10 + B 0 + C 110 + D 111 + + I.e., 0 precedes 10 which precedes 11x, and 110 and 111 are + lexicographically consecutive. + + Given this rule, we can define the Huffman code for an alphabet + just by giving the bit lengths of the codes for each symbol of + the alphabet in order; this is sufficient to determine the + actual codes. In our example, the code is completely defined + by the sequence of bit lengths (2, 1, 3, 3). The following + algorithm generates the codes as integers, intended to be read + from most- to least-significant bit. The code lengths are + initially in tree[I].Len; the codes are produced in + tree[I].Code. + + 1) Count the number of codes for each code length. Let + bl_count[N] be the number of codes of length N, N >= 1. + + 2) Find the numerical value of the smallest code for each + code length: + + code = 0; + bl_count[0] = 0; + for (bits = 1; bits <= MAX_BITS; bits++) { + code = (code + bl_count[bits-1]) << 1; + next_code[bits] = code; + } + + 3) Assign numerical values to all codes, using consecutive + values for all codes of the same length with the base + values determined at step 2. Codes that are never used + (which have a bit length of zero) must not be assigned a + value. + + for (n = 0; n <= max_code; n++) { + len = tree[n].Len; + if (len != 0) { + tree[n].Code = next_code[len]; + next_code[len]++; + } + + + +Deutsch Informational [Page 8] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + } + + Example: + + Consider the alphabet ABCDEFGH, with bit lengths (3, 3, 3, 3, + 3, 2, 4, 4). After step 1, we have: + + N bl_count[N] + - ----------- + 2 1 + 3 5 + 4 2 + + Step 2 computes the following next_code values: + + N next_code[N] + - ------------ + 1 0 + 2 0 + 3 2 + 4 14 + + Step 3 produces the following code values: + + Symbol Length Code + ------ ------ ---- + A 3 010 + B 3 011 + C 3 100 + D 3 101 + E 3 110 + F 2 00 + G 4 1110 + H 4 1111 + + 3.2.3. Details of block format + + Each block of compressed data begins with 3 header bits + containing the following data: + + first bit BFINAL + next 2 bits BTYPE + + Note that the header bits do not necessarily begin on a byte + boundary, since a block does not necessarily occupy an integral + number of bytes. + + + + + +Deutsch Informational [Page 9] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + BFINAL is set if and only if this is the last block of the data + set. + + BTYPE specifies how the data are compressed, as follows: + + 00 - no compression + 01 - compressed with fixed Huffman codes + 10 - compressed with dynamic Huffman codes + 11 - reserved (error) + + The only difference between the two compressed cases is how the + Huffman codes for the literal/length and distance alphabets are + defined. + + In all cases, the decoding algorithm for the actual data is as + follows: + + do + read block header from input stream. + if stored with no compression + skip any remaining bits in current partially + processed byte + read LEN and NLEN (see next section) + copy LEN bytes of data to output + otherwise + if compressed with dynamic Huffman codes + read representation of code trees (see + subsection below) + loop (until end of block code recognized) + decode literal/length value from input stream + if value < 256 + copy value (literal byte) to output stream + otherwise + if value = end of block (256) + break from loop + otherwise (value = 257..285) + decode distance from input stream + + move backwards distance bytes in the output + stream, and copy length bytes from this + position to the output stream. + end loop + while not last block + + Note that a duplicated string reference may refer to a string + in a previous block; i.e., the backward distance may cross one + or more block boundaries. However a distance cannot refer past + the beginning of the output stream. (An application using a + + + +Deutsch Informational [Page 10] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + preset dictionary might discard part of the output stream; a + distance can refer to that part of the output stream anyway) + Note also that the referenced string may overlap the current + position; for example, if the last 2 bytes decoded have values + X and Y, a string reference with + adds X,Y,X,Y,X to the output stream. + + We now specify each compression method in turn. + + 3.2.4. Non-compressed blocks (BTYPE=00) + + Any bits of input up to the next byte boundary are ignored. + The rest of the block consists of the following information: + + 0 1 2 3 4... + +---+---+---+---+================================+ + | LEN | NLEN |... LEN bytes of literal data...| + +---+---+---+---+================================+ + + LEN is the number of data bytes in the block. NLEN is the + one's complement of LEN. + + 3.2.5. Compressed blocks (length and distance codes) + + As noted above, encoded data blocks in the "deflate" format + consist of sequences of symbols drawn from three conceptually + distinct alphabets: either literal bytes, from the alphabet of + byte values (0..255), or pairs, + where the length is drawn from (3..258) and the distance is + drawn from (1..32,768). In fact, the literal and length + alphabets are merged into a single alphabet (0..285), where + values 0..255 represent literal bytes, the value 256 indicates + end-of-block, and values 257..285 represent length codes + (possibly in conjunction with extra bits following the symbol + code) as follows: + + + + + + + + + + + + + + + + +Deutsch Informational [Page 11] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + Extra Extra Extra + Code Bits Length(s) Code Bits Lengths Code Bits Length(s) + ---- ---- ------ ---- ---- ------- ---- ---- ------- + 257 0 3 267 1 15,16 277 4 67-82 + 258 0 4 268 1 17,18 278 4 83-98 + 259 0 5 269 2 19-22 279 4 99-114 + 260 0 6 270 2 23-26 280 4 115-130 + 261 0 7 271 2 27-30 281 5 131-162 + 262 0 8 272 2 31-34 282 5 163-194 + 263 0 9 273 3 35-42 283 5 195-226 + 264 0 10 274 3 43-50 284 5 227-257 + 265 1 11,12 275 3 51-58 285 0 258 + 266 1 13,14 276 3 59-66 + + The extra bits should be interpreted as a machine integer + stored with the most-significant bit first, e.g., bits 1110 + represent the value 14. + + Extra Extra Extra + Code Bits Dist Code Bits Dist Code Bits Distance + ---- ---- ---- ---- ---- ------ ---- ---- -------- + 0 0 1 10 4 33-48 20 9 1025-1536 + 1 0 2 11 4 49-64 21 9 1537-2048 + 2 0 3 12 5 65-96 22 10 2049-3072 + 3 0 4 13 5 97-128 23 10 3073-4096 + 4 1 5,6 14 6 129-192 24 11 4097-6144 + 5 1 7,8 15 6 193-256 25 11 6145-8192 + 6 2 9-12 16 7 257-384 26 12 8193-12288 + 7 2 13-16 17 7 385-512 27 12 12289-16384 + 8 3 17-24 18 8 513-768 28 13 16385-24576 + 9 3 25-32 19 8 769-1024 29 13 24577-32768 + + 3.2.6. Compression with fixed Huffman codes (BTYPE=01) + + The Huffman codes for the two alphabets are fixed, and are not + represented explicitly in the data. The Huffman code lengths + for the literal/length alphabet are: + + Lit Value Bits Codes + --------- ---- ----- + 0 - 143 8 00110000 through + 10111111 + 144 - 255 9 110010000 through + 111111111 + 256 - 279 7 0000000 through + 0010111 + 280 - 287 8 11000000 through + 11000111 + + + +Deutsch Informational [Page 12] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + The code lengths are sufficient to generate the actual codes, + as described above; we show the codes in the table for added + clarity. Literal/length values 286-287 will never actually + occur in the compressed data, but participate in the code + construction. + + Distance codes 0-31 are represented by (fixed-length) 5-bit + codes, with possible additional bits as shown in the table + shown in Paragraph 3.2.5, above. Note that distance codes 30- + 31 will never actually occur in the compressed data. + + 3.2.7. Compression with dynamic Huffman codes (BTYPE=10) + + The Huffman codes for the two alphabets appear in the block + immediately after the header bits and before the actual + compressed data, first the literal/length code and then the + distance code. Each code is defined by a sequence of code + lengths, as discussed in Paragraph 3.2.2, above. For even + greater compactness, the code length sequences themselves are + compressed using a Huffman code. The alphabet for code lengths + is as follows: + + 0 - 15: Represent code lengths of 0 - 15 + 16: Copy the previous code length 3 - 6 times. + The next 2 bits indicate repeat length + (0 = 3, ... , 3 = 6) + Example: Codes 8, 16 (+2 bits 11), + 16 (+2 bits 10) will expand to + 12 code lengths of 8 (1 + 6 + 5) + 17: Repeat a code length of 0 for 3 - 10 times. + (3 bits of length) + 18: Repeat a code length of 0 for 11 - 138 times + (7 bits of length) + + A code length of 0 indicates that the corresponding symbol in + the literal/length or distance alphabet will not occur in the + block, and should not participate in the Huffman code + construction algorithm given earlier. If only one distance + code is used, it is encoded using one bit, not zero bits; in + this case there is a single code length of one, with one unused + code. One distance code of zero bits means that there are no + distance codes used at all (the data is all literals). + + We can now define the format of the block: + + 5 Bits: HLIT, # of Literal/Length codes - 257 (257 - 286) + 5 Bits: HDIST, # of Distance codes - 1 (1 - 32) + 4 Bits: HCLEN, # of Code Length codes - 4 (4 - 19) + + + +Deutsch Informational [Page 13] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + (HCLEN + 4) x 3 bits: code lengths for the code length + alphabet given just above, in the order: 16, 17, 18, + 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 + + These code lengths are interpreted as 3-bit integers + (0-7); as above, a code length of 0 means the + corresponding symbol (literal/length or distance code + length) is not used. + + HLIT + 257 code lengths for the literal/length alphabet, + encoded using the code length Huffman code + + HDIST + 1 code lengths for the distance alphabet, + encoded using the code length Huffman code + + The actual compressed data of the block, + encoded using the literal/length and distance Huffman + codes + + The literal/length symbol 256 (end of data), + encoded using the literal/length Huffman code + + The code length repeat codes can cross from HLIT + 257 to the + HDIST + 1 code lengths. In other words, all code lengths form + a single sequence of HLIT + HDIST + 258 values. + + 3.3. Compliance + + A compressor may limit further the ranges of values specified in + the previous section and still be compliant; for example, it may + limit the range of backward pointers to some value smaller than + 32K. Similarly, a compressor may limit the size of blocks so that + a compressible block fits in memory. + + A compliant decompressor must accept the full range of possible + values defined in the previous section, and must accept blocks of + arbitrary size. + +4. Compression algorithm details + + While it is the intent of this document to define the "deflate" + compressed data format without reference to any particular + compression algorithm, the format is related to the compressed + formats produced by LZ77 (Lempel-Ziv 1977, see reference [2] below); + since many variations of LZ77 are patented, it is strongly + recommended that the implementor of a compressor follow the general + algorithm presented here, which is known not to be patented per se. + The material in this section is not part of the definition of the + + + +Deutsch Informational [Page 14] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + specification per se, and a compressor need not follow it in order to + be compliant. + + The compressor terminates a block when it determines that starting a + new block with fresh trees would be useful, or when the block size + fills up the compressor's block buffer. + + The compressor uses a chained hash table to find duplicated strings, + using a hash function that operates on 3-byte sequences. At any + given point during compression, let XYZ be the next 3 input bytes to + be examined (not necessarily all different, of course). First, the + compressor examines the hash chain for XYZ. If the chain is empty, + the compressor simply writes out X as a literal byte and advances one + byte in the input. If the hash chain is not empty, indicating that + the sequence XYZ (or, if we are unlucky, some other 3 bytes with the + same hash function value) has occurred recently, the compressor + compares all strings on the XYZ hash chain with the actual input data + sequence starting at the current point, and selects the longest + match. + + The compressor searches the hash chains starting with the most recent + strings, to favor small distances and thus take advantage of the + Huffman encoding. The hash chains are singly linked. There are no + deletions from the hash chains; the algorithm simply discards matches + that are too old. To avoid a worst-case situation, very long hash + chains are arbitrarily truncated at a certain length, determined by a + run-time parameter. + + To improve overall compression, the compressor optionally defers the + selection of matches ("lazy matching"): after a match of length N has + been found, the compressor searches for a longer match starting at + the next input byte. If it finds a longer match, it truncates the + previous match to a length of one (thus producing a single literal + byte) and then emits the longer match. Otherwise, it emits the + original match, and, as described above, advances N bytes before + continuing. + + Run-time parameters also control this "lazy match" procedure. If + compression ratio is most important, the compressor attempts a + complete second search regardless of the length of the first match. + In the normal case, if the current match is "long enough", the + compressor reduces the search for a longer match, thus speeding up + the process. If speed is most important, the compressor inserts new + strings in the hash table only when no match was found, or when the + match is not "too long". This degrades the compression ratio but + saves time since there are both fewer insertions and fewer searches. + + + + + +Deutsch Informational [Page 15] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + +5. References + + [1] Huffman, D. A., "A Method for the Construction of Minimum + Redundancy Codes", Proceedings of the Institute of Radio + Engineers, September 1952, Volume 40, Number 9, pp. 1098-1101. + + [2] Ziv J., Lempel A., "A Universal Algorithm for Sequential Data + Compression", IEEE Transactions on Information Theory, Vol. 23, + No. 3, pp. 337-343. + + [3] Gailly, J.-L., and Adler, M., ZLIB documentation and sources, + available in ftp://ftp.uu.net/pub/archiving/zip/doc/ + + [4] Gailly, J.-L., and Adler, M., GZIP documentation and sources, + available as gzip-*.tar in ftp://prep.ai.mit.edu/pub/gnu/ + + [5] Schwartz, E. S., and Kallick, B. "Generating a canonical prefix + encoding." Comm. ACM, 7,3 (Mar. 1964), pp. 166-169. + + [6] Hirschberg and Lelewer, "Efficient decoding of prefix codes," + Comm. ACM, 33,4, April 1990, pp. 449-459. + +6. Security Considerations + + Any data compression method involves the reduction of redundancy in + the data. Consequently, any corruption of the data is likely to have + severe effects and be difficult to correct. Uncompressed text, on + the other hand, will probably still be readable despite the presence + of some corrupted bytes. + + It is recommended that systems using this data format provide some + means of validating the integrity of the compressed data. See + reference [3], for example. + +7. Source code + + Source code for a C language implementation of a "deflate" compliant + compressor and decompressor is available within the zlib package at + ftp://ftp.uu.net/pub/archiving/zip/zlib/. + +8. Acknowledgements + + Trademarks cited in this document are the property of their + respective owners. + + Phil Katz designed the deflate format. Jean-Loup Gailly and Mark + Adler wrote the related software described in this specification. + Glenn Randers-Pehrson converted this document to RFC and HTML format. + + + +Deutsch Informational [Page 16] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + +9. Author's Address + + L. Peter Deutsch + Aladdin Enterprises + 203 Santa Margarita Ave. + Menlo Park, CA 94025 + + Phone: (415) 322-0103 (AM only) + FAX: (415) 322-1734 + EMail: + + Questions about the technical content of this specification can be + sent by email to: + + Jean-Loup Gailly and + Mark Adler + + Editorial comments on this specification can be sent by email to: + + L. Peter Deutsch and + Glenn Randers-Pehrson + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Deutsch Informational [Page 17] + diff --git a/deps/zlib/doc/rfc1952.txt b/deps/zlib/doc/rfc1952.txt new file mode 100644 index 00000000000000..a8e51b4567fd49 --- /dev/null +++ b/deps/zlib/doc/rfc1952.txt @@ -0,0 +1,675 @@ + + + + + + +Network Working Group P. Deutsch +Request for Comments: 1952 Aladdin Enterprises +Category: Informational May 1996 + + + GZIP file format specification version 4.3 + +Status of This Memo + + This memo provides information for the Internet community. This memo + does not specify an Internet standard of any kind. Distribution of + this memo is unlimited. + +IESG Note: + + The IESG takes no position on the validity of any Intellectual + Property Rights statements contained in this document. + +Notices + + Copyright (c) 1996 L. Peter Deutsch + + Permission is granted to copy and distribute this document for any + purpose and without charge, including translations into other + languages and incorporation into compilations, provided that the + copyright notice and this notice are preserved, and that any + substantive changes or deletions from the original are clearly + marked. + + A pointer to the latest version of this and related documentation in + HTML format can be found at the URL + . + +Abstract + + This specification defines a lossless compressed data format that is + compatible with the widely used GZIP utility. The format includes a + cyclic redundancy check value for detecting data corruption. The + format presently uses the DEFLATE method of compression but can be + easily extended to use other compression methods. The format can be + implemented readily in a manner not covered by patents. + + + + + + + + + + +Deutsch Informational [Page 1] + +RFC 1952 GZIP File Format Specification May 1996 + + +Table of Contents + + 1. Introduction ................................................... 2 + 1.1. Purpose ................................................... 2 + 1.2. Intended audience ......................................... 3 + 1.3. Scope ..................................................... 3 + 1.4. Compliance ................................................ 3 + 1.5. Definitions of terms and conventions used ................. 3 + 1.6. Changes from previous versions ............................ 3 + 2. Detailed specification ......................................... 4 + 2.1. Overall conventions ....................................... 4 + 2.2. File format ............................................... 5 + 2.3. Member format ............................................. 5 + 2.3.1. Member header and trailer ........................... 6 + 2.3.1.1. Extra field ................................... 8 + 2.3.1.2. Compliance .................................... 9 + 3. References .................................................. 9 + 4. Security Considerations .................................... 10 + 5. Acknowledgements ........................................... 10 + 6. Author's Address ........................................... 10 + 7. Appendix: Jean-Loup Gailly's gzip utility .................. 11 + 8. Appendix: Sample CRC Code .................................. 11 + +1. Introduction + + 1.1. Purpose + + The purpose of this specification is to define a lossless + compressed data format that: + + * Is independent of CPU type, operating system, file system, + and character set, and hence can be used for interchange; + * Can compress or decompress a data stream (as opposed to a + randomly accessible file) to produce another data stream, + using only an a priori bounded amount of intermediate + storage, and hence can be used in data communications or + similar structures such as Unix filters; + * Compresses data with efficiency comparable to the best + currently available general-purpose compression methods, + and in particular considerably better than the "compress" + program; + * Can be implemented readily in a manner not covered by + patents, and hence can be practiced freely; + * Is compatible with the file format produced by the current + widely used gzip utility, in that conforming decompressors + will be able to read data produced by the existing gzip + compressor. + + + + +Deutsch Informational [Page 2] + +RFC 1952 GZIP File Format Specification May 1996 + + + The data format defined by this specification does not attempt to: + + * Provide random access to compressed data; + * Compress specialized data (e.g., raster graphics) as well as + the best currently available specialized algorithms. + + 1.2. Intended audience + + This specification is intended for use by implementors of software + to compress data into gzip format and/or decompress data from gzip + format. + + The text of the specification assumes a basic background in + programming at the level of bits and other primitive data + representations. + + 1.3. Scope + + The specification specifies a compression method and a file format + (the latter assuming only that a file can store a sequence of + arbitrary bytes). It does not specify any particular interface to + a file system or anything about character sets or encodings + (except for file names and comments, which are optional). + + 1.4. Compliance + + Unless otherwise indicated below, a compliant decompressor must be + able to accept and decompress any file that conforms to all the + specifications presented here; a compliant compressor must produce + files that conform to all the specifications presented here. The + material in the appendices is not part of the specification per se + and is not relevant to compliance. + + 1.5. Definitions of terms and conventions used + + byte: 8 bits stored or transmitted as a unit (same as an octet). + (For this specification, a byte is exactly 8 bits, even on + machines which store a character on a number of bits different + from 8.) See below for the numbering of bits within a byte. + + 1.6. Changes from previous versions + + There have been no technical changes to the gzip format since + version 4.1 of this specification. In version 4.2, some + terminology was changed, and the sample CRC code was rewritten for + clarity and to eliminate the requirement for the caller to do pre- + and post-conditioning. Version 4.3 is a conversion of the + specification to RFC style. + + + +Deutsch Informational [Page 3] + +RFC 1952 GZIP File Format Specification May 1996 + + +2. Detailed specification + + 2.1. Overall conventions + + In the diagrams below, a box like this: + + +---+ + | | <-- the vertical bars might be missing + +---+ + + represents one byte; a box like this: + + +==============+ + | | + +==============+ + + represents a variable number of bytes. + + Bytes stored within a computer do not have a "bit order", since + they are always treated as a unit. However, a byte considered as + an integer between 0 and 255 does have a most- and least- + significant bit, and since we write numbers with the most- + significant digit on the left, we also write bytes with the most- + significant bit on the left. In the diagrams below, we number the + bits of a byte so that bit 0 is the least-significant bit, i.e., + the bits are numbered: + + +--------+ + |76543210| + +--------+ + + This document does not address the issue of the order in which + bits of a byte are transmitted on a bit-sequential medium, since + the data format described here is byte- rather than bit-oriented. + + Within a computer, a number may occupy multiple bytes. All + multi-byte numbers in the format described here are stored with + the least-significant byte first (at the lower memory address). + For example, the decimal number 520 is stored as: + + 0 1 + +--------+--------+ + |00001000|00000010| + +--------+--------+ + ^ ^ + | | + | + more significant byte = 2 x 256 + + less significant byte = 8 + + + +Deutsch Informational [Page 4] + +RFC 1952 GZIP File Format Specification May 1996 + + + 2.2. File format + + A gzip file consists of a series of "members" (compressed data + sets). The format of each member is specified in the following + section. The members simply appear one after another in the file, + with no additional information before, between, or after them. + + 2.3. Member format + + Each member has the following structure: + + +---+---+---+---+---+---+---+---+---+---+ + |ID1|ID2|CM |FLG| MTIME |XFL|OS | (more-->) + +---+---+---+---+---+---+---+---+---+---+ + + (if FLG.FEXTRA set) + + +---+---+=================================+ + | XLEN |...XLEN bytes of "extra field"...| (more-->) + +---+---+=================================+ + + (if FLG.FNAME set) + + +=========================================+ + |...original file name, zero-terminated...| (more-->) + +=========================================+ + + (if FLG.FCOMMENT set) + + +===================================+ + |...file comment, zero-terminated...| (more-->) + +===================================+ + + (if FLG.FHCRC set) + + +---+---+ + | CRC16 | + +---+---+ + + +=======================+ + |...compressed blocks...| (more-->) + +=======================+ + + 0 1 2 3 4 5 6 7 + +---+---+---+---+---+---+---+---+ + | CRC32 | ISIZE | + +---+---+---+---+---+---+---+---+ + + + + +Deutsch Informational [Page 5] + +RFC 1952 GZIP File Format Specification May 1996 + + + 2.3.1. Member header and trailer + + ID1 (IDentification 1) + ID2 (IDentification 2) + These have the fixed values ID1 = 31 (0x1f, \037), ID2 = 139 + (0x8b, \213), to identify the file as being in gzip format. + + CM (Compression Method) + This identifies the compression method used in the file. CM + = 0-7 are reserved. CM = 8 denotes the "deflate" + compression method, which is the one customarily used by + gzip and which is documented elsewhere. + + FLG (FLaGs) + This flag byte is divided into individual bits as follows: + + bit 0 FTEXT + bit 1 FHCRC + bit 2 FEXTRA + bit 3 FNAME + bit 4 FCOMMENT + bit 5 reserved + bit 6 reserved + bit 7 reserved + + If FTEXT is set, the file is probably ASCII text. This is + an optional indication, which the compressor may set by + checking a small amount of the input data to see whether any + non-ASCII characters are present. In case of doubt, FTEXT + is cleared, indicating binary data. For systems which have + different file formats for ascii text and binary data, the + decompressor can use FTEXT to choose the appropriate format. + We deliberately do not specify the algorithm used to set + this bit, since a compressor always has the option of + leaving it cleared and a decompressor always has the option + of ignoring it and letting some other program handle issues + of data conversion. + + If FHCRC is set, a CRC16 for the gzip header is present, + immediately before the compressed data. The CRC16 consists + of the two least significant bytes of the CRC32 for all + bytes of the gzip header up to and not including the CRC16. + [The FHCRC bit was never set by versions of gzip up to + 1.2.4, even though it was documented with a different + meaning in gzip 1.2.4.] + + If FEXTRA is set, optional extra fields are present, as + described in a following section. + + + +Deutsch Informational [Page 6] + +RFC 1952 GZIP File Format Specification May 1996 + + + If FNAME is set, an original file name is present, + terminated by a zero byte. The name must consist of ISO + 8859-1 (LATIN-1) characters; on operating systems using + EBCDIC or any other character set for file names, the name + must be translated to the ISO LATIN-1 character set. This + is the original name of the file being compressed, with any + directory components removed, and, if the file being + compressed is on a file system with case insensitive names, + forced to lower case. There is no original file name if the + data was compressed from a source other than a named file; + for example, if the source was stdin on a Unix system, there + is no file name. + + If FCOMMENT is set, a zero-terminated file comment is + present. This comment is not interpreted; it is only + intended for human consumption. The comment must consist of + ISO 8859-1 (LATIN-1) characters. Line breaks should be + denoted by a single line feed character (10 decimal). + + Reserved FLG bits must be zero. + + MTIME (Modification TIME) + This gives the most recent modification time of the original + file being compressed. The time is in Unix format, i.e., + seconds since 00:00:00 GMT, Jan. 1, 1970. (Note that this + may cause problems for MS-DOS and other systems that use + local rather than Universal time.) If the compressed data + did not come from a file, MTIME is set to the time at which + compression started. MTIME = 0 means no time stamp is + available. + + XFL (eXtra FLags) + These flags are available for use by specific compression + methods. The "deflate" method (CM = 8) sets these flags as + follows: + + XFL = 2 - compressor used maximum compression, + slowest algorithm + XFL = 4 - compressor used fastest algorithm + + OS (Operating System) + This identifies the type of file system on which compression + took place. This may be useful in determining end-of-line + convention for text files. The currently defined values are + as follows: + + + + + + +Deutsch Informational [Page 7] + +RFC 1952 GZIP File Format Specification May 1996 + + + 0 - FAT filesystem (MS-DOS, OS/2, NT/Win32) + 1 - Amiga + 2 - VMS (or OpenVMS) + 3 - Unix + 4 - VM/CMS + 5 - Atari TOS + 6 - HPFS filesystem (OS/2, NT) + 7 - Macintosh + 8 - Z-System + 9 - CP/M + 10 - TOPS-20 + 11 - NTFS filesystem (NT) + 12 - QDOS + 13 - Acorn RISCOS + 255 - unknown + + XLEN (eXtra LENgth) + If FLG.FEXTRA is set, this gives the length of the optional + extra field. See below for details. + + CRC32 (CRC-32) + This contains a Cyclic Redundancy Check value of the + uncompressed data computed according to CRC-32 algorithm + used in the ISO 3309 standard and in section 8.1.1.6.2 of + ITU-T recommendation V.42. (See http://www.iso.ch for + ordering ISO documents. See gopher://info.itu.ch for an + online version of ITU-T V.42.) + + ISIZE (Input SIZE) + This contains the size of the original (uncompressed) input + data modulo 2^32. + + 2.3.1.1. Extra field + + If the FLG.FEXTRA bit is set, an "extra field" is present in + the header, with total length XLEN bytes. It consists of a + series of subfields, each of the form: + + +---+---+---+---+==================================+ + |SI1|SI2| LEN |... LEN bytes of subfield data ...| + +---+---+---+---+==================================+ + + SI1 and SI2 provide a subfield ID, typically two ASCII letters + with some mnemonic value. Jean-Loup Gailly + is maintaining a registry of subfield + IDs; please send him any subfield ID you wish to use. Subfield + IDs with SI2 = 0 are reserved for future use. The following + IDs are currently defined: + + + +Deutsch Informational [Page 8] + +RFC 1952 GZIP File Format Specification May 1996 + + + SI1 SI2 Data + ---------- ---------- ---- + 0x41 ('A') 0x70 ('P') Apollo file type information + + LEN gives the length of the subfield data, excluding the 4 + initial bytes. + + 2.3.1.2. Compliance + + A compliant compressor must produce files with correct ID1, + ID2, CM, CRC32, and ISIZE, but may set all the other fields in + the fixed-length part of the header to default values (255 for + OS, 0 for all others). The compressor must set all reserved + bits to zero. + + A compliant decompressor must check ID1, ID2, and CM, and + provide an error indication if any of these have incorrect + values. It must examine FEXTRA/XLEN, FNAME, FCOMMENT and FHCRC + at least so it can skip over the optional fields if they are + present. It need not examine any other part of the header or + trailer; in particular, a decompressor may ignore FTEXT and OS + and always produce binary output, and still be compliant. A + compliant decompressor must give an error indication if any + reserved bit is non-zero, since such a bit could indicate the + presence of a new field that would cause subsequent data to be + interpreted incorrectly. + +3. References + + [1] "Information Processing - 8-bit single-byte coded graphic + character sets - Part 1: Latin alphabet No.1" (ISO 8859-1:1987). + The ISO 8859-1 (Latin-1) character set is a superset of 7-bit + ASCII. Files defining this character set are available as + iso_8859-1.* in ftp://ftp.uu.net/graphics/png/documents/ + + [2] ISO 3309 + + [3] ITU-T recommendation V.42 + + [4] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification", + available in ftp://ftp.uu.net/pub/archiving/zip/doc/ + + [5] Gailly, J.-L., GZIP documentation, available as gzip-*.tar in + ftp://prep.ai.mit.edu/pub/gnu/ + + [6] Sarwate, D.V., "Computation of Cyclic Redundancy Checks via Table + Look-Up", Communications of the ACM, 31(8), pp.1008-1013. + + + + +Deutsch Informational [Page 9] + +RFC 1952 GZIP File Format Specification May 1996 + + + [7] Schwaderer, W.D., "CRC Calculation", April 85 PC Tech Journal, + pp.118-133. + + [8] ftp://ftp.adelaide.edu.au/pub/rocksoft/papers/crc_v3.txt, + describing the CRC concept. + +4. Security Considerations + + Any data compression method involves the reduction of redundancy in + the data. Consequently, any corruption of the data is likely to have + severe effects and be difficult to correct. Uncompressed text, on + the other hand, will probably still be readable despite the presence + of some corrupted bytes. + + It is recommended that systems using this data format provide some + means of validating the integrity of the compressed data, such as by + setting and checking the CRC-32 check value. + +5. Acknowledgements + + Trademarks cited in this document are the property of their + respective owners. + + Jean-Loup Gailly designed the gzip format and wrote, with Mark Adler, + the related software described in this specification. Glenn + Randers-Pehrson converted this document to RFC and HTML format. + +6. Author's Address + + L. Peter Deutsch + Aladdin Enterprises + 203 Santa Margarita Ave. + Menlo Park, CA 94025 + + Phone: (415) 322-0103 (AM only) + FAX: (415) 322-1734 + EMail: + + Questions about the technical content of this specification can be + sent by email to: + + Jean-Loup Gailly and + Mark Adler + + Editorial comments on this specification can be sent by email to: + + L. Peter Deutsch and + Glenn Randers-Pehrson + + + +Deutsch Informational [Page 10] + +RFC 1952 GZIP File Format Specification May 1996 + + +7. Appendix: Jean-Loup Gailly's gzip utility + + The most widely used implementation of gzip compression, and the + original documentation on which this specification is based, were + created by Jean-Loup Gailly . Since this + implementation is a de facto standard, we mention some more of its + features here. Again, the material in this section is not part of + the specification per se, and implementations need not follow it to + be compliant. + + When compressing or decompressing a file, gzip preserves the + protection, ownership, and modification time attributes on the local + file system, since there is no provision for representing protection + attributes in the gzip file format itself. Since the file format + includes a modification time, the gzip decompressor provides a + command line switch that assigns the modification time from the file, + rather than the local modification time of the compressed input, to + the decompressed output. + +8. Appendix: Sample CRC Code + + The following sample code represents a practical implementation of + the CRC (Cyclic Redundancy Check). (See also ISO 3309 and ITU-T V.42 + for a formal specification.) + + The sample code is in the ANSI C programming language. Non C users + may find it easier to read with these hints: + + & Bitwise AND operator. + ^ Bitwise exclusive-OR operator. + >> Bitwise right shift operator. When applied to an + unsigned quantity, as here, right shift inserts zero + bit(s) at the left. + ! Logical NOT operator. + ++ "n++" increments the variable n. + 0xNNN 0x introduces a hexadecimal (base 16) constant. + Suffix L indicates a long value (at least 32 bits). + + /* Table of CRCs of all 8-bit messages. */ + unsigned long crc_table[256]; + + /* Flag: has the table been computed? Initially false. */ + int crc_table_computed = 0; + + /* Make the table for a fast CRC. */ + void make_crc_table(void) + { + unsigned long c; + + + +Deutsch Informational [Page 11] + +RFC 1952 GZIP File Format Specification May 1996 + + + int n, k; + for (n = 0; n < 256; n++) { + c = (unsigned long) n; + for (k = 0; k < 8; k++) { + if (c & 1) { + c = 0xedb88320L ^ (c >> 1); + } else { + c = c >> 1; + } + } + crc_table[n] = c; + } + crc_table_computed = 1; + } + + /* + Update a running crc with the bytes buf[0..len-1] and return + the updated crc. The crc should be initialized to zero. Pre- and + post-conditioning (one's complement) is performed within this + function so it shouldn't be done by the caller. Usage example: + + unsigned long crc = 0L; + + while (read_buffer(buffer, length) != EOF) { + crc = update_crc(crc, buffer, length); + } + if (crc != original_crc) error(); + */ + unsigned long update_crc(unsigned long crc, + unsigned char *buf, int len) + { + unsigned long c = crc ^ 0xffffffffL; + int n; + + if (!crc_table_computed) + make_crc_table(); + for (n = 0; n < len; n++) { + c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8); + } + return c ^ 0xffffffffL; + } + + /* Return the CRC of the bytes buf[0..len-1]. */ + unsigned long crc(unsigned char *buf, int len) + { + return update_crc(0L, buf, len); + } + + + + +Deutsch Informational [Page 12] + diff --git a/deps/zlib/doc/txtvsbin.txt b/deps/zlib/doc/txtvsbin.txt new file mode 100644 index 00000000000000..2a901eaa68af26 --- /dev/null +++ b/deps/zlib/doc/txtvsbin.txt @@ -0,0 +1,107 @@ +A Fast Method for Identifying Plain Text Files +============================================== + + +Introduction +------------ + +Given a file coming from an unknown source, it is sometimes desirable +to find out whether the format of that file is plain text. Although +this may appear like a simple task, a fully accurate detection of the +file type requires heavy-duty semantic analysis on the file contents. +It is, however, possible to obtain satisfactory results by employing +various heuristics. + +Previous versions of PKZip and other zip-compatible compression tools +were using a crude detection scheme: if more than 80% (4/5) of the bytes +found in a certain buffer are within the range [7..127], the file is +labeled as plain text, otherwise it is labeled as binary. A prominent +limitation of this scheme is the restriction to Latin-based alphabets. +Other alphabets, like Greek, Cyrillic or Asian, make extensive use of +the bytes within the range [128..255], and texts using these alphabets +are most often misidentified by this scheme; in other words, the rate +of false negatives is sometimes too high, which means that the recall +is low. Another weakness of this scheme is a reduced precision, due to +the false positives that may occur when binary files containing large +amounts of textual characters are misidentified as plain text. + +In this article we propose a new, simple detection scheme that features +a much increased precision and a near-100% recall. This scheme is +designed to work on ASCII, Unicode and other ASCII-derived alphabets, +and it handles single-byte encodings (ISO-8859, MacRoman, KOI8, etc.) +and variable-sized encodings (ISO-2022, UTF-8, etc.). Wider encodings +(UCS-2/UTF-16 and UCS-4/UTF-32) are not handled, however. + + +The Algorithm +------------- + +The algorithm works by dividing the set of bytecodes [0..255] into three +categories: +- The allow list of textual bytecodes: + 9 (TAB), 10 (LF), 13 (CR), 32 (SPACE) to 255. +- The gray list of tolerated bytecodes: + 7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB), 27 (ESC). +- The block list of undesired, non-textual bytecodes: + 0 (NUL) to 6, 14 to 31. + +If a file contains at least one byte that belongs to the allow list and +no byte that belongs to the block list, then the file is categorized as +plain text; otherwise, it is categorized as binary. (The boundary case, +when the file is empty, automatically falls into the latter category.) + + +Rationale +--------- + +The idea behind this algorithm relies on two observations. + +The first observation is that, although the full range of 7-bit codes +[0..127] is properly specified by the ASCII standard, most control +characters in the range [0..31] are not used in practice. The only +widely-used, almost universally-portable control codes are 9 (TAB), +10 (LF) and 13 (CR). There are a few more control codes that are +recognized on a reduced range of platforms and text viewers/editors: +7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB) and 27 (ESC); but these +codes are rarely (if ever) used alone, without being accompanied by +some printable text. Even the newer, portable text formats such as +XML avoid using control characters outside the list mentioned here. + +The second observation is that most of the binary files tend to contain +control characters, especially 0 (NUL). Even though the older text +detection schemes observe the presence of non-ASCII codes from the range +[128..255], the precision rarely has to suffer if this upper range is +labeled as textual, because the files that are genuinely binary tend to +contain both control characters and codes from the upper range. On the +other hand, the upper range needs to be labeled as textual, because it +is used by virtually all ASCII extensions. In particular, this range is +used for encoding non-Latin scripts. + +Since there is no counting involved, other than simply observing the +presence or the absence of some byte values, the algorithm produces +consistent results, regardless what alphabet encoding is being used. +(If counting were involved, it could be possible to obtain different +results on a text encoded, say, using ISO-8859-16 versus UTF-8.) + +There is an extra category of plain text files that are "polluted" with +one or more block-listed codes, either by mistake or by peculiar design +considerations. In such cases, a scheme that tolerates a small fraction +of block-listed codes would provide an increased recall (i.e. more true +positives). This, however, incurs a reduced precision overall, since +false positives are more likely to appear in binary files that contain +large chunks of textual data. Furthermore, "polluted" plain text should +be regarded as binary by general-purpose text detection schemes, because +general-purpose text processing algorithms might not be applicable. +Under this premise, it is safe to say that our detection method provides +a near-100% recall. + +Experiments have been run on many files coming from various platforms +and applications. We tried plain text files, system logs, source code, +formatted office documents, compiled object code, etc. The results +confirm the optimistic assumptions about the capabilities of this +algorithm. + + +-- +Cosmin Truta +Last updated: 2006-May-28 diff --git a/deps/zlib/examples/zpipe.c b/deps/zlib/examples/zpipe.c index 51dec4745772e5..effc0194834c6a 100644 --- a/deps/zlib/examples/zpipe.c +++ b/deps/zlib/examples/zpipe.c @@ -1,6 +1,6 @@ /* zpipe.c: example of proper use of zlib's inflate() and deflate() Not copyrighted -- provided to the public domain - Version 1.4 11 December 2005 Mark Adler */ + Version 1.5 11 February 2026 Mark Adler */ /* Version history: 1.0 30 Oct 2004 First version @@ -10,6 +10,7 @@ 1.3 6 Apr 2005 Remove incorrect assertion in inf() 1.4 11 Dec 2005 Add hack to avoid MSDOS end-of-line conversions Avoid some compiler warnings for input and output buffers + 1.5 11 Feb 2026 Use underscores for Windows POSIX names */ #if defined(_WIN32) && !defined(_CRT_NONSTDC_NO_DEPRECATE) @@ -24,7 +25,7 @@ #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__) # include # include -# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +# define SET_BINARY_MODE(file) _setmode(_fileno(file), _O_BINARY) #else # define SET_BINARY_MODE(file) #endif diff --git a/deps/zlib/google/test/data/bug500521311.zip b/deps/zlib/google/test/data/bug500521311.zip new file mode 100644 index 00000000000000..cb55f30fb8b83a Binary files /dev/null and b/deps/zlib/google/test/data/bug500521311.zip differ diff --git a/deps/zlib/google/test_data.filelist b/deps/zlib/google/test_data.filelist index bdfec4f3b1801c..73ed6c3c93173e 100644 --- a/deps/zlib/google/test_data.filelist +++ b/deps/zlib/google/test_data.filelist @@ -15,6 +15,7 @@ test/data/Repeated File Name.zip test/data/SJIS Bug 846195.zip test/data/Windows Special Names.zip test/data/Wrong CRC.zip +test/data/bug500521311.zip test/data/create_symlink_test_zips.py test/data/create_test_zip.sh test/data/empty.zip diff --git a/deps/zlib/google/zip_reader.cc b/deps/zlib/google/zip_reader.cc index eb3adcaee35c0b..002a1e3ed01d35 100644 --- a/deps/zlib/google/zip_reader.cc +++ b/deps/zlib/google/zip_reader.cc @@ -5,11 +5,14 @@ #include "third_party/zlib/google/zip_reader.h" #include +#include #include #include #include "base/check.h" +#include "base/containers/span.h" #include "base/containers/heap_array.h" +#include "base/strings/string_view_util.h" #include "base/files/file.h" #include "base/files/file_util.h" #include "base/functional/bind.h" @@ -86,8 +89,8 @@ class StringWriterDelegate : public WriterDelegate { explicit StringWriterDelegate(std::string* output) : output_(output) {} // WriterDelegate methods: - bool WriteBytes(const char* data, int num_bytes) override { - output_->append(data, num_bytes); + bool WriteBytes(base::span data) override { + *output_ += base::as_string_view(data); return true; } @@ -304,6 +307,12 @@ bool ZipReader::OpenEntry() { DCHECK(path_in_zip[info.size_filename] == '\0'); entry_.path_in_original_encoding = path_in_zip.data(); + if (info.size_utf8_filename > 0) { + // Use the Info-ZIP Unicode Path Extra Field if present. + DCHECK(info.utf8_filename[info.size_utf8_filename] == '\0'); + entry_.path_in_original_encoding = info.utf8_filename; + } + // Convert path from original encoding to Unicode. std::u16string path_in_utf16; const char* const encoding = encoding_.empty() ? "UTF-8" : encoding_.c_str(); @@ -485,8 +494,10 @@ bool ZipReader::ExtractCurrentEntry(WriterDelegate* delegate, uint64_t num_bytes_to_write = std::min( remaining_capacity, base::checked_cast(num_bytes_read)); - if (!delegate->WriteBytes(buf, num_bytes_to_write)) + if (!delegate->WriteBytes(base::as_byte_span(buf).first( + base::checked_cast(num_bytes_to_write)))) { break; + } if (remaining_capacity == base::checked_cast(num_bytes_read)) { // Ensures function returns true if the entire file has been read. @@ -679,7 +690,9 @@ void ZipReader::ExtractChunk(base::File output_file, return; } - if (num_bytes_read != output_file.Write(offset, buffer, num_bytes_read)) { + if (!output_file.WriteAndCheck( + offset, base::as_byte_span(buffer).first( + static_cast(num_bytes_read)))) { LOG(ERROR) << "Cannot write " << num_bytes_read << " bytes to file at offset " << offset; std::move(failure_callback).Run(); @@ -734,11 +747,12 @@ bool FileWriterDelegate::PrepareOutput() { return true; } -bool FileWriterDelegate::WriteBytes(const char* data, int num_bytes) { - int bytes_written = file_->WriteAtCurrentPos(data, num_bytes); - if (bytes_written > 0) - file_length_ += bytes_written; - return bytes_written == num_bytes; +bool FileWriterDelegate::WriteBytes(base::span data) { + const std::optional bytes_written = file_->WriteAtCurrentPos(data); + if (bytes_written > 0) { + file_length_ += *bytes_written; + } + return bytes_written == data.size(); } void FileWriterDelegate::SetTimeModified(const base::Time& time) { diff --git a/deps/zlib/google/zip_reader.h b/deps/zlib/google/zip_reader.h index 26c4f716c14cf2..8bc4a21d27c344 100644 --- a/deps/zlib/google/zip_reader.h +++ b/deps/zlib/google/zip_reader.h @@ -12,6 +12,7 @@ #include #include +#include "base/containers/span.h" #include "base/files/file.h" #include "base/files/file_path.h" #include "base/functional/callback.h" @@ -39,7 +40,7 @@ class WriterDelegate { // Invoked to write the next chunk of data. Return false on failure to cancel // extraction. - virtual bool WriteBytes(const char* data, int num_bytes) { return true; } + virtual bool WriteBytes(base::span data) { return true; } // Sets the last-modified time of the data. virtual void SetTimeModified(const base::Time& time) {} @@ -377,9 +378,9 @@ class FileWriterDelegate : public WriterDelegate { // Returns true if the file handle passed to the constructor is valid. bool PrepareOutput() override; - // Writes |num_bytes| bytes of |data| to the file, returning false on error or - // if not all bytes could be written. - bool WriteBytes(const char* data, int num_bytes) override; + // Writes |data| to the file, returning false on error or if not all bytes + // could be written. + bool WriteBytes(base::span data) override; // Sets the last-modified time of the data. void SetTimeModified(const base::Time& time) override; diff --git a/deps/zlib/google/zip_reader_unittest.cc b/deps/zlib/google/zip_reader_unittest.cc index 10ad64b4ce9b24..7a9f24b434ec20 100644 --- a/deps/zlib/google/zip_reader_unittest.cc +++ b/deps/zlib/google/zip_reader_unittest.cc @@ -119,7 +119,7 @@ class MockUnzipListener final { class MockWriterDelegate : public zip::WriterDelegate { public: MOCK_METHOD0(PrepareOutput, bool()); - MOCK_METHOD2(WriteBytes, bool(const char*, int)); + MOCK_METHOD1(WriteBytes, bool(base::span)); MOCK_METHOD1(SetTimeModified, void(const base::Time&)); MOCK_METHOD1(SetPosixFilePermissions, void(int)); MOCK_METHOD0(OnError, void()); @@ -896,7 +896,7 @@ TEST_F(ZipReaderTest, ExtractCurrentEntryWriteBytesFailure) { testing::StrictMock mock_writer; EXPECT_CALL(mock_writer, PrepareOutput()).WillOnce(Return(true)); - EXPECT_CALL(mock_writer, WriteBytes(_, _)).WillOnce(Return(false)); + EXPECT_CALL(mock_writer, WriteBytes).WillOnce(Return(false)); EXPECT_CALL(mock_writer, OnError()); base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt")); @@ -912,7 +912,7 @@ TEST_F(ZipReaderTest, ExtractCurrentEntrySuccess) { testing::StrictMock mock_writer; EXPECT_CALL(mock_writer, PrepareOutput()).WillOnce(Return(true)); - EXPECT_CALL(mock_writer, WriteBytes(_, _)).WillRepeatedly(Return(true)); + EXPECT_CALL(mock_writer, WriteBytes).WillRepeatedly(Return(true)); EXPECT_CALL(mock_writer, SetPosixFilePermissions(_)); EXPECT_CALL(mock_writer, SetTimeModified(_)); @@ -1002,7 +1002,7 @@ TEST_F(FileWriterDelegateTest, WriteToEnd) { FileWriterDelegate writer(&file_); EXPECT_EQ(0, writer.file_length()); ASSERT_TRUE(writer.PrepareOutput()); - ASSERT_TRUE(writer.WriteBytes(payload.data(), payload.size())); + ASSERT_TRUE(writer.WriteBytes(base::as_byte_span(payload))); EXPECT_EQ(payload.size(), writer.file_length()); } @@ -1016,7 +1016,7 @@ TEST_F(FileWriterDelegateTest, EmptyOnError) { FileWriterDelegate writer(&file_); EXPECT_EQ(0, writer.file_length()); ASSERT_TRUE(writer.PrepareOutput()); - ASSERT_TRUE(writer.WriteBytes(payload.data(), payload.size())); + ASSERT_TRUE(writer.WriteBytes(base::as_byte_span(payload))); EXPECT_EQ(payload.size(), writer.file_length()); EXPECT_EQ(payload.size(), file_.GetLength()); writer.OnError(); diff --git a/deps/zlib/google/zip_unittest.cc b/deps/zlib/google/zip_unittest.cc index 494ffed2d297d8..19e77d4eb4f720 100644 --- a/deps/zlib/google/zip_unittest.cc +++ b/deps/zlib/google/zip_unittest.cc @@ -15,6 +15,7 @@ #include #include +#include "base/containers/span.h" #include "base/files/file.h" #include "base/files/file_enumerator.h" #include "base/files/file_path.h" @@ -81,8 +82,8 @@ class ProgressWriterDelegate : public zip::WriterDelegate { CHECK_GT(expected_size_, 0); } - bool WriteBytes(const char* data, int num_bytes) override { - received_bytes_ += num_bytes; + bool WriteBytes(base::span data) override { + received_bytes_ += data.size(); LogProgressIfNecessary(); return true; } @@ -125,6 +126,11 @@ class VirtualFileSystem : public zip::FileAccessor { static constexpr char kFooContent[] = "This is foo."; static constexpr char kBar1Content[] = "This is bar."; static constexpr char kBar2Content[] = "This is bar too."; + // Fixed last-modified time returned by GetInfo() for every entry. + // Chosen so it is representable in the MS-DOS time format used by ZIP + // entries (2-second granularity, base year 1980). 1592222400 corresponds + // to 2020-06-15 00:00:00 UTC. + static constexpr int64_t kLastModifiedSecondsSinceUnixEpoch = 1592222400; VirtualFileSystem() { base::FilePath test_dir; @@ -212,8 +218,8 @@ class VirtualFileSystem : public zip::FileAccessor { } info->is_directory = !files_.count(path); - info->last_modified = - base::Time::FromSecondsSinceUnixEpoch(172097977); // Some random date. + info->last_modified = base::Time::FromSecondsSinceUnixEpoch( + kLastModifiedSecondsSinceUnixEpoch); return true; } @@ -1245,6 +1251,37 @@ TEST_F(ZipTest, ZipWithFileAccessor) { EXPECT_EQ(VirtualFileSystem::kBar2Content, file_content); } +TEST_F(ZipTest, ZipWithFileAccessorOverridesEntryTimestamps) { + const base::Time expected = base::Time::FromSecondsSinceUnixEpoch( + VirtualFileSystem::kLastModifiedSecondsSinceUnixEpoch); + + base::FilePath zip_file; + ASSERT_TRUE(base::CreateTemporaryFile(&zip_file)); + + VirtualFileSystem file_accessor; + const zip::ZipParams params{.file_accessor = &file_accessor, + .dest_file = zip_file}; + ASSERT_TRUE(zip::Zip(params)); + + zip::ZipReader reader; + ASSERT_TRUE(reader.Open(zip_file)); + + int file_entries = 0; + int dir_entries = 0; + while (const zip::ZipReader::Entry* const entry = reader.Next()) { + EXPECT_EQ(expected, entry->last_modified) + << "Entry " << entry->path << " carries the wrong timestamp"; + if (entry->is_directory) { + ++dir_entries; + } else { + ++file_entries; + } + } + EXPECT_TRUE(reader.ok()); + EXPECT_EQ(3, file_entries); + EXPECT_EQ(1, dir_entries); +} + // Tests progress reporting while zipping files. TEST_F(ZipTest, ZipProgress) { base::FilePath src_dir = GetDataDirectory().AppendASCII("test"); diff --git a/deps/zlib/google/zip_writer.cc b/deps/zlib/google/zip_writer.cc index 34ab0ad9ef2887..561b9ebe1dbfc6 100644 --- a/deps/zlib/google/zip_writer.cc +++ b/deps/zlib/google/zip_writer.cc @@ -7,8 +7,10 @@ #include #include +#include "base/containers/span.h" #include "base/files/file.h" #include "base/logging.h" +#include "base/numerics/safe_conversions.h" #include "base/strings/strcat.h" #include "base/strings/string_util.h" #include "third_party/zlib/google/redact.h" @@ -34,27 +36,29 @@ bool ZipWriter::ShouldContinue() { } bool ZipWriter::AddFileContent(const base::FilePath& path, base::File file) { - char buf[zip::internal::kZipBufSize]; + uint8_t buf[zip::internal::kZipBufSize]; while (ShouldContinue()) { - const int num_bytes = - file.ReadAtCurrentPos(buf, zip::internal::kZipBufSize); + const std::optional num_bytes = file.ReadAtCurrentPos(buf); - if (num_bytes < 0) { + if (!num_bytes) { PLOG(ERROR) << "Cannot read file " << Redact(path); return false; } - if (num_bytes == 0) + if (*num_bytes == 0) { return true; + } - if (zipWriteInFileInZip(zip_file_, buf, num_bytes) != ZIP_OK) { + if (zipWriteInFileInZip(zip_file_, buf, + base::checked_cast(*num_bytes)) != + ZIP_OK) { PLOG(ERROR) << "Cannot write data from file " << Redact(path) << " to ZIP"; return false; } - progress_.bytes += num_bytes; + progress_.bytes += *num_bytes; } return false; @@ -86,9 +90,12 @@ bool ZipWriter::CloseNewFileEntry() { } bool ZipWriter::AddFileEntry(const base::FilePath& path, base::File file) { - base::File::Info info; - if (!file.GetInfo(&info)) - return false; + FileAccessor::Info info; + if (!file_accessor_->GetInfo(path, &info)) { + LOG(ERROR) << "Cannot get info: " << Redact(path); + progress_.errors++; + return continue_on_error_; + } if (!OpenNewFileEntry(path, /*is_directory=*/false, info.last_modified)) return false; diff --git a/deps/zlib/gzguts.h b/deps/zlib/gzguts.h index eba72085bb756b..f7946bdc514f98 100644 --- a/deps/zlib/gzguts.h +++ b/deps/zlib/gzguts.h @@ -1,5 +1,5 @@ /* gzguts.h -- zlib internal header definitions for gz* operations - * Copyright (C) 2004-2024 Mark Adler + * Copyright (C) 2004-2026 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -17,6 +17,18 @@ # define ZLIB_INTERNAL #endif +#if defined(_WIN32) +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# ifndef _CRT_SECURE_NO_WARNINGS +# define _CRT_SECURE_NO_WARNINGS +# endif +# ifndef _CRT_NONSTDC_NO_DEPRECATE +# define _CRT_NONSTDC_NO_DEPRECATE +# endif +#endif + #include #include "zlib.h" #ifdef STDC @@ -25,8 +37,8 @@ # include #endif -#ifndef _POSIX_SOURCE -# define _POSIX_SOURCE +#ifndef _POSIX_C_SOURCE +# define _POSIX_C_SOURCE 200112L #endif #include @@ -36,19 +48,13 @@ #if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32) # include +# include #endif -#if defined(_WIN32) +#if defined(_WIN32) && !defined(WIDECHAR) # define WIDECHAR #endif -#ifdef WINAPI_FAMILY -# define open _open -# define read _read -# define write _write -# define close _close -#endif - #ifdef NO_DEFLATE /* for compatibility with old definition */ # define NO_GZCOMPRESS #endif @@ -72,33 +78,28 @@ #endif #ifndef HAVE_VSNPRINTF -# ifdef MSDOS +# if !defined(NO_vsnprintf) && \ + (defined(MSDOS) || defined(__TURBOC__) || defined(__SASC) || \ + defined(VMS) || defined(__OS400) || defined(__MVS__)) /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), but for now we just assume it doesn't. */ # define NO_vsnprintf # endif -# ifdef __TURBOC__ -# define NO_vsnprintf -# endif # ifdef WIN32 /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ -# if !defined(vsnprintf) && !defined(NO_vsnprintf) -# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) -# define vsnprintf _vsnprintf +# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) +# ifndef vsnprintf +# define vsnprintf _vsnprintf # endif # endif -# endif -# ifdef __SASC -# define NO_vsnprintf -# endif -# ifdef VMS -# define NO_vsnprintf -# endif -# ifdef __OS400__ -# define NO_vsnprintf -# endif -# ifdef __MVS__ -# define NO_vsnprintf +# elif !defined(__STDC_VERSION__) || __STDC_VERSION__-0 < 199901L +/* Otherwise if C89/90, assume no C99 snprintf() or vsnprintf() */ +# ifndef NO_snprintf +# define NO_snprintf +# endif +# ifndef NO_vsnprintf +# define NO_vsnprintf +# endif # endif #endif @@ -135,6 +136,11 @@ # endif #endif +/* some environments don't define EWOULDBLOCK */ +#ifndef EWOULDBLOCK +# define EWOULDBLOCK EAGAIN +#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 *); @@ -182,7 +188,9 @@ typedef struct { unsigned char *out; /* output buffer (double-sized when reading) */ int direct; /* 0 if processing gzip, 1 if transparent */ /* just for reading */ + int junk; /* -1 = start, 1 = junk candidate, 0 = in gzip */ int how; /* 0: get header, 1: copy, 2: decompress */ + int again; /* true if EAGAIN or EWOULDBLOCK on last i/o */ z_off64_t start; /* where the gzip data started, for rewinding */ int eof; /* true if end of input file reached */ int past; /* true if read requested past end */ @@ -192,7 +200,6 @@ typedef struct { int reset; /* true if a reset is pending after a Z_FINISH */ /* seek request */ z_off64_t skip; /* amount to skip (already rewound if backwards) */ - int seek; /* true if seek request pending */ /* error information */ int err; /* error code */ char *msg; /* error message */ diff --git a/deps/zlib/gzlib.c b/deps/zlib/gzlib.c index 7136395f89a953..2db29c8f076002 100644 --- a/deps/zlib/gzlib.c +++ b/deps/zlib/gzlib.c @@ -1,22 +1,22 @@ /* gzlib.c -- zlib functions common to reading and writing gzip files - * Copyright (C) 2004-2024 Mark Adler + * Copyright (C) 2004-2026 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ #include "gzguts.h" -#if defined(_WIN32) && !defined(__BORLANDC__) +#if defined(__DJGPP__) +# define LSEEK llseek +#elif defined(_WIN32) && !defined(__BORLANDC__) && !defined(UNDER_CE) # define LSEEK _lseeki64 # define OPEN open -#else -#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +#elif defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 # define LSEEK lseek64 # define OPEN open64 #else # define LSEEK lseek # define OPEN open #endif -#endif #if defined UNDER_CE @@ -55,7 +55,7 @@ char ZLIB_INTERNAL *gz_strwinerror(DWORD error) { msgbuf[chars] = 0; } - wcstombs(buf, msgbuf, chars + 1); + wcstombs(buf, msgbuf, chars + 1); /* assumes buf is big enough */ LocalFree(msgbuf); } else { @@ -75,10 +75,12 @@ local void gz_reset(gz_statep state) { state->eof = 0; /* not at end of file */ state->past = 0; /* have not read past end yet */ state->how = LOOK; /* look for gzip header */ + state->junk = -1; /* mark first member */ } else /* for writing ... */ state->reset = 0; /* no deflateReset pending */ - state->seek = 0; /* no seek request pending */ + state->again = 0; /* no stalled i/o yet */ + state->skip = 0; /* no seek request pending */ gz_error(state, Z_OK, NULL); /* clear error */ state->x.pos = 0; /* no uncompressed data yet */ state->strm.avail_in = 0; /* no input data yet */ @@ -88,16 +90,13 @@ local void gz_reset(gz_statep state) { local gzFile gz_open(const void *path, int fd, const char *mode) { gz_statep state; z_size_t len; - int oflag; -#ifdef O_CLOEXEC - int cloexec = 0; -#endif + int oflag = 0; #ifdef O_EXCL int exclusive = 0; #endif /* check input */ - if (path == NULL) + if (path == NULL || mode == NULL) return NULL; /* allocate gzFile structure to return */ @@ -106,6 +105,7 @@ local gzFile gz_open(const void *path, int fd, const char *mode) { return NULL; state->size = 0; /* no buffers allocated yet */ state->want = GZBUFSIZE; /* requested buffer size */ + state->err = Z_OK; /* no error yet */ state->msg = NULL; /* no error message yet */ /* interpret mode */ @@ -136,7 +136,7 @@ local gzFile gz_open(const void *path, int fd, const char *mode) { break; #ifdef O_CLOEXEC case 'e': - cloexec = 1; + oflag |= O_CLOEXEC; break; #endif #ifdef O_EXCL @@ -156,6 +156,14 @@ local gzFile gz_open(const void *path, int fd, const char *mode) { case 'F': state->strategy = Z_FIXED; break; + case 'G': + state->direct = -1; + break; +#ifdef O_NONBLOCK + case 'N': + oflag |= O_NONBLOCK; + break; +#endif case 'T': state->direct = 1; break; @@ -171,22 +179,30 @@ local gzFile gz_open(const void *path, int fd, const char *mode) { return NULL; } - /* can't force transparent read */ + /* direct is 0, 1 if "T", or -1 if "G" (last "G" or "T" wins) */ if (state->mode == GZ_READ) { - if (state->direct) { + if (state->direct == 1) { + /* can't force a transparent read */ free(state); return NULL; } - state->direct = 1; /* for empty file */ + if (state->direct == 0) + /* default when reading is auto-detect of gzip vs. transparent -- + start with a transparent assumption in case of an empty file */ + state->direct = 1; } + else if (state->direct == -1) { + /* "G" has no meaning when writing -- disallow it */ + free(state); + return NULL; + } + /* if reading, direct == 1 for auto-detect, -1 for gzip only; if writing or + appending, direct == 0 for gzip, 1 for transparent (copy in to out) */ /* save the path name for error messages */ #ifdef WIDECHAR - if (fd == -2) { + if (fd == -2) len = wcstombs(NULL, path, 0); - if (len == (z_size_t)-1) - len = 0; - } else #endif len = strlen((const char *)path); @@ -196,29 +212,29 @@ local gzFile gz_open(const void *path, int fd, const char *mode) { return NULL; } #ifdef WIDECHAR - if (fd == -2) + if (fd == -2) { if (len) wcstombs(state->path, path, len + 1); else *(state->path) = 0; + } else #endif + { #if !defined(NO_snprintf) && !defined(NO_vsnprintf) (void)snprintf(state->path, len + 1, "%s", (const char *)path); #else strcpy(state->path, path); #endif + } /* compute the flags for open() */ - oflag = + oflag |= #ifdef O_LARGEFILE O_LARGEFILE | #endif #ifdef O_BINARY O_BINARY | -#endif -#ifdef O_CLOEXEC - (cloexec ? O_CLOEXEC : 0) | #endif (state->mode == GZ_READ ? O_RDONLY : @@ -231,11 +247,23 @@ local gzFile gz_open(const void *path, int fd, const char *mode) { O_APPEND))); /* open the file with the appropriate flags (or just use fd) */ - state->fd = fd > -1 ? fd : ( + if (fd == -1) + state->fd = OPEN((const char *)path, oflag, 0666); #ifdef WIDECHAR - fd == -2 ? _wopen(path, oflag, 0666) : + else if (fd == -2) + state->fd = _wopen(path, oflag, _S_IREAD | _S_IWRITE); +#endif + else { +#ifdef O_NONBLOCK + if (oflag & O_NONBLOCK) + fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); #endif - OPEN((const char *)path, oflag, 0666)); +#ifdef O_CLOEXEC + if (oflag & O_CLOEXEC) + fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | O_CLOEXEC); +#endif + state->fd = fd; + } if (state->fd == -1) { free(state->path); free(state); @@ -362,9 +390,10 @@ z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence) { /* normalize offset to a SEEK_CUR specification */ if (whence == SEEK_SET) offset -= state->x.pos; - else if (state->seek) - offset += state->skip; - state->seek = 0; + else { + offset += state->past ? 0 : state->skip; + state->skip = 0; + } /* if within raw area while reading, just go there */ if (state->mode == GZ_READ && state->how == COPY && @@ -375,7 +404,7 @@ z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence) { state->x.have = 0; state->eof = 0; state->past = 0; - state->seek = 0; + state->skip = 0; gz_error(state, Z_OK, NULL); state->strm.avail_in = 0; state->x.pos += offset; @@ -404,10 +433,7 @@ z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence) { } /* request skip (if not zero) */ - if (offset) { - state->seek = 1; - state->skip = offset; - } + state->skip = offset; return state->x.pos + offset; } @@ -431,7 +457,7 @@ z_off64_t ZEXPORT gztell64(gzFile file) { return -1; /* return position */ - return state->x.pos + (state->seek ? state->skip : 0); + return state->x.pos + (state->past ? 0 : state->skip); } /* -- see zlib.h -- */ @@ -538,7 +564,7 @@ void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg) { } /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ - if (err != Z_OK && err != Z_BUF_ERROR) + if (err != Z_OK && err != Z_BUF_ERROR && !state->again) state->x.have = 0; /* set error code, and if no message, then done */ @@ -575,6 +601,7 @@ unsigned ZLIB_INTERNAL gz_intmax(void) { return INT_MAX; #else unsigned p = 1, q; + do { q = p; p <<= 1; diff --git a/deps/zlib/gzread.c b/deps/zlib/gzread.c index 9a9f7847ce4cc6..bf41d63bc61566 100644 --- a/deps/zlib/gzread.c +++ b/deps/zlib/gzread.c @@ -1,5 +1,5 @@ /* gzread.c -- zlib functions for reading gzip files - * Copyright (C) 2004-2017 Mark Adler + * Copyright (C) 2004-2026 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -8,23 +8,36 @@ /* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from state->fd, and update state->eof, state->err, and state->msg as appropriate. This function needs to loop on read(), since read() is not guaranteed to - read the number of bytes requested, depending on the type of descriptor. */ + read the number of bytes requested, depending on the type of descriptor. It + also needs to loop to manage the fact that read() returns an int. If the + descriptor is non-blocking and read() returns with no data in order to avoid + blocking, then gz_load() will return 0 if some data has been read, or -1 if + no data has been read. Either way, state->again is set true to indicate a + non-blocking event. If errno is non-zero on return, then there was an error + signaled from read(). *have is set to the number of bytes read. */ local int gz_load(gz_statep state, unsigned char *buf, unsigned len, unsigned *have) { int ret; unsigned get, max = ((unsigned)-1 >> 2) + 1; + state->again = 0; + errno = 0; *have = 0; do { get = len - *have; if (get > max) get = max; - ret = read(state->fd, buf + *have, get); + ret = (int)read(state->fd, buf + *have, get); if (ret <= 0) break; *have += (unsigned)ret; } while (*have < len); if (ret < 0) { + if (errno == EAGAIN || errno == EWOULDBLOCK) { + state->again = 1; + if (*have != 0) + return 0; + } gz_error(state, Z_ERRNO, zstrerror()); return -1; } @@ -50,10 +63,14 @@ local int gz_avail(gz_statep state) { if (strm->avail_in) { /* copy what's there to the start */ unsigned char *p = state->in; unsigned const char *q = strm->next_in; - unsigned n = strm->avail_in; - do { - *p++ = *q++; - } while (--n); + + if (q != p) { + unsigned n = strm->avail_in; + + do { + *p++ = *q++; + } while (--n); + } } if (gz_load(state, state->in + strm->avail_in, state->size - strm->avail_in, &got) == -1) @@ -104,39 +121,44 @@ local int gz_look(gz_statep state) { } } - /* get at least the magic bytes in the input buffer */ - if (strm->avail_in < 2) { - if (gz_avail(state) == -1) - return -1; - if (strm->avail_in == 0) - return 0; - } - - /* look for gzip magic bytes -- if there, do gzip decoding (note: there is - a logical dilemma here when considering the case of a partially written - gzip file, to wit, if a single 31 byte is written, then we cannot tell - whether this is a single-byte file, or just a partially written gzip - file -- for here we assume that if a gzip file is being written, then - the header will be written in a single operation, so that reading a - single byte is sufficient indication that it is not a gzip file) */ - if (strm->avail_in > 1 && - strm->next_in[0] == 31 && strm->next_in[1] == 139) { + /* if transparent reading is disabled, which would only be at the start, or + if we're looking for a gzip member after the first one, which is not at + the start, then proceed directly to look for a gzip member next */ + if (state->direct == -1 || state->junk == 0) { inflateReset(strm); state->how = GZIP; + state->junk = state->junk != -1; state->direct = 0; return 0; } - /* no gzip header -- if we were decoding gzip before, then this is trailing - garbage. Ignore the trailing garbage and finish. */ - if (state->direct == 0) { - strm->avail_in = 0; - state->eof = 1; - state->x.have = 0; + /* otherwise we're at the start with auto-detect -- we check to see if the + first four bytes could be gzip header in order to decide whether or not + this will be a transparent read */ + + /* load any header bytes into the input buffer -- if the input is empty, + then it's not an error as this is a transparent read of zero bytes */ + if (gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0 || (state->again && strm->avail_in < 4)) + /* if non-blocking input stalled before getting four bytes, then + return and wait until a later call has accumulated enough */ + return 0; + + /* see if this is (likely) gzip input -- if the first four bytes are + consistent with a gzip header, then go look for the first gzip member, + otherwise proceed to copy the input transparently */ + if (strm->avail_in > 3 && + strm->next_in[0] == 31 && strm->next_in[1] == 139 && + strm->next_in[2] == 8 && strm->next_in[3] < 32) { + inflateReset(strm); + state->how = GZIP; + state->junk = 1; + state->direct = 0; return 0; } - /* doing raw i/o, copy any leftover input to output -- this assumes that + /* doing raw i/o: copy any leftover input to output -- this assumes that the output buffer is larger than the input buffer, which also assures space for gzungetc() */ state->x.next = state->out; @@ -144,15 +166,17 @@ local int gz_look(gz_statep state) { state->x.have = strm->avail_in; strm->avail_in = 0; state->how = COPY; - state->direct = 1; return 0; } /* Decompress from input to the provided next_out and avail_out in the state. On return, state->x.have and state->x.next point to the just decompressed - data. If the gzip stream completes, state->how is reset to LOOK to look for - the next gzip stream or raw data, once state->x.have is depleted. Returns 0 - on success, -1 on failure. */ + data. If the gzip stream completes, state->how is reset to LOOK to look for + the next gzip stream or raw data, once state->x.have is depleted. Returns 0 + on success, -1 on failure. If EOF is reached when looking for more input to + complete the gzip member, then an unexpected end of file error is raised. + If there is no more input, but state->again is true, then EOF has not been + reached, and no error is raised. */ local int gz_decomp(gz_statep state) { int ret = Z_OK; unsigned had; @@ -162,28 +186,41 @@ local int gz_decomp(gz_statep state) { had = strm->avail_out; do { /* get more input for inflate() */ - if (strm->avail_in == 0 && gz_avail(state) == -1) - return -1; + if (strm->avail_in == 0 && gz_avail(state) == -1) { + ret = state->err; + break; + } if (strm->avail_in == 0) { - gz_error(state, Z_BUF_ERROR, "unexpected end of file"); + if (!state->again) + gz_error(state, Z_BUF_ERROR, "unexpected end of file"); break; } /* decompress and handle errors */ ret = inflate(strm, Z_NO_FLUSH); + if (strm->avail_out < had) + /* any decompressed data marks this as a real gzip stream */ + state->junk = 0; if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { gz_error(state, Z_STREAM_ERROR, "internal error: inflate stream corrupt"); - return -1; + break; } if (ret == Z_MEM_ERROR) { gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; + break; } if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ + if (state->junk == 1) { /* trailing garbage is ok */ + strm->avail_in = 0; + state->eof = 1; + state->how = LOOK; + ret = Z_OK; + break; + } gz_error(state, Z_DATA_ERROR, strm->msg == NULL ? "compressed data error" : strm->msg); - return -1; + break; } } while (strm->avail_out && ret != Z_STREAM_END); @@ -192,11 +229,14 @@ local int gz_decomp(gz_statep state) { state->x.next = strm->next_out - state->x.have; /* if the gzip stream completed successfully, look for another */ - if (ret == Z_STREAM_END) + if (ret == Z_STREAM_END) { + state->junk = 0; state->how = LOOK; + return 0; + } - /* good decompression */ - return 0; + /* return decompression status */ + return ret != Z_OK ? -1 : 0; } /* Fetch data and put it in the output buffer. Assumes state->x.have is 0. @@ -227,25 +267,31 @@ local int gz_fetch(gz_statep state) { strm->next_out = state->out; if (gz_decomp(state) == -1) return -1; + break; + default: + gz_error(state, Z_STREAM_ERROR, "state corrupt"); + return -1; } } while (state->x.have == 0 && (!state->eof || strm->avail_in)); return 0; } -/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ -local int gz_skip(gz_statep state, z_off64_t len) { +/* Skip state->skip (> 0) uncompressed bytes of output. Return -1 on error, 0 + on success. */ +local int gz_skip(gz_statep state) { unsigned n; /* skip over len bytes or reach end-of-file, whichever comes first */ - while (len) + do { /* skip over whatever is in output buffer */ if (state->x.have) { - n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? - (unsigned)len : state->x.have; + n = GT_OFF(state->x.have) || + (z_off64_t)state->x.have > state->skip ? + (unsigned)state->skip : state->x.have; state->x.have -= n; state->x.next += n; state->x.pos += n; - len -= n; + state->skip -= n; } /* output buffer empty -- return if we're at the end of the input */ @@ -258,30 +304,32 @@ local int gz_skip(gz_statep state, z_off64_t len) { if (gz_fetch(state) == -1) return -1; } + } while (state->skip); return 0; } /* Read len bytes into buf from file, or less than len up to the end of the - input. Return the number of bytes read. If zero is returned, either the - end of file was reached, or there was an error. state->err must be - consulted in that case to determine which. */ + input. Return the number of bytes read. If zero is returned, either the end + of file was reached, or there was an error. state->err must be consulted in + that case to determine which. If there was an error, but some uncompressed + bytes were read before the error, then that count is returned. The error is + still recorded, and so is deferred until the next call. */ local z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) { z_size_t got; unsigned n; + int err; /* if len is zero, avoid unnecessary operations */ if (len == 0) return 0; /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return 0; - } + if (state->skip && gz_skip(state) == -1) + return 0; /* get len bytes to buf, or less than len if at the end */ got = 0; + err = 0; do { /* set n to the maximum amount of len that fits in an unsigned int */ n = (unsigned)-1; @@ -295,37 +343,36 @@ local z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) { memcpy(buf, state->x.next, n); state->x.next += n; state->x.have -= n; + if (state->err != Z_OK) + /* caught deferred error from gz_fetch() */ + err = -1; } /* output buffer empty -- return if we're at the end of the input */ - else if (state->eof && state->strm.avail_in == 0) { - state->past = 1; /* tried to read past end */ + else if (state->eof && state->strm.avail_in == 0) break; - } /* need output data -- for small len or new stream load up our output - buffer */ + buffer, so that gzgetc() can be fast */ else if (state->how == LOOK || n < (state->size << 1)) { /* get more output, looking for header if required */ - if (gz_fetch(state) == -1) - return 0; + if (gz_fetch(state) == -1 && state->x.have == 0) + /* if state->x.have != 0, error will be caught after copy */ + err = -1; continue; /* no progress yet -- go back to copy above */ /* the copy above assures that we will leave with space in the output buffer, allowing at least one gzungetc() to succeed */ } /* large len -- read directly into user buffer */ - else if (state->how == COPY) { /* read directly */ - if (gz_load(state, (unsigned char *)buf, n, &n) == -1) - return 0; - } + else if (state->how == COPY) /* read directly */ + err = gz_load(state, (unsigned char *)buf, n, &n); /* large len -- decompress directly into user buffer */ else { /* state->how == GZIP */ state->strm.avail_out = n; state->strm.next_out = (unsigned char *)buf; - if (gz_decomp(state) == -1) - return 0; + err = gz_decomp(state); n = state->x.have; state->x.have = 0; } @@ -335,7 +382,11 @@ local z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) { buf = (char *)buf + n; got += n; state->x.pos += n; - } while (len); + } while (len && !err); + + /* note read past eof */ + if (len && state->eof) + state->past = 1; /* return number of bytes read into user buffer */ return got; @@ -345,15 +396,17 @@ local z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) { int ZEXPORT gzread(gzFile file, voidp buf, unsigned len) { gz_statep state; - /* get internal structure */ + /* get internal structure and check that it's for reading */ if (file == NULL) return -1; state = (gz_statep)file; + if (state->mode != GZ_READ) + return -1; - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) + /* check that there was no (serious) error */ + if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again) return -1; + gz_error(state, Z_OK, NULL); /* since an int is returned, make sure len fits in one, otherwise return with an error (this avoids a flaw in the interface) */ @@ -366,27 +419,39 @@ int ZEXPORT gzread(gzFile file, voidp buf, unsigned len) { len = (unsigned)gz_read(state, buf, len); /* check for an error */ - if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR) - return -1; + if (len == 0) { + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + if (state->again) { + /* non-blocking input stalled after some input was read, but no + uncompressed bytes were produced -- let the application know + this isn't EOF */ + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + } - /* return the number of bytes read (this is assured to fit in an int) */ + /* return the number of bytes read */ return (int)len; } /* -- see zlib.h -- */ -z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, gzFile file) { +z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, + gzFile file) { z_size_t len; gz_statep state; - /* get internal structure */ + /* get internal structure and check that it's for reading */ if (file == NULL) return 0; state = (gz_statep)file; + if (state->mode != GZ_READ) + return 0; - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) + /* check that there was no (serious) error */ + if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again) return 0; + gz_error(state, Z_OK, NULL); /* compute bytes to read -- error on overflow */ len = nitems * size; @@ -413,15 +478,17 @@ int ZEXPORT gzgetc(gzFile file) { unsigned char buf[1]; gz_statep state; - /* get internal structure */ + /* get internal structure and check that it's for reading */ if (file == NULL) return -1; state = (gz_statep)file; + if (state->mode != GZ_READ) + return -1; - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) + /* check that there was no (serious) error */ + if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again) return -1; + gz_error(state, Z_OK, NULL); /* try output buffer (no need to check for skip request) */ if (state->x.have) { @@ -442,22 +509,25 @@ int ZEXPORT gzgetc_(gzFile file) { int ZEXPORT gzungetc(int c, gzFile file) { gz_statep state; - /* get internal structure */ + /* get internal structure and check that it's for reading */ if (file == NULL) return -1; state = (gz_statep)file; + if (state->mode != GZ_READ) + return -1; + + /* in case this was just opened, set up the input buffer */ + if (state->how == LOOK && state->x.have == 0) + (void)gz_look(state); - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) + /* check that there was no (serious) error */ + if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again) return -1; + gz_error(state, Z_OK, NULL); /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return -1; - } + if (state->skip && gz_skip(state) == -1) + return -1; /* can't push EOF */ if (c < 0) @@ -483,6 +553,7 @@ int ZEXPORT gzungetc(int c, gzFile file) { if (state->x.next == state->out) { unsigned char *src = state->out + state->x.have; unsigned char *dest = state->out + (state->size << 1); + while (src > state->out) *--dest = *--src; state->x.next = dest; @@ -502,32 +573,31 @@ char * ZEXPORT gzgets(gzFile file, char *buf, int len) { unsigned char *eol; gz_statep state; - /* check parameters and get internal structure */ + /* check parameters, get internal structure, and check that it's for + reading */ if (file == NULL || buf == NULL || len < 1) return NULL; state = (gz_statep)file; + if (state->mode != GZ_READ) + return NULL; - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) + /* check that there was no (serious) error */ + if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again) return NULL; + gz_error(state, Z_OK, NULL); /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return NULL; - } + if (state->skip && gz_skip(state) == -1) + return NULL; - /* copy output bytes up to new line or len - 1, whichever comes first -- - append a terminating zero to the string (we don't check for a zero in - the contents, let the user worry about that) */ + /* copy output up to a new line, len-1 bytes, or there is no more output, + whichever comes first */ str = buf; left = (unsigned)len - 1; if (left) do { /* assure that something is in the output buffer */ if (state->x.have == 0 && gz_fetch(state) == -1) - return NULL; /* error */ + break; /* error */ if (state->x.have == 0) { /* end of file */ state->past = 1; /* read past end */ break; /* return what we have */ @@ -548,7 +618,9 @@ char * ZEXPORT gzgets(gzFile file, char *buf, int len) { buf += n; } while (left && eol == NULL); - /* return terminated string, or if nothing, end of file */ + /* append a terminating zero to the string (we don't check for a zero in + the contents, let the user worry about that) -- return the terminated + string, or if nothing was read, NULL */ if (buf == str) return NULL; buf[0] = 0; @@ -570,7 +642,7 @@ int ZEXPORT gzdirect(gzFile file) { (void)gz_look(state); /* return 1 if transparent, 0 if processing a gzip stream */ - return state->direct; + return state->direct == 1; } /* -- see zlib.h -- */ @@ -578,12 +650,10 @@ int ZEXPORT gzclose_r(gzFile file) { int ret, err; gz_statep state; - /* get internal structure */ + /* get internal structure and check that it's for reading */ if (file == NULL) return Z_STREAM_ERROR; state = (gz_statep)file; - - /* check that we're reading */ if (state->mode != GZ_READ) return Z_STREAM_ERROR; diff --git a/deps/zlib/gzwrite.c b/deps/zlib/gzwrite.c index 435b4621b5349f..13a3700a83c7ca 100644 --- a/deps/zlib/gzwrite.c +++ b/deps/zlib/gzwrite.c @@ -1,5 +1,5 @@ /* gzwrite.c -- zlib functions for writing gzip files - * Copyright (C) 2004-2019 Mark Adler + * Copyright (C) 2004-2026 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -74,9 +74,13 @@ local int gz_comp(gz_statep state, int flush) { /* write directly if requested */ if (state->direct) { while (strm->avail_in) { + errno = 0; + state->again = 0; put = strm->avail_in > max ? max : strm->avail_in; - writ = write(state->fd, strm->next_in, put); + writ = (int)write(state->fd, strm->next_in, put); if (writ < 0) { + if (errno == EAGAIN || errno == EWOULDBLOCK) + state->again = 1; gz_error(state, Z_ERRNO, zstrerror()); return -1; } @@ -88,8 +92,9 @@ local int gz_comp(gz_statep state, int flush) { /* check for a pending reset */ if (state->reset) { - /* don't start a new gzip member unless there is data to write */ - if (strm->avail_in == 0) + /* don't start a new gzip member unless there is data to write and + we're not flushing */ + if (strm->avail_in == 0 && flush == Z_NO_FLUSH) return 0; deflateReset(strm); state->reset = 0; @@ -103,10 +108,14 @@ local int gz_comp(gz_statep state, int flush) { if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && (flush != Z_FINISH || ret == Z_STREAM_END))) { while (strm->next_out > state->x.next) { + errno = 0; + state->again = 0; put = strm->next_out - state->x.next > (int)max ? max : (unsigned)(strm->next_out - state->x.next); - writ = write(state->fd, state->x.next, put); + writ = (int)write(state->fd, state->x.next, put); if (writ < 0) { + if (errno == EAGAIN || errno == EWOULDBLOCK) + state->again = 1; gz_error(state, Z_ERRNO, zstrerror()); return -1; } @@ -138,10 +147,12 @@ local int gz_comp(gz_statep state, int flush) { return 0; } -/* Compress len zeros to output. Return -1 on a write error or memory - allocation failure by gz_comp(), or 0 on success. */ -local int gz_zero(gz_statep state, z_off64_t len) { - int first; +/* Compress state->skip (> 0) zeros to output. Return -1 on a write error or + memory allocation failure by gz_comp(), or 0 on success. state->skip is + updated with the number of successfully written zeros, in case there is a + stall on a non-blocking write destination. */ +local int gz_zero(gz_statep state) { + int first, ret; unsigned n; z_streamp strm = &(state->strm); @@ -149,29 +160,34 @@ local int gz_zero(gz_statep state, z_off64_t len) { if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) return -1; - /* compress len zeros (len guaranteed > 0) */ + /* compress state->skip zeros */ first = 1; - while (len) { - n = GT_OFF(state->size) || (z_off64_t)state->size > len ? - (unsigned)len : state->size; + do { + n = GT_OFF(state->size) || (z_off64_t)state->size > state->skip ? + (unsigned)state->skip : state->size; if (first) { memset(state->in, 0, n); first = 0; } strm->avail_in = n; strm->next_in = state->in; + ret = gz_comp(state, Z_NO_FLUSH); + n -= strm->avail_in; state->x.pos += n; - if (gz_comp(state, Z_NO_FLUSH) == -1) + state->skip -= n; + if (ret == -1) return -1; - len -= n; - } + } while (state->skip); return 0; } /* Write len bytes from buf to file. Return the number of bytes written. If - the returned value is less than len, then there was an error. */ + the returned value is less than len, then there was an error. If the error + was a non-blocking stall, then the number of bytes consumed is returned. + For any other error, 0 is returned. */ local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) { z_size_t put = len; + int ret; /* if len is zero, avoid unnecessary operations */ if (len == 0) @@ -182,16 +198,13 @@ local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) { return 0; /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return 0; - } + if (state->skip && gz_zero(state) == -1) + return 0; /* for small len, copy to input buffer, otherwise compress directly */ if (len < state->size) { /* copy to input buffer, compress when full */ - do { + for (;;) { unsigned have, copy; if (state->strm.avail_in == 0) @@ -206,9 +219,11 @@ local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) { state->x.pos += copy; buf = (const char *)buf + copy; len -= copy; - if (len && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - } while (len); + if (len == 0) + break; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return state->again ? put - len : 0; + } } else { /* consume whatever's left in the input buffer */ @@ -219,13 +234,16 @@ local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) { state->strm.next_in = (z_const Bytef *)buf; do { unsigned n = (unsigned)-1; + if (n > len) n = (unsigned)len; state->strm.avail_in = n; + ret = gz_comp(state, Z_NO_FLUSH); + n -= state->strm.avail_in; state->x.pos += n; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return 0; len -= n; + if (ret == -1) + return state->again ? put - len : 0; } while (len); } @@ -242,9 +260,10 @@ int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len) { return 0; state = (gz_statep)file; - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) + /* check that we're writing and that there's no (serious) error */ + if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again)) return 0; + gz_error(state, Z_OK, NULL); /* since an int is returned, make sure len fits in one, otherwise return with an error (this avoids a flaw in the interface) */ @@ -268,9 +287,10 @@ z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, z_size_t nitems, return 0; state = (gz_statep)file; - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) + /* check that we're writing and that there's no (serious) error */ + if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again)) return 0; + gz_error(state, Z_OK, NULL); /* compute bytes to read -- error on overflow */ len = nitems * size; @@ -296,16 +316,14 @@ int ZEXPORT gzputc(gzFile file, int c) { state = (gz_statep)file; strm = &(state->strm); - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) + /* check that we're writing and that there's no (serious) error */ + if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again)) return -1; + gz_error(state, Z_OK, NULL); /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return -1; - } + if (state->skip && gz_zero(state) == -1) + return -1; /* try writing to input buffer for speed (state->size == 0 if buffer not initialized) */ @@ -338,9 +356,10 @@ int ZEXPORT gzputs(gzFile file, const char *s) { return -1; state = (gz_statep)file; - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) + /* check that we're writing and that there's no (serious) error */ + if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again)) return -1; + gz_error(state, Z_OK, NULL); /* write string */ len = strlen(s); @@ -349,16 +368,47 @@ int ZEXPORT gzputs(gzFile file, const char *s) { return -1; } put = gz_write(state, s, len); - return put < len ? -1 : (int)len; + return len && put == 0 ? -1 : (int)put; +} + +#if (((!defined(STDC) && !defined(Z_HAVE_STDARG_H)) || !defined(NO_vsnprintf)) && \ + (defined(STDC) || defined(Z_HAVE_STDARG_H) || !defined(NO_snprintf))) || \ + defined(ZLIB_INSECURE) +/* If the second half of the input buffer is occupied, write out the contents. + If there is any input remaining due to a non-blocking stall on write, move + it to the start of the buffer. Return true if this did not open up the + second half of the buffer. state->err should be checked after this to + handle a gz_comp() error. */ +local int gz_vacate(gz_statep state) { + z_streamp strm; + + strm = &(state->strm); + if (strm->next_in + strm->avail_in <= state->in + state->size) + return 0; + (void)gz_comp(state, Z_NO_FLUSH); + if (strm->avail_in == 0) { + strm->next_in = state->in; + return 0; + } + memmove(state->in, strm->next_in, strm->avail_in); + strm->next_in = state->in; + return strm->avail_in > state->size; } +#endif #if defined(STDC) || defined(Z_HAVE_STDARG_H) #include /* -- see zlib.h -- */ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) { - int len; - unsigned left; +#if defined(NO_vsnprintf) && !defined(ZLIB_INSECURE) +#warning "vsnprintf() not available -- gzprintf() stub returns Z_STREAM_ERROR" +#warning "you can recompile with ZLIB_INSECURE defined to use vsprintf()" + /* prevent use of insecure vsprintf(), unless purposefully requested */ + (void)file, (void)format, (void)va; + return Z_STREAM_ERROR; +#else + int len, ret; char *next; gz_statep state; z_streamp strm; @@ -369,24 +419,34 @@ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) { state = (gz_statep)file; strm = &(state->strm); - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) + /* check that we're writing and that there's no (serious) error */ + if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again)) return Z_STREAM_ERROR; + gz_error(state, Z_OK, NULL); /* make sure we have some buffer space */ if (state->size == 0 && gz_init(state) == -1) return state->err; /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return state->err; - } + if (state->skip && gz_zero(state) == -1) + return state->err; /* do the printf() into the input buffer, put length in len -- the input - buffer is double-sized just for this function, so there is guaranteed to - be state->size bytes available after the current contents */ + buffer is double-sized just for this function, so there should be + state->size bytes available after the current contents */ + ret = gz_vacate(state); + if (state->err) { + if (ret && state->again) { + /* There was a non-blocking stall on write, resulting in the part + of the second half of the output buffer being occupied. Return + a Z_BUF_ERROR to let the application know that this gzprintf() + needs to be retried. */ + gz_error(state, Z_BUF_ERROR, "stalled write on gzprintf"); + } + if (!state->again) + return state->err; + } if (strm->avail_in == 0) strm->next_in = state->in; next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in); @@ -412,19 +472,16 @@ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) { if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0) return 0; - /* update buffer and position, compress first half if past that */ + /* update buffer and position */ strm->avail_in += (unsigned)len; state->x.pos += len; - if (strm->avail_in >= state->size) { - left = strm->avail_in - state->size; - strm->avail_in = state->size; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return state->err; - memmove(state->in, state->in + state->size, left); - strm->next_in = state->in; - strm->avail_in = left; - } + + /* write out buffer if more than half is occupied */ + ret = gz_vacate(state); + if (state->err && !state->again) + return state->err; return len; +#endif } int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) { @@ -444,6 +501,17 @@ int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, int a11, int a12, int a13, int a14, int a15, int a16, int a17, int a18, int a19, int a20) { +#if defined(NO_snprintf) && !defined(ZLIB_INSECURE) +#warning "snprintf() not available -- gzprintf() stub returns Z_STREAM_ERROR" +#warning "you can recompile with ZLIB_INSECURE defined to use sprintf()" + /* prevent use of insecure sprintf(), unless purposefully requested */ + (void)file, (void)format, (void)a1, (void)a2, (void)a3, (void)a4, (void)a5, + (void)a6, (void)a7, (void)a8, (void)a9, (void)a10, (void)a11, (void)a12, + (void)a13, (void)a14, (void)a15, (void)a16, (void)a17, (void)a18, + (void)a19, (void)a20; + return Z_STREAM_ERROR; +#else + int ret; unsigned len, left; char *next; gz_statep state; @@ -459,24 +527,34 @@ int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3, if (sizeof(int) != sizeof(void *)) return Z_STREAM_ERROR; - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) + /* check that we're writing and that there's no (serious) error */ + if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again)) return Z_STREAM_ERROR; + gz_error(state, Z_OK, NULL); /* make sure we have some buffer space */ if (state->size == 0 && gz_init(state) == -1) - return state->error; + return state->err; /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return state->error; - } + if (state->skip && gz_zero(state) == -1) + return state->err; /* do the printf() into the input buffer, put length in len -- the input buffer is double-sized just for this function, so there is guaranteed to be state->size bytes available after the current contents */ + ret = gz_vacate(state); + if (state->err) { + if (ret && state->again) { + /* There was a non-blocking stall on write, resulting in the part + of the second half of the output buffer being occupied. Return + a Z_BUF_ERROR to let the application know that this gzprintf() + needs to be retried. */ + gz_error(state, Z_BUF_ERROR, "stalled write on gzprintf"); + } + if (!state->again) + return state->err; + } if (strm->avail_in == 0) strm->next_in = state->in; next = (char *)(strm->next_in + strm->avail_in); @@ -510,16 +588,13 @@ int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3, /* update buffer and position, compress first half if past that */ strm->avail_in += len; state->x.pos += len; - if (strm->avail_in >= state->size) { - left = strm->avail_in - state->size; - strm->avail_in = state->size; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return state->err; - memmove(state->in, state->in + state->size, left); - strm->next_in = state->in; - strm->avail_in = left; - } + + /* write out buffer if more than half is occupied */ + ret = gz_vacate(state); + if (state->err && !state->again) + return state->err; return (int)len; +#endif } #endif @@ -533,20 +608,18 @@ int ZEXPORT gzflush(gzFile file, int flush) { return Z_STREAM_ERROR; state = (gz_statep)file; - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) + /* check that we're writing and that there's no (serious) error */ + if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again)) return Z_STREAM_ERROR; + gz_error(state, Z_OK, NULL); /* check flush parameter */ if (flush < 0 || flush > Z_FINISH) return Z_STREAM_ERROR; /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return state->err; - } + if (state->skip && gz_zero(state) == -1) + return state->err; /* compress remaining data with requested flush */ (void)gz_comp(state, flush); @@ -564,20 +637,19 @@ int ZEXPORT gzsetparams(gzFile file, int level, int strategy) { state = (gz_statep)file; strm = &(state->strm); - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK || state->direct) + /* check that we're compressing and that there's no (serious) error */ + if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again) || + state->direct) return Z_STREAM_ERROR; + gz_error(state, Z_OK, NULL); /* if no change is requested, then do nothing */ if (level == state->level && strategy == state->strategy) return Z_OK; /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return state->err; - } + if (state->skip && gz_zero(state) == -1) + return state->err; /* change compression parameters for subsequent input */ if (state->size) { @@ -606,11 +678,8 @@ int ZEXPORT gzclose_w(gzFile file) { return Z_STREAM_ERROR; /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - ret = state->err; - } + if (state->skip && gz_zero(state) == -1) + ret = state->err; /* flush, free memory, and close file */ if (gz_comp(state, Z_FINISH) == -1) diff --git a/deps/zlib/infback.c b/deps/zlib/infback.c index 9bfc30fe555f57..7ffb7b04486409 100644 --- a/deps/zlib/infback.c +++ b/deps/zlib/infback.c @@ -1,5 +1,5 @@ /* infback.c -- inflate using a call-back interface - * Copyright (C) 1995-2022 Mark Adler + * Copyright (C) 1995-2026 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -46,7 +46,7 @@ int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, #ifdef Z_SOLO return Z_STREAM_ERROR; #else - strm->zfree = zcfree; + strm->zfree = zcfree; #endif state = (struct inflate_state FAR *)ZALLOC(strm, 1, sizeof(struct inflate_state)); @@ -63,57 +63,6 @@ int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, return Z_OK; } -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(struct inflate_state FAR *state) { -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - /* Macros for inflateBack(): */ /* Load returned state from inflate_fast() */ @@ -293,7 +242,7 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, state->mode = STORED; break; case 1: /* fixed block */ - fixedtables(state); + inflate_fixed(state); Tracev((stderr, "inflate: fixed codes block%s\n", state->last ? " (last)" : "")); state->mode = LEN; /* decode codes */ @@ -303,8 +252,8 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, state->last ? " (last)" : "")); state->mode = TABLE; break; - case 3: - strm->msg = (char *)"invalid block type"; + default: + strm->msg = (z_const char *)"invalid block type"; state->mode = BAD; } DROPBITS(2); @@ -315,7 +264,7 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, BYTEBITS(); /* go to byte boundary */ NEEDBITS(32); if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; + strm->msg = (z_const char *)"invalid stored block lengths"; state->mode = BAD; break; } @@ -353,7 +302,8 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, DROPBITS(4); #ifndef PKZIP_BUG_WORKAROUND if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; + strm->msg = (z_const char *) + "too many length or distance symbols"; state->mode = BAD; break; } @@ -375,7 +325,7 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, ret = inflate_table(CODES, state->lens, 19, &(state->next), &(state->lenbits), state->work); if (ret) { - strm->msg = (char *)"invalid code lengths set"; + strm->msg = (z_const char *)"invalid code lengths set"; state->mode = BAD; break; } @@ -398,7 +348,8 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, NEEDBITS(here.bits + 2); DROPBITS(here.bits); if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; + strm->msg = (z_const char *) + "invalid bit length repeat"; state->mode = BAD; break; } @@ -421,7 +372,8 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, DROPBITS(7); } if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; + strm->msg = (z_const char *) + "invalid bit length repeat"; state->mode = BAD; break; } @@ -435,7 +387,8 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, /* check for end-of-block code (better have one) */ if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; + strm->msg = (z_const char *) + "invalid code -- missing end-of-block"; state->mode = BAD; break; } @@ -449,7 +402,7 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), &(state->lenbits), state->work); if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; + strm->msg = (z_const char *)"invalid literal/lengths set"; state->mode = BAD; break; } @@ -458,7 +411,7 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, &(state->next), &(state->distbits), state->work); if (ret) { - strm->msg = (char *)"invalid distances set"; + strm->msg = (z_const char *)"invalid distances set"; state->mode = BAD; break; } @@ -471,8 +424,6 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, if (have >= INFLATE_FAST_MIN_INPUT && left >= INFLATE_FAST_MIN_OUTPUT) { RESTORE(); - if (state->whave < state->wsize) - state->whave = state->wsize - left; inflate_fast(strm, state->wsize); LOAD(); break; @@ -518,7 +469,7 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, /* invalid code */ if (here.op & 64) { - strm->msg = (char *)"invalid literal/length code"; + strm->msg = (z_const char *)"invalid literal/length code"; state->mode = BAD; break; } @@ -550,7 +501,7 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, } DROPBITS(here.bits); if (here.op & 64) { - strm->msg = (char *)"invalid distance code"; + strm->msg = (z_const char *)"invalid distance code"; state->mode = BAD; break; } @@ -565,7 +516,7 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, } if (state->offset > state->wsize - (state->whave < state->wsize ? left : 0)) { - strm->msg = (char *)"invalid distance too far back"; + strm->msg = (z_const char *)"invalid distance too far back"; state->mode = BAD; break; } diff --git a/deps/zlib/inffast.c b/deps/zlib/inffast.c index 52ed8ca2df612e..58fc5afc054696 100644 --- a/deps/zlib/inffast.c +++ b/deps/zlib/inffast.c @@ -1,5 +1,5 @@ /* inffast.c -- fast decoding - * Copyright (C) 1995-2017 Mark Adler + * Copyright (C) 1995-2026 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -159,7 +159,8 @@ void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) { dist += (unsigned)hold & ((1U << op) - 1); #ifdef INFLATE_STRICT if (dist > dmax) { - strm->msg = (char *)"invalid distance too far back"; + strm->msg = (z_const char *) + "invalid distance too far back"; state->mode = BAD; break; } @@ -172,8 +173,8 @@ void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) { op = dist - op; /* distance back in window */ if (op > whave) { if (state->sane) { - strm->msg = - (char *)"invalid distance too far back"; + strm->msg = (z_const char *) + "invalid distance too far back"; state->mode = BAD; break; } @@ -269,7 +270,7 @@ void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) { goto dodist; } else { - strm->msg = (char *)"invalid distance code"; + strm->msg = (z_const char *)"invalid distance code"; state->mode = BAD; break; } @@ -284,7 +285,7 @@ void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) { break; } else { - strm->msg = (char *)"invalid literal/length code"; + strm->msg = (z_const char *)"invalid literal/length code"; state->mode = BAD; break; } diff --git a/deps/zlib/inffixed.h b/deps/zlib/inffixed.h index d6283277694802..05ce88e4ff5cd4 100644 --- a/deps/zlib/inffixed.h +++ b/deps/zlib/inffixed.h @@ -1,94 +1,94 @@ - /* inffixed.h -- table for decoding fixed codes - * Generated automatically by makefixed(). - */ +/* inffixed.h -- table for decoding fixed codes + * Generated automatically by makefixed(). + */ - /* WARNING: this file should *not* be used by applications. - It is part of the implementation of this library and is - subject to change. Applications should only use zlib.h. - */ +/* WARNING: this file should *not* be used by applications. + It is part of the implementation of this library and is + subject to change. Applications should only use zlib.h. + */ - static const code lenfix[512] = { - {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, - {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, - {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, - {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, - {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, - {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, - {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, - {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, - {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, - {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, - {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, - {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, - {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, - {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, - {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, - {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, - {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, - {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, - {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, - {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, - {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, - {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, - {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, - {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, - {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, - {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, - {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, - {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, - {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, - {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, - {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, - {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, - {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, - {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, - {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, - {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, - {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, - {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, - {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, - {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, - {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, - {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, - {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, - {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, - {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, - {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, - {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, - {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, - {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, - {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, - {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, - {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, - {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, - {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, - {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, - {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, - {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, - {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, - {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, - {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, - {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, - {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, - {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, - {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, - {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, - {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, - {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, - {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, - {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, - {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, - {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, - {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, - {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, - {0,9,255} - }; +static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, + {0,9,255} +}; - static const code distfix[32] = { - {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, - {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, - {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, - {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, - {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, - {22,5,193},{64,5,0} - }; +static const code distfix[32] = { + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, + {22,5,193},{64,5,0} +}; diff --git a/deps/zlib/inflate.c b/deps/zlib/inflate.c index 0990ae7bf9a8d2..0742ce10ed94a6 100644 --- a/deps/zlib/inflate.c +++ b/deps/zlib/inflate.c @@ -1,5 +1,5 @@ /* inflate.c -- zlib decompression - * Copyright (C) 1995-2022 Mark Adler + * Copyright (C) 1995-2026 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -85,12 +85,6 @@ #include "inflate.h" #include "inffast.h" -#ifdef MAKEFIXED -# ifndef BUILDFIXED -# define BUILDFIXED -# endif -#endif - local int inflateStateCheck(z_streamp strm) { struct inflate_state FAR *state; if (strm == Z_NULL || @@ -110,6 +104,7 @@ int ZEXPORT inflateResetKeep(z_streamp strm) { state = (struct inflate_state FAR *)strm->state; strm->total_in = strm->total_out = state->total = 0; strm->msg = Z_NULL; + strm->data_type = 0; if (state->wrap) /* to support ill-conceived Java test suite */ strm->adler = state->wrap & 1; state->mode = HEAD; @@ -202,6 +197,7 @@ int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, state = (struct inflate_state FAR *) ZALLOC(strm, 1, sizeof(struct inflate_state)); if (state == Z_NULL) return Z_MEM_ERROR; + zmemzero(state, sizeof(struct inflate_state)); Tracev((stderr, "inflate: allocated\n")); strm->state = (struct internal_state FAR *)state; state->strm = strm; @@ -235,123 +231,11 @@ int ZEXPORT inflatePrime(z_streamp strm, int bits, int value) { } if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR; value &= (1L << bits) - 1; - state->hold += (unsigned)value << state->bits; + state->hold += (unsigned long)value << state->bits; state->bits += (uInt)bits; return Z_OK; } -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(struct inflate_state FAR *state) { -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -#ifdef MAKEFIXED -#include - -/* - Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also - defines BUILDFIXED, so the tables are built on the fly. makefixed() writes - those tables to stdout, which would be piped to inffixed.h. A small program - can simply call makefixed to do this: - - void makefixed(void); - - int main(void) - { - makefixed(); - return 0; - } - - Then that can be linked with zlib built with MAKEFIXED defined and run: - - a.out > inffixed.h - */ -void makefixed(void) -{ - unsigned low, size; - struct inflate_state state; - - fixedtables(&state); - puts(" /* inffixed.h -- table for decoding fixed codes"); - puts(" * Generated automatically by makefixed()."); - puts(" */"); - puts(""); - puts(" /* WARNING: this file should *not* be used by applications."); - puts(" It is part of the implementation of this library and is"); - puts(" subject to change. Applications should only use zlib.h."); - puts(" */"); - puts(""); - size = 1U << 9; - printf(" static const code lenfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 7) == 0) printf("\n "); - printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, - state.lencode[low].bits, state.lencode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); - size = 1U << 5; - printf("\n static const code distfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 6) == 0) printf("\n "); - printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, - state.distcode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); -} -#endif /* MAKEFIXED */ - /* Update the window with the last wsize (normally 32K) bytes written before returning. If window does not exist yet, create it. This is only called @@ -643,12 +527,12 @@ int ZEXPORT inflate(z_streamp strm, int flush) { if ( #endif ((BITS(8) << 8) + (hold >> 8)) % 31) { - strm->msg = (char *)"incorrect header check"; + strm->msg = (z_const char *)"incorrect header check"; state->mode = BAD; break; } if (BITS(4) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; + strm->msg = (z_const char *)"unknown compression method"; state->mode = BAD; break; } @@ -657,7 +541,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) { if (state->wbits == 0) state->wbits = len; if (len > 15 || len > state->wbits) { - strm->msg = (char *)"invalid window size"; + strm->msg = (z_const char *)"invalid window size"; state->mode = BAD; break; } @@ -673,12 +557,12 @@ int ZEXPORT inflate(z_streamp strm, int flush) { NEEDBITS(16); state->flags = (int)(hold); if ((state->flags & 0xff) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; + strm->msg = (z_const char *)"unknown compression method"; state->mode = BAD; break; } if (state->flags & 0xe000) { - strm->msg = (char *)"unknown header flags set"; + strm->msg = (z_const char *)"unknown header flags set"; state->mode = BAD; break; } @@ -794,7 +678,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) { if (state->flags & 0x0200) { NEEDBITS(16); if ((state->wrap & 4) && hold != (state->check & 0xffff)) { - strm->msg = (char *)"header crc mismatch"; + strm->msg = (z_const char *)"header crc mismatch"; state->mode = BAD; break; } @@ -841,7 +725,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) { state->mode = STORED; break; case 1: /* fixed block */ - fixedtables(state); + inflate_fixed(state); Tracev((stderr, "inflate: fixed codes block%s\n", state->last ? " (last)" : "")); state->mode = LEN_; /* decode codes */ @@ -855,8 +739,8 @@ int ZEXPORT inflate(z_streamp strm, int flush) { state->last ? " (last)" : "")); state->mode = TABLE; break; - case 3: - strm->msg = (char *)"invalid block type"; + default: + strm->msg = (z_const char *)"invalid block type"; state->mode = BAD; } DROPBITS(2); @@ -865,7 +749,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) { BYTEBITS(); /* go to byte boundary */ NEEDBITS(32); if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; + strm->msg = (z_const char *)"invalid stored block lengths"; state->mode = BAD; break; } @@ -906,7 +790,8 @@ int ZEXPORT inflate(z_streamp strm, int flush) { DROPBITS(4); #ifndef PKZIP_BUG_WORKAROUND if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; + strm->msg = (z_const char *) + "too many length or distance symbols"; state->mode = BAD; break; } @@ -924,12 +809,12 @@ int ZEXPORT inflate(z_streamp strm, int flush) { while (state->have < 19) state->lens[order[state->have++]] = 0; state->next = state->codes; - state->lencode = (const code FAR *)(state->next); + state->lencode = state->distcode = (const code FAR *)(state->next); state->lenbits = 7; ret = inflate_table(CODES, state->lens, 19, &(state->next), &(state->lenbits), state->work); if (ret) { - strm->msg = (char *)"invalid code lengths set"; + strm->msg = (z_const char *)"invalid code lengths set"; state->mode = BAD; break; } @@ -953,7 +838,8 @@ int ZEXPORT inflate(z_streamp strm, int flush) { NEEDBITS(here.bits + 2); DROPBITS(here.bits); if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; + strm->msg = (z_const char *) + "invalid bit length repeat"; state->mode = BAD; break; } @@ -976,7 +862,8 @@ int ZEXPORT inflate(z_streamp strm, int flush) { DROPBITS(7); } if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; + strm->msg = (z_const char *) + "invalid bit length repeat"; state->mode = BAD; break; } @@ -990,7 +877,8 @@ int ZEXPORT inflate(z_streamp strm, int flush) { /* check for end-of-block code (better have one) */ if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; + strm->msg = (z_const char *) + "invalid code -- missing end-of-block"; state->mode = BAD; break; } @@ -1004,7 +892,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) { ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), &(state->lenbits), state->work); if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; + strm->msg = (z_const char *)"invalid literal/lengths set"; state->mode = BAD; break; } @@ -1013,7 +901,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) { ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, &(state->next), &(state->distbits), state->work); if (ret) { - strm->msg = (char *)"invalid distances set"; + strm->msg = (z_const char *)"invalid distances set"; state->mode = BAD; break; } @@ -1068,7 +956,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) { break; } if (here.op & 64) { - strm->msg = (char *)"invalid literal/length code"; + strm->msg = (z_const char *)"invalid literal/length code"; state->mode = BAD; break; } @@ -1106,7 +994,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) { DROPBITS(here.bits); state->back += here.bits; if (here.op & 64) { - strm->msg = (char *)"invalid distance code"; + strm->msg = (z_const char *)"invalid distance code"; state->mode = BAD; break; } @@ -1123,7 +1011,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) { } #ifdef INFLATE_STRICT if (state->offset > state->dmax) { - strm->msg = (char *)"invalid distance too far back"; + strm->msg = (z_const char *)"invalid distance too far back"; state->mode = BAD; break; } @@ -1138,7 +1026,8 @@ int ZEXPORT inflate(z_streamp strm, int flush) { copy = state->offset - copy; if (copy > state->whave) { if (state->sane) { - strm->msg = (char *)"invalid distance too far back"; + strm->msg = (z_const char *) + "invalid distance too far back"; state->mode = BAD; break; } @@ -1197,7 +1086,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) { state->flags ? hold : #endif ZSWAP32(hold)) != state->check) { - strm->msg = (char *)"incorrect data check"; + strm->msg = (z_const char *)"incorrect data check"; state->mode = BAD; break; } @@ -1211,7 +1100,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) { if (state->wrap && state->flags) { NEEDBITS(32); if ((state->wrap & 4) && hold != (state->total & 0xffffffff)) { - strm->msg = (char *)"incorrect length check"; + strm->msg = (z_const char *)"incorrect length check"; state->mode = BAD; break; } @@ -1442,7 +1331,6 @@ int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) { struct inflate_state FAR *state; struct inflate_state FAR *copy; unsigned char FAR *window; - unsigned wsize; /* check input */ if (inflateStateCheck(source) || dest == Z_NULL) @@ -1453,6 +1341,7 @@ int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) { copy = (struct inflate_state FAR *) ZALLOC(source, 1, sizeof(struct inflate_state)); if (copy == Z_NULL) return Z_MEM_ERROR; + zmemzero(copy, sizeof(struct inflate_state)); window = Z_NULL; if (state->window != Z_NULL) { window = (unsigned char FAR *) @@ -1464,8 +1353,8 @@ int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) { } /* copy state */ - zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); - zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); + zmemcpy(dest, source, sizeof(z_stream)); + zmemcpy(copy, state, sizeof(struct inflate_state)); copy->strm = dest; if (state->lencode >= state->codes && state->lencode <= state->codes + ENOUGH - 1) { @@ -1473,10 +1362,8 @@ int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) { copy->distcode = copy->codes + (state->distcode - state->codes); } copy->next = copy->codes + (state->next - state->codes); - if (window != Z_NULL) { - wsize = 1U << state->wbits; - zmemcpy(window, state->window, wsize); - } + if (window != Z_NULL) + zmemcpy(window, state->window, state->whave); copy->window = window; dest->state = (struct internal_state FAR *)copy; return Z_OK; diff --git a/deps/zlib/inflate.h b/deps/zlib/inflate.h index f127b6b1fa5f7d..f758e0dcc18dc1 100644 --- a/deps/zlib/inflate.h +++ b/deps/zlib/inflate.h @@ -100,7 +100,7 @@ struct inflate_state { unsigned char FAR *window; /* allocated sliding window, if needed */ /* bit accumulator */ unsigned long hold; /* input bit accumulator */ - unsigned bits; /* number of bits in "in" */ + unsigned bits; /* number of bits in hold */ /* for string and stored block copying */ unsigned length; /* literal or length of data to copy */ unsigned offset; /* distance back to copy string from */ diff --git a/deps/zlib/inftrees.c b/deps/zlib/inftrees.c index 98cfe164458c40..99d8d773075055 100644 --- a/deps/zlib/inftrees.c +++ b/deps/zlib/inftrees.c @@ -1,15 +1,29 @@ /* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2024 Mark Adler + * Copyright (C) 1995-2026 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ +#ifdef MAKEFIXED +# ifndef BUILDFIXED +# define BUILDFIXED +# endif +#endif +#ifdef BUILDFIXED +# define Z_ONCE +#endif + #include "zutil.h" #include "inftrees.h" +#include "inflate.h" + +#ifndef NULL +# define NULL 0 +#endif #define MAXBITS 15 const char inflate_copyright[] = - " inflate 1.3.1 Copyright 1995-2024 Mark Adler "; + " inflate 1.3.2.1 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 @@ -47,9 +61,9 @@ int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, unsigned mask; /* mask for low root bits */ code here; /* table entry for duplication */ code FAR *next; /* next available space in table */ - const unsigned short FAR *base; /* base value table to use */ - const unsigned short FAR *extra; /* extra bits table to use */ - unsigned match; /* use base and extra for symbol >= match */ + const unsigned short FAR *base = NULL; /* base value table to use */ + const unsigned short FAR *extra = NULL; /* extra bits table to use */ + unsigned match = 0; /* use base and extra for symbol >= match */ unsigned short count[MAXBITS+1]; /* number of codes of each length */ unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ static const unsigned short lbase[31] = { /* Length codes 257..285 base */ @@ -57,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, 203, 77}; + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 68, 193}; 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, @@ -175,7 +189,6 @@ int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, /* set up for code type */ switch (type) { case CODES: - base = extra = work; /* dummy value--not used */ match = 20; break; case LENS: @@ -183,10 +196,9 @@ int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, extra = lext; match = 257; break; - default: /* DISTS */ + case DISTS: base = dbase; extra = dext; - match = 0; } /* initialize state for loop */ @@ -297,3 +309,116 @@ int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, *bits = root; return 0; } + +#ifdef BUILDFIXED +/* + If this is compiled with BUILDFIXED defined, and if inflate will be used in + multiple threads, and if atomics are not available, then inflate() must be + called with a fixed block (e.g. 0x03 0x00) to initialize the tables and must + return before any other threads are allowed to call inflate. + */ + +static code *lenfix, *distfix; +static code fixed[544]; + +/* State for z_once(). */ +local z_once_t built = Z_ONCE_INIT; + +local void buildtables(void) { + unsigned sym, bits; + static code *next; + unsigned short lens[288], work[288]; + + /* literal/length table */ + sym = 0; + while (sym < 144) lens[sym++] = 8; + while (sym < 256) lens[sym++] = 9; + while (sym < 280) lens[sym++] = 7; + while (sym < 288) lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, lens, 288, &(next), &(bits), work); + + /* distance table */ + sym = 0; + while (sym < 32) lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, lens, 32, &(next), &(bits), work); +} +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications if atomics are not available, as it will + not be thread-safe. + */ +void inflate_fixed(struct inflate_state FAR *state) { +#ifdef BUILDFIXED + z_once(&built, buildtables); +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +#ifdef MAKEFIXED +#include + +/* + Write out the inffixed.h that will be #include'd above. Defining MAKEFIXED + also defines BUILDFIXED, so the tables are built on the fly. main() writes + those tables to stdout, which would directed to inffixed.h. Compile this + along with zutil.c: + + cc -DMAKEFIXED -o fix inftrees.c zutil.c + ./fix > inffixed.h + */ +int main(void) { + unsigned low, size; + struct inflate_state state; + + inflate_fixed(&state); + puts("/* inffixed.h -- table for decoding fixed codes"); + puts(" * Generated automatically by makefixed()."); + puts(" */"); + puts(""); + puts("/* WARNING: this file should *not* be used by applications."); + puts(" It is part of the implementation of this library and is"); + puts(" subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf("static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 7) == 0) printf("\n "); + printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, + state.lencode[low].bits, state.lencode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n};"); + size = 1U << 5; + printf("\nstatic const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) printf("\n "); + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, + state.distcode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n};"); + return 0; +} +#endif /* MAKEFIXED */ diff --git a/deps/zlib/inftrees.h b/deps/zlib/inftrees.h index 6e7f0fa2a8afde..c572f49d555fd9 100644 --- a/deps/zlib/inftrees.h +++ b/deps/zlib/inftrees.h @@ -1,5 +1,5 @@ /* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995-2005, 2010 Mark Adler + * Copyright (C) 1995-2026 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -60,3 +60,5 @@ typedef enum { int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, unsigned codes, code FAR * FAR *table, unsigned FAR *bits, unsigned short FAR *work); +struct inflate_state; +void ZLIB_INTERNAL inflate_fixed(struct inflate_state FAR *state); diff --git a/deps/zlib/patches/0000-build.patch b/deps/zlib/patches/0000-build.patch index 1861194dd50cd3..0f2b83409bffec 100644 --- a/deps/zlib/patches/0000-build.patch +++ b/deps/zlib/patches/0000-build.patch @@ -6,8 +6,8 @@ index 782d32469ae5d..a38881dca90a2 100644 #define _CRT_SECURE_NO_WARNINGS #endif --#if defined(__APPLE__) || defined(IOAPI_NO_64) || defined(__HAIKU__) || defined(MINIZIP_FOPEN_NO_64) -+#if defined(__APPLE__) || defined(__Fuchsia__) || defined(IOAPI_NO_64) || defined(__HAIKU__) || defined(MINIZIP_FOPEN_NO_64) +-#if defined(__APPLE__) || defined(IOAPI_NO_64) || defined(__HAIKU__) || defined(MINIZIP_FOPEN_NO_64) || (defined(__ANDROID_API__) && __ANDROID_API__ < 24) ++#if defined(__APPLE__) || defined(__Fuchsia__) || defined(IOAPI_NO_64) || defined(__HAIKU__) || defined(MINIZIP_FOPEN_NO_64) || (defined(__ANDROID_API__) && __ANDROID_API__ < 24) // In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions #define FOPEN_FUNC(filename, mode) fopen(filename, mode) #define FTELLO_FUNC(stream) ftello(stream) @@ -15,7 +15,7 @@ diff --git a/contrib/minizip/iowin32.c b/contrib/minizip/iowin32.c index 08536e94b8a28..bbd7773e67146 100644 --- a/contrib/minizip/iowin32.c +++ b/contrib/minizip/iowin32.c -@@ -25,7 +25,12 @@ +@@ -24,7 +24,12 @@ #define INVALID_SET_FILE_POINTER ((DWORD)-1) #endif @@ -25,7 +25,7 @@ index 08536e94b8a28..bbd7773e67146 100644 +#endif +#if _WIN32_WINNT >= _WIN32_WINNT_WIN8 - // see Include/shared/winapifamily.h in the Windows Kit + /* see Include/shared/winapifamily.h in the Windows Kit */ #if defined(WINAPI_FAMILY_PARTITION) && (!(defined(IOWIN32_USING_WINRT_API))) @@ -37,6 +42,7 @@ diff --git a/deps/zlib/patches/0004-fix-uwp.patch b/deps/zlib/patches/0004-fix-uwp.patch index edef10a2025678..ba3173b6ec4dee 100644 --- a/deps/zlib/patches/0004-fix-uwp.patch +++ b/deps/zlib/patches/0004-fix-uwp.patch @@ -2,12 +2,12 @@ diff --git a/third_party/zlib/contrib/minizip/iowin32.c b/third_party/zlib/contr index bbd7773e67146..3f6867fd7e40b 100644 --- a/third_party/zlib/contrib/minizip/iowin32.c +++ b/third_party/zlib/contrib/minizip/iowin32.c -@@ -30,19 +30,12 @@ +@@ -29,19 +29,12 @@ #define _WIN32_WINNT 0x601 #endif - + -#if _WIN32_WINNT >= _WIN32_WINNT_WIN8 --// see Include/shared/winapifamily.h in the Windows Kit +-/* see Include/shared/winapifamily.h in the Windows Kit */ -#if defined(WINAPI_FAMILY_PARTITION) && (!(defined(IOWIN32_USING_WINRT_API))) - -#if !defined(WINAPI_FAMILY_ONE_PARTITION) @@ -22,6 +22,6 @@ index bbd7773e67146..3f6867fd7e40b 100644 #endif #endif -#endif - + typedef struct { diff --git a/deps/zlib/patches/0008-minizip-zip-unzip-tools.patch b/deps/zlib/patches/0008-minizip-zip-unzip-tools.patch index a359e0f72b0f97..73a3fa3e3cdf2b 100644 --- a/deps/zlib/patches/0008-minizip-zip-unzip-tools.patch +++ b/deps/zlib/patches/0008-minizip-zip-unzip-tools.patch @@ -9,11 +9,11 @@ Subject: [PATCH] Build minizip zip and unzip tools 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/third_party/zlib/contrib/minizip/miniunz.c b/third_party/zlib/contrib/minizip/miniunz.c -index 616c30325e07c..f4ad16bdd377b 100644 +index cd577ea03ad55..e8a5c726c4c72 100644 --- a/third_party/zlib/contrib/minizip/miniunz.c +++ b/third_party/zlib/contrib/minizip/miniunz.c -@@ -12,7 +12,7 @@ - Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) +@@ -11,7 +11,7 @@ + Copyright (C) 2009-2010 Mathias Svensson ( https://result42.com ) */ -#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__)) @@ -21,7 +21,7 @@ index 616c30325e07c..f4ad16bdd377b 100644 #ifndef __USE_FILE_OFFSET64 #define __USE_FILE_OFFSET64 #endif -@@ -27,7 +27,7 @@ +@@ -26,7 +26,7 @@ #endif #endif @@ -30,7 +30,7 @@ index 616c30325e07c..f4ad16bdd377b 100644 // In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions #define FOPEN_FUNC(filename, mode) fopen(filename, mode) #define FTELLO_FUNC(stream) ftello(stream) -@@ -97,7 +97,7 @@ static void change_file_date(const char *filename, uLong dosdate, tm_unz tmu_dat +@@ -96,7 +96,7 @@ static void change_file_date(const char *filename, uLong dosdate, tm_unz tmu_dat LocalFileTimeToFileTime(&ftLocal,&ftm); SetFileTime(hFile,&ftm,&ftLastAcc,&ftm); CloseHandle(hFile); @@ -39,7 +39,7 @@ index 616c30325e07c..f4ad16bdd377b 100644 (void)dosdate; struct utimbuf ut; struct tm newdate; -@@ -129,7 +129,7 @@ static int mymkdir(const char* dirname) { +@@ -128,7 +128,7 @@ static int mymkdir(const char* dirname) { int ret=0; #ifdef _WIN32 ret = _mkdir(dirname); @@ -49,11 +49,11 @@ index 616c30325e07c..f4ad16bdd377b 100644 #else (void)dirname; diff --git a/third_party/zlib/contrib/minizip/minizip.c b/third_party/zlib/contrib/minizip/minizip.c -index a44e36a01869d..53fdd363e6222 100644 +index f68bea1daab2b..91d051a38bee3 100644 --- a/third_party/zlib/contrib/minizip/minizip.c +++ b/third_party/zlib/contrib/minizip/minizip.c -@@ -12,8 +12,7 @@ - Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) +@@ -11,8 +11,7 @@ + Copyright (C) 2009-2010 Mathias Svensson ( https://result42.com ) */ - @@ -62,7 +62,7 @@ index a44e36a01869d..53fdd363e6222 100644 #ifndef __USE_FILE_OFFSET64 #define __USE_FILE_OFFSET64 #endif -@@ -28,7 +27,7 @@ +@@ -27,7 +26,7 @@ #endif #endif @@ -71,7 +71,7 @@ index a44e36a01869d..53fdd363e6222 100644 // In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions #define FOPEN_FUNC(filename, mode) fopen(filename, mode) #define FTELLO_FUNC(stream) ftello(stream) -@@ -96,7 +95,7 @@ static int filetime(const char *f, tm_zip *tmzip, uLong *dt) { +@@ -95,7 +94,7 @@ static int filetime(const char *f, tm_zip *tmzip, uLong *dt) { } return ret; } diff --git a/deps/zlib/patches/0010-cmake-enable-simd.patch b/deps/zlib/patches/0010-cmake-enable-simd.patch deleted file mode 100644 index 3893101b7c6a7e..00000000000000 --- a/deps/zlib/patches/0010-cmake-enable-simd.patch +++ /dev/null @@ -1,96 +0,0 @@ -diff --git a/third_party/zlib/CMakeLists.txt b/third_party/zlib/CMakeLists.txt -index b412dc7feb732..0431278405046 100644 ---- a/third_party/zlib/CMakeLists.txt -+++ b/third_party/zlib/CMakeLists.txt -@@ -1,4 +1,4 @@ --cmake_minimum_required(VERSION 2.4.4) -+cmake_minimum_required(VERSION 3.0) - set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) - - project(zlib C) -@@ -21,6 +21,26 @@ check_include_file(sys/types.h HAVE_SYS_TYPES_H) - check_include_file(stdint.h HAVE_STDINT_H) - check_include_file(stddef.h HAVE_STDDEF_H) - -+option(ENABLE_SIMD_OPTIMIZATIONS "Enable all SIMD optimizations" OFF) -+ -+# TODO(cavalcantii): add support for other OSes (e.g. Android, fuchsia, osx) -+# and architectures (e.g. Arm). -+if (ENABLE_SIMD_OPTIMIZATIONS) -+ add_definitions(-DINFLATE_CHUNK_SIMD_SSE2) -+ add_definitions(-DADLER32_SIMD_SSSE3) -+ add_definitions(-DINFLATE_CHUNK_READ_64LE) -+ add_definitions(-DCRC32_SIMD_SSE42_PCLMUL) -+ add_definitions(-DDEFLATE_SLIDE_HASH_SSE2) -+ add_compile_options(-msse4.2 -mpclmul) -+ # Required by CPU features detection code. -+ add_definitions(-DX86_NOT_WINDOWS) -+ # Apparently some environments (e.g. CentOS) require to explicitly link -+ # with pthread and that is required by the CPU features detection code. -+ find_package (Threads REQUIRED) -+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread") -+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") -+endif() -+ - # - # Check to see if we have large file support - # -@@ -120,10 +140,25 @@ set(ZLIB_SRCS - zutil.c - ) - --if(NOT MINGW) -- set(ZLIB_DLL_SRCS -- win32/zlib1.rc # If present will override custom build rule below. -- ) -+ -+#============================================================================ -+# Update list of source files if optimizations were enabled -+#============================================================================ -+if (ENABLE_SIMD_OPTIMIZATIONS) -+ list(REMOVE_ITEM ZLIB_SRCS inflate.c) -+ -+ list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/adler32_simd.h) -+ list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/optimizations/chunkcopy.h) -+ list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/optimizations/inffast_chunk.h) -+ list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/cpu_features.h) -+ list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/crc32_simd.h) -+ -+ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/adler32_simd.c) -+ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/optimizations/inffast_chunk.c) -+ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/optimizations/inflate.c) -+ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/cpu_features.c) -+ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/crc32_simd.c) -+ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/crc_folding.c) - endif() - - # parse the full version number from zlib.h and include in ZLIB_FULL_VERSION -@@ -191,23 +226,9 @@ if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL ) - endif() - - #============================================================================ --# Example binaries -+# Benchmarker - #============================================================================ -- --add_executable(example test/example.c) --target_link_libraries(example zlib) --add_test(example example) -- --add_executable(minigzip test/minigzip.c) --target_link_libraries(minigzip zlib) -- --if(HAVE_OFF64_T) -- add_executable(example64 test/example.c) -- target_link_libraries(example64 zlib) -- set_target_properties(example64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64") -- add_test(example64 example64) -- -- add_executable(minigzip64 test/minigzip.c) -- target_link_libraries(minigzip64 zlib) -- set_target_properties(minigzip64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64") --endif() -+enable_language(CXX) -+set(CMAKE_CXX_STANDARD 14) # workaround for older compilers (e.g. g++ 5.4). -+add_executable(zlib_bench contrib/bench/zlib_bench.cc) -+target_link_libraries(zlib_bench zlib) diff --git a/deps/zlib/patches/0010-cmake.patch b/deps/zlib/patches/0010-cmake.patch new file mode 100644 index 00000000000000..5036f043c90fd9 --- /dev/null +++ b/deps/zlib/patches/0010-cmake.patch @@ -0,0 +1,256 @@ +diff --git a/third_party/zlib/CMakeLists.txt b/third_party/zlib/CMakeLists.txt +index eef01a8947dd7..b569804ace088 100644 +--- a/third_party/zlib/CMakeLists.txt ++++ b/third_party/zlib/CMakeLists.txt +@@ -71,6 +71,85 @@ if(NOT ZLIB_CONF_WRITTEN) + mark_as_advanced(ZLIB_CONF_WRITTEN) + endif(NOT ZLIB_CONF_WRITTEN) + ++option(ENABLE_SIMD_OPTIMIZATIONS "Enable all SIMD optimizations" OFF) ++option(ENABLE_SIMD_AVX512 "Enable SIMD AXV512 optimizations" OFF) ++option(USE_ZLIB_RABIN_KARP_HASH "Enable bitstream compatibility with canonical zlib" OFF) ++option(ENABLE_INTEL_QAT_COMPRESSION "Enable Intel Quick Assist Technology use for compression" OFF) ++option(BUILD_UNITTESTS "Enable standalone unit tests build" OFF) ++option(BUILD_MINIZIP_BIN "Enable building minzip_bin tool" OFF) ++option(BUILD_ZPIPE "Enable building zpipe tool" OFF) ++option(BUILD_MINIGZIP "Enable building minigzip tool" OFF) ++ ++if (USE_ZLIB_RABIN_KARP_HASH) ++ add_definitions(-DUSE_ZLIB_RABIN_KARP_ROLLING_HASH) ++endif() ++ ++# TODO(cavalcantii): add support for other OSes (e.g. Android, Fuchsia, etc) ++# and architectures (e.g. RISCV). ++if (ENABLE_SIMD_OPTIMIZATIONS) ++ # Apparently some environments (e.g. CentOS) require to explicitly link ++ # with pthread and that is required by the CPU features detection code. ++ find_package (Threads REQUIRED) ++ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread") ++ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") ++ ++ if (CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") ++ add_definitions(-DINFLATE_CHUNK_SIMD_SSE2) ++ add_definitions(-DADLER32_SIMD_SSSE3) ++ add_definitions(-DINFLATE_CHUNK_READ_64LE) ++ add_definitions(-DDEFLATE_CHUNK_WRITE_64LE) ++ add_definitions(-DCRC32_SIMD_SSE42_PCLMUL) ++ if (ENABLE_SIMD_AVX512) ++ add_definitions(-DCRC32_SIMD_AVX512_PCLMUL) ++ add_compile_options(-mvpclmulqdq -msse2 -mavx512f -mpclmul) ++ else() ++ add_compile_options(-msse4.2 -mpclmul) ++ endif() ++ add_definitions(-DDEFLATE_SLIDE_HASH_SSE2) ++ # Required by CPU features detection code. ++ add_definitions(-DX86_NOT_WINDOWS) ++ endif() ++ ++ if ((CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64") OR ++ (CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")) ++ add_definitions(-DINFLATE_CHUNK_SIMD_NEON) ++ add_definitions(-DADLER32_SIMD_NEON) ++ add_definitions(-DINFLATE_CHUNK_READ_64LE) ++ add_definitions(-DDEFLATE_CHUNK_WRITE_64LE) ++ add_definitions(-DCRC32_ARMV8_CRC32) ++ add_definitions(-DDEFLATE_SLIDE_HASH_NEON) ++ # Required by CPU features detection code. ++ if (APPLE) ++ add_definitions(-DARMV8_OS_MACOS) ++ endif() ++ ++ if (UNIX AND NOT APPLE) ++ add_definitions(-DARMV8_OS_LINUX) ++ endif() ++ ++ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a+crc+crypto") ++ endif() ++ ++ if (CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64") ++ add_definitions(-DRISCV_RVV) ++ add_definitions(-DDEFLATE_SLIDE_HASH_RVV) ++ add_definitions(-DADLER32_SIMD_RVV) ++ ++ # chunk_copy is required for READ64 and unconditional decode of literals. ++ add_definitions(-DINFLATE_CHUNK_GENERIC) ++ add_definitions(-DINFLATE_CHUNK_READ_64LE) ++ add_definitions(-DDEFLATE_CHUNK_WRITE_64LE) ++ ++ # TODO(cavalcantii): only missing optimization is SLIDE_HASH, got port it ++ # to RISCV. ++ ++ # Tested with clang-17, unaligned loads are required by read64 & chunk_copy. ++ # TODO(cavalcantii): replace internal clang flags for -munaligned-access ++ # when we have a newer compiler available. ++ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --target=riscv64-unknown-linux-gnu -march=rv64gcv -Xclang -target-feature -Xclang +unaligned-scalar-mem") ++ endif() ++endif() ++ + # + # Check to see if we have large file support + # +@@ -154,6 +233,65 @@ if(WIN32) + set(CMAKE_DEBUG_POSTFIX "d") + endif(WIN32) + ++ ++#============================================================================ ++# Update list of source files if optimizations were enabled ++#============================================================================ ++if (ENABLE_SIMD_OPTIMIZATIONS) ++ if (CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64") ++ message("RISCVV: Add optimizations.") ++ list(REMOVE_ITEM ZLIB_SRCS inflate.c) ++ list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/adler32_simd.h) ++ list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/optimizations/chunkcopy.h) ++ list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/cpu_features.h) ++ ++ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/adler32_simd.c) ++ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/optimizations/inffast_chunk.c) ++ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/optimizations/inflate.c) ++ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/cpu_features.c) ++ else() ++ list(REMOVE_ITEM ZLIB_SRCS inflate.c) ++ ++ list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/adler32_simd.h) ++ list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/optimizations/chunkcopy.h) ++ list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/optimizations/inffast_chunk.h) ++ list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/cpu_features.h) ++ list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/crc32_simd.h) ++ ++ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/adler32_simd.c) ++ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/optimizations/inffast_chunk.c) ++ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/optimizations/inflate.c) ++ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/cpu_features.c) ++ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/crc32_simd.c) ++ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/crc_folding.c) ++ endif() ++endif() ++ ++if (ENABLE_INTEL_QAT_COMPRESSION) ++ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/qat/deflate_qat.cpp) ++ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/qat/qatzpp/io_buffers.cpp) ++ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/qat/qatzpp/memory.cpp) ++ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/qat/qatzpp/qat_buffer_list.cpp) ++ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/qat/qatzpp/qat.cpp) ++ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/qat/qatzpp/qat_instance.cpp) ++ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/qat/qatzpp/session.cpp) ++ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/qat/qatzpp/qat_task.cpp) ++ ++ # TODO(gustavoa): Find a way to include the qatzpp headers without having the ++ # presubmit check throw errors. ++ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/contrib/qat/qatzpp) ++ add_compile_definitions(QAT_COMPRESSION_ENABLED) ++endif() ++ ++if (ENABLE_INTEL_QAT_COMPRESSION) ++ target_include_directories(zlib PUBLIC ${QATZPP_INCLUDE_DIRS}) ++ target_link_libraries(zlib ${QATZPP_LIBRARY}) ++ target_link_libraries(zlib qat) ++ target_include_directories(zlibstatic PUBLIC ${QATZPP_INCLUDE_DIRS}) ++ target_link_libraries(zlibstatic ${QATZPP_LIBRARY}) ++ target_link_libraries(zlibstatic qat) ++endif() ++ + if(ZLIB_BUILD_SHARED) + add_library( + zlib SHARED ${ZLIB_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS} +@@ -299,12 +437,90 @@ if(ZLIB_INSTALL) + DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") + endif(ZLIB_INSTALL) + +-# ============================================================================ +-# Tests +-# ============================================================================ +-if(ZLIB_BUILD_TESTING) +- enable_testing() +- add_subdirectory(test) +-endif(ZLIB_BUILD_TESTING) +- +-add_subdirectory(contrib) ++#============================================================================ ++# Benchmarker ++#============================================================================ ++enable_language(CXX) ++set(CMAKE_CXX_STANDARD 14) # workaround for older compilers (e.g. g++ 5.4). ++add_executable(zlib_bench contrib/bench/zlib_bench.cc) ++target_link_libraries(zlib_bench zlib) ++ ++#============================================================================ ++# Unit Tests ++#============================================================================ ++if (BUILD_UNITTESTS) ++ include (ExternalProject) ++ set_directory_properties(PROPERTIES EP_PREFIX ${CMAKE_BINARY_DIR}/third_party) ++ ExternalProject_add( ++ googletest ++ GIT_REPOSITORY https://github.com/google/googletest.git ++ GIT_TAG d1467f5813f4d363cfd11aba99c4e9fe47a85e99 ++ UPDATE_COMMAND "" ++ INSTALL_COMMAND "" ++ LOG_DOWNLOAD ON ++ LOG_CONFIGURE ON ++ LOG_BUILD ON ++ ) ++ ++ # gtest includedir ++ ExternalProject_Get_Property(googletest source_dir) ++ set(GTEST_INCLUDE_DIRS ++ ${source_dir}/googletest/include ++ ${source_dir}/googletest/include/gtest ++ ) ++ ++ # gtest library ++ ExternalProject_Get_Property(googletest binary_dir) ++ set(GTEST_LIBRARY_PATH ${binary_dir}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gtest.a) ++ set(GTEST_LIBRARY gtest) ++ add_library(${GTEST_LIBRARY} UNKNOWN IMPORTED) ++ set_property(TARGET ${GTEST_LIBRARY} PROPERTY IMPORTED_LOCATION ${GTEST_LIBRARY_PATH}) ++ add_dependencies(${GTEST_LIBRARY} googletest) ++ ++ set(UTEST_SRC ++ ${CMAKE_CURRENT_SOURCE_DIR}/contrib/tests/infcover.cc ++ ${CMAKE_CURRENT_SOURCE_DIR}/contrib/tests/infcover.h ++ ${CMAKE_CURRENT_SOURCE_DIR}/contrib/tests/utils_unittest.cc ++ ${CMAKE_CURRENT_SOURCE_DIR}/contrib/tests/standalone_test_runner.cc ++ ${CMAKE_CURRENT_SOURCE_DIR}/google/compression_utils_portable.cc ++ ) ++ ++ add_compile_definitions(CMAKE_STANDALONE_UNITTESTS) ++ ++ add_executable(zlib_unittests ${UTEST_SRC}) ++ target_include_directories(zlib_unittests PUBLIC ${GTEST_INCLUDE_DIRS}) ++ target_include_directories(zlib_unittests PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/google) ++ ++ target_link_libraries(zlib_unittests ${GTEST_LIBRARY}) ++ target_link_libraries(zlib_unittests zlib) ++ # Needed by gtest ++ target_link_libraries(zlib_unittests pthread) ++endif() ++ ++#============================================================================ ++# Minizip tool ++#============================================================================ ++# TODO(cavalcantii): get it working on Windows. ++if (BUILD_MINIZIP_BIN) ++ add_executable(minizip_bin contrib/minizip/minizip.c contrib/minizip/ioapi.c ++ contrib/minizip/ioapi.h contrib/minizip/unzip.c ++ contrib/minizip/unzip.h contrib/minizip/zip.c contrib/minizip/zip.h ++ contrib/minizip/ints.h contrib/minizip/skipset.h ++ ) ++ target_link_libraries(minizip_bin zlib) ++endif() ++ ++#============================================================================ ++# zpipe tool ++#============================================================================ ++if (BUILD_ZPIPE) ++ add_executable(zpipe examples/zpipe.c) ++ target_link_libraries(zpipe zlib) ++endif() ++#============================================================================ ++# MiniGzip tool ++#============================================================================ ++if (BUILD_MINIGZIP) ++ add_executable(minigzip_bin test/minigzip.c) ++ target_link_libraries(minigzip_bin zlib) ++endif() diff --git a/deps/zlib/patches/0011-avx512.patch b/deps/zlib/patches/0011-avx512.patch index 6d409b77383d53..d58162624eb259 100644 --- a/deps/zlib/patches/0011-avx512.patch +++ b/deps/zlib/patches/0011-avx512.patch @@ -8,7 +8,6 @@ beyond current SSE SIMD optimization. It enables multiple folding operations and AVX512 new instructions, providing ~3.5X CRC32 performance and ~3.7% gain on Zlib_bench gzip performance. --- - CMakeLists.txt | 8 +- cpu_features.c | 9 +++ cpu_features.h | 1 + crc32.c | 14 +++- @@ -16,33 +15,6 @@ performance and ~3.7% gain on Zlib_bench gzip performance. crc32_simd.h | 6 ++ 6 files changed, 230 insertions(+), 6 deletions(-) -diff --git a/CMakeLists.txt b/CMakeLists.txt -index f06e193..d45b902 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -22,6 +22,7 @@ check_include_file(stdint.h HAVE_STDINT_H) - check_include_file(stddef.h HAVE_STDDEF_H) - - option(ENABLE_SIMD_OPTIMIZATIONS "Enable all SIMD optimizations" OFF) -+option(ENABLE_SIMD_AVX512 "Enable SIMD AXV512 optimizations" OFF) - - # TODO(cavalcantii): add support for other OSes (e.g. Android, fuchsia, osx) - # and architectures (e.g. Arm). -@@ -30,8 +31,13 @@ if (ENABLE_SIMD_OPTIMIZATIONS) - add_definitions(-DADLER32_SIMD_SSSE3) - add_definitions(-DINFLATE_CHUNK_READ_64LE) - add_definitions(-DCRC32_SIMD_SSE42_PCLMUL) -+ if (ENABLE_SIMD_AVX512) -+ add_definitions(-DCRC32_SIMD_AVX512_PCLMUL) -+ add_compile_options(-mvpclmulqdq -msse2 -mavx512f -mpclmul) -+ else() -+ add_compile_options(-msse4.2 -mpclmul) -+ endif() - add_definitions(-DDEFLATE_SLIDE_HASH_SSE2) -- add_compile_options(-msse4.2 -mpclmul) - # Required by CPU features detection code. - add_definitions(-DX86_NOT_WINDOWS) - # Apparently some environments (e.g. CentOS) require to explicitly link diff --git a/cpu_features.c b/cpu_features.c index 877d5f2..ac6ee88 100644 --- a/cpu_features.c diff --git a/deps/zlib/patches/0016-minizip-parse-unicode-path-extra-field.patch b/deps/zlib/patches/0016-minizip-parse-unicode-path-extra-field.patch index d69e57c07861e8..bb3e077c714718 100644 --- a/deps/zlib/patches/0016-minizip-parse-unicode-path-extra-field.patch +++ b/deps/zlib/patches/0016-minizip-parse-unicode-path-extra-field.patch @@ -68,11 +68,33 @@ Date: Fri Jul 11 13:04:30 2025 +0200 Change-Id: Ib06e1009b6e25d2d14e36858385df46d72b7bc3e Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6725677 +commit 8188181a34a48914bab22f0bc26b740fbdb38bd0 +Author: Hans Wennborg +Date: Mon Apr 27 13:24:27 2026 +0200 + + [minizip] Store the filename from Unicode Path Extra Field separately + + Instead of overriding unz_file_info64's size_filename and writing it to + szFileName, store the Unicode filename and its size in new fields. + + Overriding size_filename could cause unzGoToNextFile() to jump to the + wrong offset, potentially skipping a file in the central directory, + as demonstrated by a newly added test. + + Storing the Unicode filename and its size separately avoids that + problem and lets the caller decide what to do with the filename. Besides + fixing the problem above, that seems like a safer way of bolting on + support for this functionality. + + Bug: 40623474, 500521311 + Change-Id: I06e6c8a8ff8baa729b10a67a998f8804803ae6cd + Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7797172 + diff --git a/third_party/zlib/contrib/minizip/unzip.c b/third_party/zlib/contrib/minizip/unzip.c -index c8a01b23efd42..42677cff82c96 100644 +index 56f1468cd8d22..0264f7ac570f7 100644 --- a/third_party/zlib/contrib/minizip/unzip.c +++ b/third_party/zlib/contrib/minizip/unzip.c -@@ -64,6 +64,7 @@ +@@ -63,6 +63,7 @@ */ @@ -80,7 +102,7 @@ index c8a01b23efd42..42677cff82c96 100644 #include #include #include -@@ -193,6 +193,26 @@ typedef struct +@@ -195,6 +196,26 @@ typedef struct Reads a long in LSB order from the given gz_stream. Sets */ @@ -107,15 +129,18 @@ index c8a01b23efd42..42677cff82c96 100644 local int unz64local_getShort(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX) { -@@ -777,6 +838,7 @@ local int unz64local_GetCurrentFileInfoI +@@ -836,6 +857,10 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file, uLong uMagic; long lSeek=0; uLong uL; + uLong uFileNameCrc; ++ ++ file_info.size_utf8_filename = 0; ++ file_info.utf8_filename[0] = '\0'; if (file==NULL) return UNZ_PARAMERROR; -@@ -848,21 +910,34 @@ local int unz64local_GetCurrentFileInfoI +@@ -907,21 +932,34 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file, file_info_internal.offset_curfile = uL; lSeek+=file_info.size_filename; @@ -160,8 +185,8 @@ index c8a01b23efd42..42677cff82c96 100644 + lSeek -= file_info.size_filename; } - // Read extrafield -@@ -948,6 +1023,76 @@ local int unz64local_GetCurrentFileInfoI + /* Read extrafield */ +@@ -1007,6 +1045,62 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file, } } @@ -190,51 +215,82 @@ index c8a01b23efd42..42677cff82c96 100644 + } + else + { -+ uLong uCrc, fileNameSize; ++ uLong uCrc, utf8FileNameSize; + + if (unz64local_getLong(&s->z_filefunc, s->filestream, &uCrc) != UNZ_OK) + { + err = UNZ_ERRNO; + } -+ fileNameSize = dataSize - (1 + 4); /* 1 for version, 4 for uCrc */ ++ utf8FileNameSize = dataSize - (1 + 4); /* 1 for version, 4 for uCrc */ + + /* Check CRC against file name in the header. */ + if (uCrc != uFileNameCrc) + { -+ if (ZSEEK64(s->z_filefunc, s->filestream, fileNameSize, ZLIB_FILEFUNC_SEEK_CUR) != 0) ++ if (ZSEEK64(s->z_filefunc, s->filestream, utf8FileNameSize, ZLIB_FILEFUNC_SEEK_CUR) != 0) + { + err = UNZ_ERRNO; + } + } + else + { -+ file_info.size_filename = fileNameSize; -+ -+ char szCurrentFileName[UINT16_MAX] = {0}; ++ file_info.size_utf8_filename = utf8FileNameSize; + -+ if (file_info.size_filename > 0) ++ if (file_info.size_utf8_filename > 0) + { -+ if (ZREAD64(s->z_filefunc, s->filestream, szCurrentFileName, file_info.size_filename) != file_info.size_filename) ++ if (ZREAD64(s->z_filefunc, s->filestream, file_info.utf8_filename, file_info.size_utf8_filename) != file_info.size_utf8_filename) + { + err = UNZ_ERRNO; + } + } -+ -+ if (szFileName != NULL) -+ { -+ if (fileNameBufferSize <= file_info.size_filename) -+ { -+ memcpy(szFileName, szCurrentFileName, fileNameBufferSize); -+ } -+ else -+ { -+ memcpy(szFileName, szCurrentFileName, file_info.size_filename); -+ szFileName[file_info.size_filename] = '\0'; -+ } -+ } ++ file_info.utf8_filename[file_info.size_utf8_filename] = '\0'; + } + } + } else { if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0) +@@ -1106,6 +1200,9 @@ extern int ZEXPORT unzGetCurrentFileInfo(unzFile file, + pfile_info->compressed_size = (uLong)file_info64.compressed_size; + pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size; + ++ pfile_info->size_utf8_filename = file_info64.size_utf8_filename; ++ memcpy(pfile_info->utf8_filename, file_info64.utf8_filename, file_info64.size_utf8_filename + 1); ++ + } + return err; + } +diff --git a/third_party/zlib/contrib/minizip/unzip.h b/third_party/zlib/contrib/minizip/unzip.h +index 9c98b608c7342..05efa64ea477e 100644 +--- a/third_party/zlib/contrib/minizip/unzip.h ++++ b/third_party/zlib/contrib/minizip/unzip.h +@@ -42,6 +42,8 @@ + #ifndef _unz64_H + #define _unz64_H + ++#include ++ + #ifdef __cplusplus + extern "C" { + #endif +@@ -128,6 +130,10 @@ typedef struct unz_file_info64_s + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; ++ ++ /* Info-ZIP Unicode Path Extra Field */ ++ char utf8_filename[UINT16_MAX + 1]; /* UTF-8 Filename, null terminated */ ++ uLong size_utf8_filename; /* Length, excluding null terminator */ + } unz_file_info64; + + typedef struct unz_file_info_s +@@ -149,6 +155,10 @@ typedef struct unz_file_info_s + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; ++ ++ /* Info-ZIP Unicode Path Extra Field */ ++ char utf8_filename[UINT16_MAX + 1]; /* UTF-8 Filename, null terminated */ ++ uLong size_utf8_filename; /* Length, excluding null terminator */ + } unz_file_info; + + extern int ZEXPORT unzStringFileNameCompare(const char* fileName1, diff --git a/deps/zlib/patches/0018-support-prefixed-zip64.patch b/deps/zlib/patches/0018-support-prefixed-zip64.patch index 9e1b4732344dab..f65d470046f0f1 100644 --- a/deps/zlib/patches/0018-support-prefixed-zip64.patch +++ b/deps/zlib/patches/0018-support-prefixed-zip64.patch @@ -40,14 +40,14 @@ index a39e1752f6d2e..2c8a73e87e011 100644 + /* If bytes are pre-pended to the archive, relativeOffset must be advanced + by that many bytes. The central dir must exist between the specified + relativeOffset and uPosFound. */ ++ if (relativeOffset > uPosFound) ++ return CENTRALDIRINVALID; + const int BUFSIZE = 1024 * 4; + buf = (unsigned char*)ALLOC(BUFSIZE); + if (buf==NULL) + return CENTRALDIRINVALID; -+ if (relativeOffset > uPosFound) -+ return CENTRALDIRINVALID; + // Zip64 EOCDR is at least 48 bytes long. -+ while (relativeOffset + 48 <= uPosFound) { ++ while (uPosFound - relativeOffset >= 48) { + int found = 0; + uLong uReadSize = uPosFound - relativeOffset; + if (uReadSize > BUFSIZE) { diff --git a/deps/zlib/patches/0019-fix-zip64-in-zip.patch b/deps/zlib/patches/0019-fix-zip64-in-zip.patch new file mode 100644 index 00000000000000..26b8528645af75 --- /dev/null +++ b/deps/zlib/patches/0019-fix-zip64-in-zip.patch @@ -0,0 +1,37 @@ +diff --git a/third_party/zlib/contrib/minizip/unzip.c b/third_party/zlib/contrib/minizip/unzip.c +index b77b787ccc0db..78663ec2d53a8 100644 +--- a/third_party/zlib/contrib/minizip/unzip.c ++++ b/third_party/zlib/contrib/minizip/unzip.c +@@ -444,12 +444,28 @@ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + +- for (i=(int)uReadSize-3; (i--)>0;) ++ /* Search for the non-zip64 EoCDR and confirm zip64 EoCDL is 20 bytes ++ earlier. This avoids false positives if the file is a non-zip64 zip ++ but contains an uncompressed zip64 near its end. Note: zip64 EoCDL is ++ 20 bytes long. */ ++ for (i=(int)uReadSize-3; (i--)>20;) ++ // End of central directory record signature (PK\5\6) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && +- ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) ++ ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { +- uPosFound = uReadPos+(unsigned)i; +- break; ++ // Zip64 end of central directory locator signature (PK\6\7) ++ if (((*(buf+i-20))==0x50) && ((*(buf+i+1-20))==0x4b) && ++ ((*(buf+i+2-20))==0x06) && ((*(buf+i+3-20))==0x07)) ++ { ++ uPosFound = uReadPos+(unsigned)i-20; ++ break; ++ } ++ else ++ { ++ /* This is a non-zip64 zip; abandon the search. */ ++ free(buf); ++ return CENTRALDIRINVALID; ++ } + } + + if (uPosFound!=CENTRALDIRINVALID) diff --git a/deps/zlib/test/minigzip.c b/deps/zlib/test/minigzip.c index 134e10e6c3e947..40da8736fbd2fe 100644 --- a/deps/zlib/test/minigzip.c +++ b/deps/zlib/test/minigzip.c @@ -1,5 +1,5 @@ /* minigzip.c -- simulate gzip using the zlib compression library - * Copyright (C) 1995-2006, 2010, 2011, 2016 Jean-loup Gailly + * Copyright (C) 1995-2026 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -15,6 +15,17 @@ /* @(#) $Id$ */ +#ifndef _POSIX_C_SOURCE +# define _POSIX_C_SOURCE 200112L +#endif + +#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS) +# define _CRT_SECURE_NO_WARNINGS +#endif +#if defined(_WIN32) && !defined(_CRT_NONSTDC_NO_DEPRECATE) +# define _CRT_NONSTDC_NO_DEPRECATE +#endif + #include "zlib.h" #include @@ -40,18 +51,16 @@ # define SET_BINARY_MODE(file) #endif -#if defined(_MSC_VER) && _MSC_VER < 1900 -# define snprintf _snprintf -#endif - #ifdef VMS # define unlink delete # define GZ_SUFFIX "-gz" #endif -#ifdef RISCOS -# define unlink remove -# define GZ_SUFFIX "-gz" -# define fileno(file) file->__file +#if defined(__riscos) && !defined(__TARGET_UNIXLIB__) +# define GZ_SUFFIX "/gz" +# ifndef __GNUC__ +# define unlink remove +# define fileno(file) file->__file +# endif #endif #if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os # include /* for fileno */ @@ -109,7 +118,7 @@ static char *strwinerror (error) LocalFree(msgbuf); } else { - sprintf(buf, "unknown win32 error (%ld)", error); + sprintf(buf, "unknown win32 error (%lu)", error); } SetLastError(lasterr); @@ -142,6 +151,25 @@ static void pwinerror (s) # define local #endif +/* =========================================================================== + * Safe string copy. Copy up to len bytes from src to dst, if src terminates + * with a null by then. If not, copy len-1 bytes from src, terminating it with + * a null in dst[len-1], cutting src short. Return a pointer to the terminating + * null. If len is zero, nothing is written to *dst and NULL is returned. + */ +static char *string_copy(char *dst, char const *src, z_size_t len) { + if (len == 0) + return NULL; + while (--len) { + *dst = *src++; + if (*dst == 0) + return dst; + dst++; + } + *dst = 0; + return dst; +} + #ifdef Z_SOLO /* for Z_SOLO, create simplified gz* functions using deflate and inflate */ @@ -224,7 +252,7 @@ static int gzwrite(gzFile gz, const void *buf, unsigned len) { (void)deflate(strm, Z_NO_FLUSH); fwrite(out, 1, BUFLEN - strm->avail_out, gz->file); } while (strm->avail_out == 0); - return len; + return (int)len; } static int gzread(gzFile gz, void *buf, unsigned len) { @@ -241,7 +269,7 @@ static int gzread(gzFile gz, void *buf, unsigned len) { strm->next_out = (void *)buf; strm->avail_out = len; do { - got = fread(in, 1, 1, gz->file); + got = (unsigned)fread(in, 1, 1, gz->file); if (got == 0) break; strm->next_in = in; @@ -255,7 +283,7 @@ static int gzread(gzFile gz, void *buf, unsigned len) { if (ret == Z_STREAM_END) inflateReset(strm); } while (strm->avail_out); - return len - strm->avail_out; + return (int)(len - strm->avail_out); } static int gzclose(gzFile gz) { @@ -391,7 +419,7 @@ static void gz_uncompress(gzFile in, FILE *out) { * original. */ static void file_compress(char *file, char *mode) { - local char outfile[MAX_NAME_LEN]; + local char outfile[MAX_NAME_LEN+1], *end; FILE *in; gzFile out; @@ -400,12 +428,8 @@ static void file_compress(char *file, char *mode) { exit(1); } -#if !defined(NO_snprintf) && !defined(NO_vsnprintf) - snprintf(outfile, sizeof(outfile), "%s%s", file, GZ_SUFFIX); -#else - strcpy(outfile, file); - strcat(outfile, GZ_SUFFIX); -#endif + end = string_copy(outfile, file, sizeof(outfile)); + string_copy(end, GZ_SUFFIX, sizeof(outfile) - (z_size_t)(end - outfile)); in = fopen(file, "rb"); if (in == NULL) { @@ -414,6 +438,7 @@ static void file_compress(char *file, char *mode) { } out = gzopen(outfile, mode); if (out == NULL) { + fclose(in); fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile); exit(1); } @@ -427,7 +452,7 @@ static void file_compress(char *file, char *mode) { * Uncompress the given file and remove the original. */ static void file_uncompress(char *file) { - local char buf[MAX_NAME_LEN]; + local char buf[MAX_NAME_LEN+1]; char *infile, *outfile; FILE *out; gzFile in; @@ -438,11 +463,7 @@ static void file_uncompress(char *file) { exit(1); } -#if !defined(NO_snprintf) && !defined(NO_vsnprintf) - snprintf(buf, sizeof(buf), "%s", file); -#else - strcpy(buf, file); -#endif + string_copy(buf, file, sizeof(buf)); if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) { infile = file; @@ -451,11 +472,7 @@ static void file_uncompress(char *file) { } else { outfile = file; infile = buf; -#if !defined(NO_snprintf) && !defined(NO_vsnprintf) - snprintf(buf + len, sizeof(buf) - len, "%s", GZ_SUFFIX); -#else - strcat(infile, GZ_SUFFIX); -#endif + string_copy(buf + len, GZ_SUFFIX, sizeof(buf) - len); } in = gzopen(infile, "rb"); if (in == NULL) { @@ -464,6 +481,7 @@ static void file_uncompress(char *file) { } out = fopen(outfile, "wb"); if (out == NULL) { + gzclose(in); perror(file); exit(1); } @@ -488,14 +506,9 @@ int main(int argc, char *argv[]) { int copyout = 0; int uncompr = 0; gzFile file; - char *bname, outmode[20]; - -#if !defined(NO_snprintf) && !defined(NO_vsnprintf) - snprintf(outmode, sizeof(outmode), "%s", "wb6 "); -#else - strcpy(outmode, "wb6 "); -#endif + char *bname, outmode[5]; + string_copy(outmode, "wb6 ", sizeof(outmode)); prog = argv[0]; bname = strrchr(argv[0], '/'); if (bname) diff --git a/deps/zlib/trees.c b/deps/zlib/trees.c index 7359429702f791..1aa15510271ac3 100644 --- a/deps/zlib/trees.c +++ b/deps/zlib/trees.c @@ -1,5 +1,5 @@ /* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2024 Jean-loup Gailly + * Copyright (C) 1995-2026 Jean-loup Gailly * detect_data_type() function provided freely by Cosmin Truta, 2006 * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -112,7 +112,7 @@ local int base_dist[D_CODES]; #else # include "trees.h" -#endif /* GEN_TREES_H */ +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ struct static_tree_desc_s { const ct_data *static_tree; /* static tree or NULL */ @@ -159,7 +159,7 @@ local TCONST static_tree_desc static_bl_desc = * IN assertion: 1 <= len <= 15 */ local unsigned bi_reverse(unsigned code, int len) { - register unsigned res = 0; + unsigned res = 0; do { res |= code & 1; code >>= 1, res <<= 1; @@ -207,10 +207,11 @@ local void bi_windup(deflate_state *s) { } else if (s->bi_valid > 0) { put_byte(s, (Byte)s->bi_buf); } + s->bi_used = ((s->bi_valid - 1) & 7) + 1; s->bi_buf = 0; s->bi_valid = 0; #ifdef ZLIB_DEBUG - s->bits_sent = (s->bits_sent + 7) & ~7; + s->bits_sent = (s->bits_sent + 7) & ~(ulg)7; #endif } @@ -509,6 +510,7 @@ void ZLIB_INTERNAL _tr_init(deflate_state *s) { s->bi_buf = 0; s->bi_valid = 0; + s->bi_used = 0; #ifdef ZLIB_DEBUG s->compressed_len = 0L; s->bits_sent = 0L; @@ -767,7 +769,7 @@ local void scan_tree(deflate_state *s, ct_data *tree, int max_code) { if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { - s->bl_tree[curlen].Freq += count; + s->bl_tree[curlen].Freq += (ush)count; } else if (curlen != 0) { if (curlen != prevlen) s->bl_tree[curlen].Freq++; s->bl_tree[REP_3_6].Freq++; @@ -860,7 +862,7 @@ local int build_bl_tree(deflate_state *s) { } /* Update opt_len to include the bit length tree and counts */ s->opt_len += 3*((ulg)max_blindex + 1) + 5 + 5 + 4; - Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + Tracev((stderr, "\ndyn trees: dyn %lu, stat %lu", s->opt_len, s->static_len)); return max_blindex; @@ -886,13 +888,13 @@ local void send_all_trees(deflate_state *s, int lcodes, int dcodes, Tracev((stderr, "\nbl code %2d ", bl_order[rank])); send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); } - Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + Tracev((stderr, "\nbl tree: sent %lu", s->bits_sent)); send_tree(s, (ct_data *)s->dyn_ltree, lcodes - 1); /* literal tree */ - Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + Tracev((stderr, "\nlit tree: sent %lu", s->bits_sent)); send_tree(s, (ct_data *)s->dyn_dtree, dcodes - 1); /* distance tree */ - Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); + Tracev((stderr, "\ndist tree: sent %lu", s->bits_sent)); } /* =========================================================================== @@ -975,7 +977,7 @@ local void compress_block(deflate_state *s, const ct_data *ltree, extra = extra_dbits[code]; if (extra != 0) { dist -= (unsigned)base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ + send_bits(s, (int)dist, extra); /* send the extra bits */ } } /* literal or match pair ? */ @@ -1050,11 +1052,11 @@ void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, /* Construct the literal and distance trees */ build_tree(s, (tree_desc *)(&(s->l_desc))); - Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + Tracev((stderr, "\nlit data: dyn %lu, stat %lu", s->opt_len, s->static_len)); build_tree(s, (tree_desc *)(&(s->d_desc))); - Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + Tracev((stderr, "\ndist data: dyn %lu, stat %lu", s->opt_len, s->static_len)); /* At this point, opt_len and static_len are the total bit lengths of * the compressed block data, excluding the tree representations. @@ -1127,7 +1129,7 @@ void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, #endif } Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len >> 3, - s->compressed_len - 7*last)); + s->compressed_len - 7*(ulg)last)); } /* =========================================================================== diff --git a/deps/zlib/uncompr.c b/deps/zlib/uncompr.c index 5e256663b4511c..2195e785506457 100644 --- a/deps/zlib/uncompr.c +++ b/deps/zlib/uncompr.c @@ -1,5 +1,5 @@ /* uncompr.c -- decompress a memory buffer - * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler + * Copyright (C) 1995-2026 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -23,24 +23,24 @@ memory, Z_BUF_ERROR if there was not enough room in the output buffer, or Z_DATA_ERROR if the input data was corrupted, including if the input data is an incomplete zlib stream. + + The _z versions of the functions take size_t length arguments. */ -int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source, - uLong *sourceLen) { +int ZEXPORT uncompress2_z(Bytef *dest, z_size_t *destLen, const Bytef *source, + z_size_t *sourceLen) { z_stream stream; int err; const uInt max = (uInt)-1; - uLong len, left; - Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */ + z_size_t len, left; + + if (sourceLen == NULL || (*sourceLen > 0 && source == NULL) || + destLen == NULL || (*destLen > 0 && dest == NULL)) + return Z_STREAM_ERROR; len = *sourceLen; - if (*destLen) { - left = *destLen; - *destLen = 0; - } - else { - left = 1; - dest = buf; - } + left = *destLen; + if (left == 0 && dest == Z_NULL) + dest = (Bytef *)&stream.reserved; /* next_out cannot be NULL */ stream.next_in = (z_const Bytef *)source; stream.avail_in = 0; @@ -56,30 +56,46 @@ int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source, do { if (stream.avail_out == 0) { - stream.avail_out = left > (uLong)max ? max : (uInt)left; + stream.avail_out = left > (z_size_t)max ? max : (uInt)left; left -= stream.avail_out; } if (stream.avail_in == 0) { - stream.avail_in = len > (uLong)max ? max : (uInt)len; + stream.avail_in = len > (z_size_t)max ? max : (uInt)len; len -= stream.avail_in; } err = inflate(&stream, Z_NO_FLUSH); } while (err == Z_OK); - *sourceLen -= len + stream.avail_in; - if (dest != buf) - *destLen = stream.total_out; - else if (stream.total_out && err == Z_BUF_ERROR) - left = 1; + /* Set len and left to the unused input data and unused output space. Set + *sourceLen to the amount of input consumed. Set *destLen to the amount + of data produced. */ + len += stream.avail_in; + left += stream.avail_out; + *sourceLen -= len; + *destLen -= left; inflateEnd(&stream); return err == Z_STREAM_END ? Z_OK : err == Z_NEED_DICT ? Z_DATA_ERROR : - err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR : + err == Z_BUF_ERROR && len == 0 ? Z_DATA_ERROR : err; } - +int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source, + uLong *sourceLen) { + int ret; + z_size_t got = *destLen, used = *sourceLen; + ret = uncompress2_z(dest, &got, source, &used); + *sourceLen = (uLong)used; + *destLen = (uLong)got; + return ret; +} +int ZEXPORT uncompress_z(Bytef *dest, z_size_t *destLen, const Bytef *source, + z_size_t sourceLen) { + z_size_t used = sourceLen; + return uncompress2_z(dest, destLen, source, &used); +} int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen) { - return uncompress2(dest, destLen, source, &sourceLen); + uLong used = sourceLen; + return uncompress2(dest, destLen, source, &used); } diff --git a/deps/zlib/win32/zlib1.rc b/deps/zlib/win32/zlib1.rc new file mode 100644 index 00000000000000..e86ce568571c42 --- /dev/null +++ b/deps/zlib/win32/zlib1.rc @@ -0,0 +1,37 @@ +#include +#include "../zlib.h" + +VS_VERSION_INFO VERSIONINFO + + FILEVERSION ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0 + PRODUCTVERSION ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS 1 +#else + FILEFLAGS 0 +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, char set = Windows, Multilingual + BEGIN + VALUE "FileDescription", "zlib data compression library\0" + VALUE "FileVersion", ZLIB_VERSION "\0" + VALUE "InternalName", "zlib1.dll\0" + VALUE "LegalCopyright", "(C) 1995-2026 Jean-loup Gailly & Mark Adler\0" + VALUE "OriginalFilename", "zlib1.dll\0" + VALUE "ProductName", "zlib\0" + VALUE "ProductVersion", ZLIB_VERSION "\0" + VALUE "Comments", "For more information visit https://www.zlib.net/\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END diff --git a/deps/zlib/zconf.h b/deps/zlib/zconf.h index d72d337f701c30..4d64a653071cd0 100644 --- a/deps/zlib/zconf.h +++ b/deps/zlib/zconf.h @@ -1,5 +1,5 @@ /* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler + * Copyright (C) 1995-2026 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -45,7 +45,10 @@ # ifndef Z_SOLO # define compress z_compress # define compress2 z_compress2 +# define compress_z z_compress_z +# define compress2_z z_compress2_z # define compressBound z_compressBound +# define compressBound_z z_compressBound_z # endif # define crc32 z_crc32 # define crc32_combine z_crc32_combine @@ -56,6 +59,7 @@ # define crc32_z z_crc32_z # define deflate z_deflate # define deflateBound z_deflateBound +# define deflateBound_z z_deflateBound_z # define deflateCopy z_deflateCopy # define deflateEnd z_deflateEnd # define deflateGetDictionary z_deflateGetDictionary @@ -71,6 +75,7 @@ # define deflateSetDictionary z_deflateSetDictionary # define deflateSetHeader z_deflateSetHeader # define deflateTune z_deflateTune +# define deflateUsed z_deflateUsed # define deflate_copyright z_deflate_copyright # define get_crc_table z_get_crc_table # ifndef Z_SOLO @@ -140,9 +145,12 @@ # define inflate_copyright z_inflate_copyright # define inflate_fast z_inflate_fast # define inflate_table z_inflate_table +# define inflate_fixed z_inflate_fixed # ifndef Z_SOLO # define uncompress z_uncompress # define uncompress2 z_uncompress2 +# define uncompress_z z_uncompress_z +# define uncompress2_z z_uncompress2_z # endif # define zError z_zError # ifndef Z_SOLO @@ -246,10 +254,12 @@ # endif #endif -#if defined(ZLIB_CONST) && !defined(z_const) -# define z_const const -#else -# define z_const +#ifndef z_const +# ifdef ZLIB_CONST +# define z_const const +# else +# define z_const +# endif #endif #ifdef Z_SOLO @@ -452,7 +462,7 @@ typedef uLong FAR uLongf; # define Z_HAVE_UNISTD_H #endif -#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ +#if defined(HAVE_STDARG_H) && HAVE_STDARG_H-0 # define Z_HAVE_STDARG_H #endif @@ -485,12 +495,8 @@ typedef uLong FAR uLongf; #endif #ifndef Z_HAVE_UNISTD_H -# ifdef __WATCOMC__ -# define Z_HAVE_UNISTD_H -# endif -#endif -#ifndef Z_HAVE_UNISTD_H -# if defined(_LARGEFILE64_SOURCE) && !defined(_WIN32) +# if defined(__WATCOMC__) || defined(__GO32__) || \ + (defined(_LARGEFILE64_SOURCE) && !defined(_WIN32)) # define Z_HAVE_UNISTD_H # endif #endif @@ -525,17 +531,19 @@ typedef uLong FAR uLongf; #endif #ifndef z_off_t -# define z_off_t long +# define z_off_t long long #endif #if !defined(_WIN32) && defined(Z_LARGE64) # define z_off64_t off64_t +#elif defined(__MINGW32__) +# define z_off64_t long long +#elif defined(_WIN32) && !defined(__GNUC__) +# define z_off64_t __int64 +#elif defined(__GO32__) +# define z_off64_t offset_t #else -# if defined(_WIN32) && !defined(__GNUC__) -# define z_off64_t __int64 -# else -# define z_off64_t z_off_t -# endif +# define z_off64_t z_off_t #endif /* MVS linker does not support external names larger than 8 bytes */ diff --git a/deps/zlib/zconf.h.cmakein b/deps/zlib/zconf.h.cmakein deleted file mode 100644 index 0abe3bc9d8fa4e..00000000000000 --- a/deps/zlib/zconf.h.cmakein +++ /dev/null @@ -1,545 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H -#cmakedefine Z_PREFIX -#cmakedefine Z_HAVE_UNISTD_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - * Even better than compiling with -DZ_PREFIX would be to use configure to set - * this permanently in zconf.h using "./configure --zprefix". - */ -#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ -# define Z_PREFIX_SET - -/* all linked symbols and init macros */ -# define _dist_code z__dist_code -# define _length_code z__length_code -# define _tr_align z__tr_align -# define _tr_flush_bits z__tr_flush_bits -# define _tr_flush_block z__tr_flush_block -# define _tr_init z__tr_init -# define _tr_stored_block z__tr_stored_block -# define _tr_tally z__tr_tally -# define adler32 z_adler32 -# define adler32_combine z_adler32_combine -# define adler32_combine64 z_adler32_combine64 -# define adler32_z z_adler32_z -# ifndef Z_SOLO -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# endif -# define crc32 z_crc32 -# define crc32_combine z_crc32_combine -# define crc32_combine64 z_crc32_combine64 -# define crc32_combine_gen z_crc32_combine_gen -# define crc32_combine_gen64 z_crc32_combine_gen64 -# define crc32_combine_op z_crc32_combine_op -# define crc32_z z_crc32_z -# define deflate z_deflate -# define deflateBound z_deflateBound -# define deflateCopy z_deflateCopy -# define deflateEnd z_deflateEnd -# define deflateGetDictionary z_deflateGetDictionary -# define deflateInit z_deflateInit -# define deflateInit2 z_deflateInit2 -# define deflateInit2_ z_deflateInit2_ -# define deflateInit_ z_deflateInit_ -# define deflateParams z_deflateParams -# define deflatePending z_deflatePending -# define deflatePrime z_deflatePrime -# define deflateReset z_deflateReset -# define deflateResetKeep z_deflateResetKeep -# define deflateSetDictionary z_deflateSetDictionary -# define deflateSetHeader z_deflateSetHeader -# define deflateTune z_deflateTune -# define deflate_copyright z_deflate_copyright -# define get_crc_table z_get_crc_table -# ifndef Z_SOLO -# define gz_error z_gz_error -# define gz_intmax z_gz_intmax -# define gz_strwinerror z_gz_strwinerror -# define gzbuffer z_gzbuffer -# define gzclearerr z_gzclearerr -# define gzclose z_gzclose -# define gzclose_r z_gzclose_r -# define gzclose_w z_gzclose_w -# define gzdirect z_gzdirect -# define gzdopen z_gzdopen -# define gzeof z_gzeof -# define gzerror z_gzerror -# define gzflush z_gzflush -# define gzfread z_gzfread -# define gzfwrite z_gzfwrite -# define gzgetc z_gzgetc -# define gzgetc_ z_gzgetc_ -# define gzgets z_gzgets -# define gzoffset z_gzoffset -# define gzoffset64 z_gzoffset64 -# define gzopen z_gzopen -# define gzopen64 z_gzopen64 -# ifdef _WIN32 -# define gzopen_w z_gzopen_w -# endif -# define gzprintf z_gzprintf -# define gzputc z_gzputc -# define gzputs z_gzputs -# define gzread z_gzread -# define gzrewind z_gzrewind -# define gzseek z_gzseek -# define gzseek64 z_gzseek64 -# define gzsetparams z_gzsetparams -# define gztell z_gztell -# define gztell64 z_gztell64 -# define gzungetc z_gzungetc -# define gzvprintf z_gzvprintf -# define gzwrite z_gzwrite -# endif -# define inflate z_inflate -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define inflateBackInit z_inflateBackInit -# define inflateBackInit_ z_inflateBackInit_ -# define inflateCodesUsed z_inflateCodesUsed -# define inflateCopy z_inflateCopy -# define inflateEnd z_inflateEnd -# define inflateGetDictionary z_inflateGetDictionary -# define inflateGetHeader z_inflateGetHeader -# define inflateInit z_inflateInit -# define inflateInit2 z_inflateInit2 -# define inflateInit2_ z_inflateInit2_ -# define inflateInit_ z_inflateInit_ -# define inflateMark z_inflateMark -# define inflatePrime z_inflatePrime -# define inflateReset z_inflateReset -# define inflateReset2 z_inflateReset2 -# define inflateResetKeep z_inflateResetKeep -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateUndermine z_inflateUndermine -# define inflateValidate z_inflateValidate -# define inflate_copyright z_inflate_copyright -# define inflate_fast z_inflate_fast -# define inflate_table z_inflate_table -# ifndef Z_SOLO -# define uncompress z_uncompress -# define uncompress2 z_uncompress2 -# endif -# define zError z_zError -# ifndef Z_SOLO -# define zcalloc z_zcalloc -# define zcfree z_zcfree -# endif -# define zlibCompileFlags z_zlibCompileFlags -# define zlibVersion z_zlibVersion - -/* all zlib typedefs in zlib.h and zconf.h */ -# define Byte z_Byte -# define Bytef z_Bytef -# define alloc_func z_alloc_func -# define charf z_charf -# define free_func z_free_func -# ifndef Z_SOLO -# define gzFile z_gzFile -# endif -# define gz_header z_gz_header -# define gz_headerp z_gz_headerp -# define in_func z_in_func -# define intf z_intf -# define out_func z_out_func -# define uInt z_uInt -# define uIntf z_uIntf -# define uLong z_uLong -# define uLongf z_uLongf -# define voidp z_voidp -# define voidpc z_voidpc -# define voidpf z_voidpf - -/* all zlib structs in zlib.h and zconf.h */ -# define gz_header_s z_gz_header_s -# define internal_state z_internal_state - -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -#if defined(ZLIB_CONST) && !defined(z_const) -# define z_const const -#else -# define z_const -#endif - -#ifdef Z_SOLO -# ifdef _WIN64 - typedef unsigned long long z_size_t; -# else - typedef unsigned long z_size_t; -# endif -#else -# define z_longlong long long -# if defined(NO_SIZE_T) - typedef unsigned NO_SIZE_T z_size_t; -# elif defined(STDC) -# include - typedef size_t z_size_t; -# else - typedef unsigned long z_size_t; -# endif -# undef z_longlong -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus about 7 kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# include - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) -# include -# if (UINT_MAX == 0xffffffffUL) -# define Z_U4 unsigned -# elif (ULONG_MAX == 0xffffffffUL) -# define Z_U4 unsigned long -# elif (USHRT_MAX == 0xffffffffUL) -# define Z_U4 unsigned short -# endif -#endif - -#ifdef Z_U4 - typedef Z_U4 z_crc_t; -#else - typedef unsigned long z_crc_t; -#endif - -#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ -# define Z_HAVE_UNISTD_H -#endif - -#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ -# define Z_HAVE_STDARG_H -#endif - -#ifdef STDC -# ifndef Z_SOLO -# include /* for off_t */ -# endif -#endif - -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifndef Z_SOLO -# include /* for va_list */ -# endif -#endif - -#ifdef _WIN32 -# ifndef Z_SOLO -# include /* for wchar_t */ -# endif -#endif - -/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and - * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even - * though the former does not conform to the LFS document), but considering - * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as - * equivalently requesting no 64-bit operations - */ -#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 -# undef _LARGEFILE64_SOURCE -#endif - -#ifndef Z_HAVE_UNISTD_H -# ifdef __WATCOMC__ -# define Z_HAVE_UNISTD_H -# endif -#endif -#ifndef Z_HAVE_UNISTD_H -# if defined(_LARGEFILE64_SOURCE) && !defined(_WIN32) -# define Z_HAVE_UNISTD_H -# endif -#endif -#ifndef Z_SOLO -# if defined(Z_HAVE_UNISTD_H) -# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ -# ifdef VMS -# include /* for off_t */ -# endif -# ifndef z_off_t -# define z_off_t off_t -# endif -# endif -#endif - -#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 -# define Z_LFS64 -#endif - -#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) -# define Z_LARGE64 -#endif - -#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) -# define Z_WANT64 -#endif - -#if !defined(SEEK_SET) && !defined(Z_SOLO) -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif - -#ifndef z_off_t -# define z_off_t long -#endif - -#if !defined(_WIN32) && defined(Z_LARGE64) -# define z_off64_t off64_t -#else -# if defined(_WIN32) && !defined(__GNUC__) -# define z_off64_t __int64 -# else -# define z_off64_t z_off_t -# endif -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) - #pragma map(deflateInit_,"DEIN") - #pragma map(deflateInit2_,"DEIN2") - #pragma map(deflateEnd,"DEEND") - #pragma map(deflateBound,"DEBND") - #pragma map(inflateInit_,"ININ") - #pragma map(inflateInit2_,"ININ2") - #pragma map(inflateEnd,"INEND") - #pragma map(inflateSync,"INSY") - #pragma map(inflateSetDictionary,"INSEDI") - #pragma map(compressBound,"CMBND") - #pragma map(inflate_table,"INTABL") - #pragma map(inflate_fast,"INFA") - #pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ diff --git a/deps/zlib/zconf.h.in b/deps/zlib/zconf.h.in index 62adc8d8431f2f..828ca617e90747 100644 --- a/deps/zlib/zconf.h.in +++ b/deps/zlib/zconf.h.in @@ -1,5 +1,5 @@ /* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler + * Copyright (C) 1995-2026 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -33,7 +33,10 @@ # ifndef Z_SOLO # define compress z_compress # define compress2 z_compress2 +# define compress_z z_compress_z +# define compress2_z z_compress2_z # define compressBound z_compressBound +# define compressBound_z z_compressBound_z # endif # define crc32 z_crc32 # define crc32_combine z_crc32_combine @@ -44,6 +47,7 @@ # define crc32_z z_crc32_z # define deflate z_deflate # define deflateBound z_deflateBound +# define deflateBound_z z_deflateBound_z # define deflateCopy z_deflateCopy # define deflateEnd z_deflateEnd # define deflateGetDictionary z_deflateGetDictionary @@ -59,6 +63,7 @@ # define deflateSetDictionary z_deflateSetDictionary # define deflateSetHeader z_deflateSetHeader # define deflateTune z_deflateTune +# define deflateUsed z_deflateUsed # define deflate_copyright z_deflate_copyright # define get_crc_table z_get_crc_table # ifndef Z_SOLO @@ -128,9 +133,12 @@ # define inflate_copyright z_inflate_copyright # define inflate_fast z_inflate_fast # define inflate_table z_inflate_table +# define inflate_fixed z_inflate_fixed # ifndef Z_SOLO # define uncompress z_uncompress # define uncompress2 z_uncompress2 +# define uncompress_z z_uncompress_z +# define uncompress2_z z_uncompress2_z # endif # define zError z_zError # ifndef Z_SOLO @@ -234,10 +242,12 @@ # endif #endif -#if defined(ZLIB_CONST) && !defined(z_const) -# define z_const const -#else -# define z_const +#ifndef z_const +# ifdef ZLIB_CONST +# define z_const const +# else +# define z_const +# endif #endif #ifdef Z_SOLO @@ -433,11 +443,11 @@ typedef uLong FAR uLongf; typedef unsigned long z_crc_t; #endif -#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +#if HAVE_UNISTD_H-0 /* may be set to #if 1 by ./configure */ # define Z_HAVE_UNISTD_H #endif -#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ +#if HAVE_STDARG_H-0 /* may be set to #if 1 by ./configure */ # define Z_HAVE_STDARG_H #endif @@ -470,12 +480,8 @@ typedef uLong FAR uLongf; #endif #ifndef Z_HAVE_UNISTD_H -# ifdef __WATCOMC__ -# define Z_HAVE_UNISTD_H -# endif -#endif -#ifndef Z_HAVE_UNISTD_H -# if defined(_LARGEFILE64_SOURCE) && !defined(_WIN32) +# if defined(__WATCOMC__) || defined(__GO32__) || \ + (defined(_LARGEFILE64_SOURCE) && !defined(_WIN32)) # define Z_HAVE_UNISTD_H # endif #endif @@ -510,17 +516,19 @@ typedef uLong FAR uLongf; #endif #ifndef z_off_t -# define z_off_t long +# define z_off_t long long #endif #if !defined(_WIN32) && defined(Z_LARGE64) # define z_off64_t off64_t +#elif defined(__MINGW32__) +# define z_off64_t long long +#elif defined(_WIN32) && !defined(__GNUC__) +# define z_off64_t __int64 +#elif defined(__GO32__) +# define z_off64_t offset_t #else -# if defined(_WIN32) && !defined(__GNUC__) -# define z_off64_t __int64 -# else -# define z_off64_t z_off_t -# endif +# define z_off64_t z_off_t #endif /* MVS linker does not support external names larger than 8 bytes */ diff --git a/deps/zlib/zlib.3 b/deps/zlib/zlib.3 index c716020ea9c420..7dbae943318350 100644 --- a/deps/zlib/zlib.3 +++ b/deps/zlib/zlib.3 @@ -1,4 +1,4 @@ -.TH ZLIB 3 "22 Jan 2024" +.TH ZLIB 3 "xx Feb 2026" .SH NAME zlib \- compression/decompression library .SH SYNOPSIS @@ -57,7 +57,7 @@ written on top of by Gilles Vollant (info@winimage.com), is available at: .IP -http://www.winimage.com/zLibDll/minizip.html +https://www.winimage.com/zLibDll/minizip.html and also in the .I contrib/minizip directory of the main @@ -68,25 +68,25 @@ The .I zlib web site can be found at: .IP -http://zlib.net/ +https://zlib.net/ .LP The data format used by the .I zlib library is described by RFC -(Request for Comments) 1950 to 1952 in the files: +(Request for Comments) 1950 to 1952 at: .IP -http://tools.ietf.org/html/rfc1950 (for the zlib header and trailer format) +https://datatracker.ietf.org/doc/html/rfc1950 (for the zlib header and trailer format) .br -http://tools.ietf.org/html/rfc1951 (for the deflate compressed data format) +https://datatracker.ietf.org/doc/html/rfc1951 (for the deflate compressed data format) .br -http://tools.ietf.org/html/rfc1952 (for the gzip header and trailer format) +https://datatracker.ietf.org/doc/html/rfc1952 (for the gzip header and trailer format) .LP Mark Nelson wrote an article about .I zlib for the Jan. 1997 issue of Dr. Dobb's Journal; a copy of the article is available at: .IP -http://marknelson.us/1997/01/01/zlib-engine/ +https://zlib.net/nelson/ .SH "REPORTING PROBLEMS" Before reporting a problem, please check the @@ -99,15 +99,15 @@ Please read the .I zlib FAQ at: .IP -http://zlib.net/zlib_faq.html +https://zlib.net/zlib_faq.html .LP 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.1 +Version 1.3.2.1 .LP -Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler +Copyright (C) 1995-2026 Jean-loup Gailly and Mark Adler .LP This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/deps/zlib/zlib.h b/deps/zlib/zlib.h index 8b2f6c1db99a5e..13909f2f8eb291 100644 --- a/deps/zlib/zlib.h +++ b/deps/zlib/zlib.h @@ -1,7 +1,7 @@ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.3.1, January 22nd, 2024 + version 1.3.2.1, February xxth, 2026 - Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler + Copyright (C) 1995-2026 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,25 +24,29 @@ The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 + Comments) 1950 to 1952 at https://datatracker.ietf.org/doc/html/rfc1950 (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). */ #ifndef ZLIB_H #define ZLIB_H -#include "zconf.h" +#ifdef ZLIB_BUILD +# include +#else +# include "zconf.h" +#endif #ifdef __cplusplus extern "C" { #endif -#define ZLIB_VERSION "1.3.1" -#define ZLIB_VERNUM 0x1310 +#define ZLIB_VERSION "1.3.2.1-motley" +#define ZLIB_VERNUM 0x1321 #define ZLIB_VER_MAJOR 1 #define ZLIB_VER_MINOR 3 -#define ZLIB_VER_REVISION 1 -#define ZLIB_VER_SUBREVISION 0 +#define ZLIB_VER_REVISION 2 +#define ZLIB_VER_SUBREVISION 1 /* The 'zlib' compression library provides in-memory compression and @@ -440,7 +444,7 @@ ZEXTERN int ZEXPORT inflate(z_streamp strm, int flush); The Z_BLOCK option assists in appending to or combining deflate streams. To assist in this, on return inflate() always sets strm->data_type to the - number of unused bits in the last byte taken from strm->next_in, plus 64 if + number of unused bits in the input taken from strm->next_in, plus 64 if inflate() is currently decoding the last block in the deflate stream, plus 128 if inflate() returned immediately after decoding an end-of-block code or decoding the complete header up to just before the first byte of the deflate @@ -586,18 +590,21 @@ ZEXTERN int ZEXPORT deflateInit2(z_streamp strm, The strategy parameter is used to tune the compression algorithm. Use the value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no - string match), or Z_RLE to limit match distances to one (run-length - encoding). Filtered data consists mostly of small values with a somewhat - random distribution. In this case, the compression algorithm is tuned to - compress them better. The effect of Z_FILTERED is to force more Huffman - coding and less string matching; it is somewhat intermediate between - Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as - fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The - strategy parameter only affects the compression ratio but not the - correctness of the compressed output even if it is not set appropriately. - Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler - decoder for special applications. + filter (or predictor), Z_RLE to limit match distances to one (run-length + encoding), or Z_HUFFMAN_ONLY to force Huffman encoding only (no string + matching). Filtered data consists mostly of small values with a somewhat + random distribution, as produced by the PNG filters. In this case, the + compression algorithm is tuned to compress them better. The effect of + Z_FILTERED is to force more Huffman coding and less string matching than the + default; it is intermediate between Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. + Z_RLE is almost as fast as Z_HUFFMAN_ONLY, but should give better + compression for PNG image data than Huffman only. The degree of string + matching from most to none is: Z_DEFAULT_STRATEGY, Z_FILTERED, Z_RLE, then + Z_HUFFMAN_ONLY. The strategy parameter affects the compression ratio but + never the correctness of the compressed output, even if it is not set + optimally for the given data. Z_FIXED uses the default string matching, but + prevents the use of dynamic Huffman codes, allowing for a simpler decoder + for special applications. deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid @@ -757,8 +764,8 @@ ZEXTERN int ZEXPORT deflateTune(z_streamp strm, returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. */ -ZEXTERN uLong ZEXPORT deflateBound(z_streamp strm, - uLong sourceLen); +ZEXTERN uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen); +ZEXTERN z_size_t ZEXPORT deflateBound_z(z_streamp strm, z_size_t sourceLen); /* deflateBound() returns an upper bound on the compressed size after deflation of sourceLen bytes. It must be called after deflateInit() or @@ -770,6 +777,9 @@ ZEXTERN uLong ZEXPORT deflateBound(z_streamp strm, to return Z_STREAM_END. Note that it is possible for the compressed size to be larger than the value returned by deflateBound() if flush options other than Z_FINISH or Z_NO_FLUSH are used. + + delfateBound_z() is the same, but takes and returns a size_t length. Note + that a long is 32 bits on Windows. */ ZEXTERN int ZEXPORT deflatePending(z_streamp strm, @@ -784,6 +794,21 @@ ZEXTERN int ZEXPORT deflatePending(z_streamp strm, or bits are Z_NULL, then those values are not set. deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. If an int is 16 bits and memLevel is 9, then + it is possible for the number of pending bytes to not fit in an unsigned. In + that case Z_BUF_ERROR is returned and *pending is set to the maximum value + of an unsigned. + */ + +ZEXTERN int ZEXPORT deflateUsed(z_streamp strm, + int *bits); +/* + deflateUsed() returns in *bits the most recent number of deflate bits used + in the last byte when flushing to a byte boundary. The result is in 1..8, or + 0 if there has not yet been a flush. This helps determine the location of + the last bit of a deflate stream. + + deflateUsed returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ @@ -986,13 +1011,15 @@ ZEXTERN int ZEXPORT inflatePrime(z_streamp strm, int bits, int value); /* - This function inserts bits in the inflate input stream. The intent is - that this function is used to start inflating at a bit position in the - middle of a byte. The provided bits will be used before any bytes are used - from next_in. This function should only be used with raw inflate, and - should be used before the first inflate() call after inflateInit2() or - inflateReset(). bits must be less than or equal to 16, and that many of the - least significant bits of value will be inserted in the input. + This function inserts bits in the inflate input stream. The intent is to + use inflatePrime() to start inflating at a bit position in the middle of a + byte. The provided bits will be used before any bytes are used from + next_in. This function should be used with raw inflate, before the first + inflate() call, after inflateInit2() or inflateReset(). It can also be used + after an inflate() return indicates the end of a deflate block or header + when using Z_BLOCK. bits must be less than or equal to 16, and that many of + the least significant bits of value will be inserted in the input. The + other bits in value can be non-zero, and will be ignored. If bits is negative, then the input stream bit buffer is emptied. Then inflatePrime() can be called again to put bits in the buffer. This is used @@ -1000,7 +1027,15 @@ ZEXTERN int ZEXPORT inflatePrime(z_streamp strm, to feeding inflate codes. inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. + stream state was inconsistent, or if bits is out of range. If inflate was + in the middle of processing a header, trailer, or stored block lengths, then + it is possible for there to be only eight bits available in the bit buffer. + In that case, bits > 8 is considered out of range. However, when used as + outlined above, there will always be 16 bits available in the buffer for + insertion. As noted in its documentation above, inflate records the number + of bits in the bit buffer on return in data_type. 32 minus that is the + number of bits available for insertion. inflatePrime does not update + data_type with the new number of bits in buffer. */ ZEXTERN long ZEXPORT inflateMark(z_streamp strm); @@ -1046,20 +1081,22 @@ ZEXTERN int ZEXPORT inflateGetHeader(z_streamp strm, The text, time, xflags, and os fields are filled in with the gzip header contents. hcrc is set to true if there is a header CRC. (The header CRC - was valid if done is set to one.) If extra is not Z_NULL, then extra_max - contains the maximum number of bytes to write to extra. Once done is true, - extra_len contains the actual extra field length, and extra contains the - extra field, or that field truncated if extra_max is less than extra_len. - If name is not Z_NULL, then up to name_max characters are written there, - terminated with a zero unless the length is greater than name_max. If - comment is not Z_NULL, then up to comm_max characters are written there, - terminated with a zero unless the length is greater than comm_max. When any - of extra, name, or comment are not Z_NULL and the respective field is not - present in the header, then that field is set to Z_NULL to signal its - absence. This allows the use of deflateSetHeader() with the returned - structure to duplicate the header. However if those fields are set to - allocated memory, then the application will need to save those pointers - elsewhere so that they can be eventually freed. + was valid if done is set to one.) The extra, name, and comment pointers + much each be either Z_NULL or point to space to store that information from + the header. If extra is not Z_NULL, then extra_max contains the maximum + number of bytes that can be written to extra. Once done is true, extra_len + contains the actual extra field length, and extra contains the extra field, + or that field truncated if extra_max is less than extra_len. If name is not + Z_NULL, then up to name_max characters, including the terminating zero, are + written there. If comment is not Z_NULL, then up to comm_max characters, + including the terminating zero, are written there. The application can tell + that the name or comment did not fit in the provided space by the absence of + a terminating zero. If any of extra, name, or comment are not present in + the header, then that field's pointer is set to Z_NULL. This allows the use + of deflateSetHeader() with the returned structure to duplicate the header. + Note that if those fields initially pointed to allocated memory, then the + application will need to save them elsewhere so that they can be eventually + freed. If inflateGetHeader is not used, then the header information is simply discarded. The header is always checked for validity, including the header @@ -1207,13 +1244,14 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags(void); 21: FASTEST -- deflate algorithm with only one, lowest compression level 22,23: 0 (reserved) - The sprintf variant used by gzprintf (zero is best): + The sprintf variant used by gzprintf (all zeros is best): 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format - 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() is not secure! 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + 27: 0 = gzprintf() present, 1 = not -- 1 means gzprintf() returns an error Remainder: - 27-31: 0 (reserved) + 28-31: 0 (reserved) */ #ifndef Z_SOLO @@ -1225,11 +1263,14 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags(void); stream-oriented functions. To simplify the interface, some default options are assumed (compression level and memory usage, standard memory allocation functions). The source code of these utility functions can be modified if - you need special options. + you need special options. The _z versions of the functions use the size_t + type for lengths. Note that a long is 32 bits on Windows. */ -ZEXTERN int ZEXPORT compress(Bytef *dest, uLongf *destLen, +ZEXTERN int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen); +ZEXTERN int ZEXPORT compress_z(Bytef *dest, z_size_t *destLen, + const Bytef *source, z_size_t sourceLen); /* Compresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size @@ -1243,9 +1284,12 @@ ZEXTERN int ZEXPORT compress(Bytef *dest, uLongf *destLen, buffer. */ -ZEXTERN int ZEXPORT compress2(Bytef *dest, uLongf *destLen, +ZEXTERN int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level); +ZEXTERN int ZEXPORT compress2_z(Bytef *dest, z_size_t *destLen, + const Bytef *source, z_size_t sourceLen, + int level); /* Compresses the source buffer into the destination buffer. The level parameter has the same meaning as in deflateInit. sourceLen is the byte @@ -1260,21 +1304,24 @@ ZEXTERN int ZEXPORT compress2(Bytef *dest, uLongf *destLen, */ ZEXTERN uLong ZEXPORT compressBound(uLong sourceLen); +ZEXTERN z_size_t ZEXPORT compressBound_z(z_size_t sourceLen); /* compressBound() returns an upper bound on the compressed size after compress() or compress2() on sourceLen bytes. It would be used before a compress() or compress2() call to allocate the destination buffer. */ -ZEXTERN int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, +ZEXTERN int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen); +ZEXTERN int ZEXPORT uncompress_z(Bytef *dest, z_size_t *destLen, + const Bytef *source, z_size_t sourceLen); /* Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size + the byte length of the source buffer. On entry, *destLen is the total size of the destination buffer, which must be large enough to hold the entire uncompressed data. (The size of the uncompressed data must have been saved previously by the compressor and transmitted to the decompressor by some - mechanism outside the scope of this compression library.) Upon exit, destLen + mechanism outside the scope of this compression library.) On exit, *destLen is the actual size of the uncompressed data. uncompress returns Z_OK if success, Z_MEM_ERROR if there was not @@ -1284,8 +1331,10 @@ ZEXTERN int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, buffer with the uncompressed data up to that point. */ -ZEXTERN int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, +ZEXTERN int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source, uLong *sourceLen); +ZEXTERN int ZEXPORT uncompress2_z(Bytef *dest, z_size_t *destLen, + const Bytef *source, z_size_t *sourceLen); /* Same as uncompress, except that sourceLen is a pointer, where the length of the source is *sourceLen. On return, *sourceLen is the number of @@ -1313,13 +1362,17 @@ ZEXTERN gzFile ZEXPORT gzopen(const char *path, const char *mode); 'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression as in "wb9F". (See the description of deflateInit2 for more information about the strategy parameter.) 'T' will request transparent writing or - appending with no compression and not using the gzip format. - - "a" can be used instead of "w" to request that the gzip stream that will - be written be appended to the file. "+" will result in an error, since + appending with no compression and not using the gzip format. 'T' cannot be + used to force transparent reading. Transparent reading is automatically + performed if there is no gzip header at the start. Transparent reading can + be disabled with the 'G' option, which will instead return an error if there + is no gzip header. 'N' will open the file in non-blocking mode. + + 'a' can be used instead of 'w' to request that the gzip stream that will + be written be appended to the file. '+' will result in an error, since reading and writing to the same gzip file is not supported. The addition of - "x" when writing will create the file exclusively, which fails if the file - already exists. On systems that support it, the addition of "e" when + 'x' when writing will create the file exclusively, which fails if the file + already exists. On systems that support it, the addition of 'e' when reading or writing will set the flag to close the file on an execve() call. These functions, as well as gzip, will read and decode a sequence of gzip @@ -1338,14 +1391,22 @@ ZEXTERN gzFile ZEXPORT gzopen(const char *path, const char *mode); insufficient memory to allocate the gzFile state, or if an invalid mode was specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). errno can be checked to determine if the reason gzopen failed was that the - file could not be opened. + file could not be opened. Note that if 'N' is in mode for non-blocking, the + open() itself can fail in order to not block. In that case gzopen() will + return NULL and errno will be EAGAIN or ENONBLOCK. The call to gzopen() can + then be re-tried. If the application would like to block on opening the + file, then it can use open() without O_NONBLOCK, and then gzdopen() with the + resulting file descriptor and 'N' in the mode, which will set it to non- + blocking. */ ZEXTERN gzFile ZEXPORT gzdopen(int fd, const char *mode); /* Associate a gzFile with the file descriptor fd. File descriptors are obtained from calls like open, dup, creat, pipe or fileno (if the file has - been previously opened with fopen). The mode parameter is as in gzopen. + been previously opened with fopen). The mode parameter is as in gzopen. An + 'e' in mode will set fd's flag to close the file on an execve() call. An 'N' + in mode will set fd's non-blocking flag. The next call of gzclose on the returned gzFile will also close the file descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor @@ -1415,10 +1476,16 @@ ZEXTERN int ZEXPORT gzread(gzFile file, voidp buf, unsigned len); stream. Alternatively, gzerror can be used before gzclose to detect this case. + gzread can be used to read a gzip file on a non-blocking device. If the + input stalls and there is no uncompressed data to return, then gzread() will + return -1, and errno will be EAGAIN or EWOULDBLOCK. gzread() can then be + called again. + gzread returns the number of uncompressed bytes actually read, less than len for end of file, or -1 for error. If len is too large to fit in an int, then nothing is read, -1 is returned, and the error state is set to - Z_STREAM_ERROR. + Z_STREAM_ERROR. If some data was read before an error, then that data is + returned until exhausted, after which the next call will signal the error. */ ZEXTERN z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, @@ -1442,15 +1509,20 @@ ZEXTERN z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, multiple of size, then the final partial item is nevertheless read into buf and the end-of-file flag is set. The length of the partial item read is not provided, but could be inferred from the result of gztell(). This behavior - is the same as the behavior of fread() implementations in common libraries, - but it prevents the direct use of gzfread() to read a concurrently written - file, resetting and retrying on end-of-file, when size is not 1. + is the same as that of fread() implementations in common libraries. This + could result in data loss if used with size != 1 when reading a concurrently + written file or a non-blocking file. In that case, use size == 1 or gzread() + instead. */ ZEXTERN int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len); /* Compress and write the len uncompressed bytes at buf to file. gzwrite - returns the number of uncompressed bytes written or 0 in case of error. + returns the number of uncompressed bytes written, or 0 in case of error or + if len is 0. If the write destination is non-blocking, then gzwrite() may + return a number of bytes written that is not 0 and less than len. + + If len does not fit in an int, then 0 is returned and nothing is written. */ ZEXTERN z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, @@ -1465,9 +1537,18 @@ ZEXTERN z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, if there was an error. If the multiplication of size and nitems overflows, i.e. the product does not fit in a z_size_t, then nothing is written, zero is returned, and the error state is set to Z_STREAM_ERROR. + + If writing a concurrently read file or a non-blocking file with size != 1, + a partial item could be written, with no way of knowing how much of it was + not written, resulting in data loss. In that case, use size == 1 or + gzwrite() instead. */ +#if defined(STDC) || defined(Z_HAVE_STDARG_H) ZEXTERN int ZEXPORTVA gzprintf(gzFile file, const char *format, ...); +#else +ZEXTERN int ZEXPORTVA gzprintf(); +#endif /* Convert, format, compress, and write the arguments (...) to file under control of the string format, as in fprintf. gzprintf returns the number of @@ -1475,11 +1556,19 @@ ZEXTERN int ZEXPORTVA gzprintf(gzFile file, const char *format, ...); of error. The number of uncompressed bytes written is limited to 8191, or one less than the buffer size given to gzbuffer(). The caller should assure that this limit is not exceeded. If it is exceeded, then gzprintf() will - return an error (0) with nothing written. In this case, there may also be a - buffer overflow with unpredictable consequences, which is possible only if - zlib was compiled with the insecure functions sprintf() or vsprintf(), - because the secure snprintf() or vsnprintf() functions were not available. - This can be determined using zlibCompileFlags(). + return an error (0) with nothing written. + + In that last case, there may also be a buffer overflow with unpredictable + consequences, which is possible only if zlib was compiled with the insecure + functions sprintf() or vsprintf(), because the secure snprintf() and + vsnprintf() functions were not available. That would only be the case for + a non-ANSI C compiler. zlib may have been built without gzprintf() because + secure functions were not available and having gzprintf() be insecure was + not an option, in which case, gzprintf() returns Z_STREAM_ERROR. All of + these possibilities can be determined using zlibCompileFlags(). + + If a Z_BUF_ERROR is returned, then nothing was written due to a stall on + the non-blocking write destination. */ ZEXTERN int ZEXPORT gzputs(gzFile file, const char *s); @@ -1488,6 +1577,11 @@ ZEXTERN int ZEXPORT gzputs(gzFile file, const char *s); the terminating null character. gzputs returns the number of characters written, or -1 in case of error. + The number of characters written may be less than the length of the string + if the write destination is non-blocking. + + If the length of the string does not fit in an int, then -1 is returned + and nothing is written. */ ZEXTERN char * ZEXPORT gzgets(gzFile file, char *buf, int len); @@ -1500,8 +1594,13 @@ ZEXTERN char * ZEXPORT gzgets(gzFile file, char *buf, int len); left untouched. gzgets returns buf which is a null-terminated string, or it returns NULL - for end-of-file or in case of error. If there was an error, the contents at - buf are indeterminate. + for end-of-file or in case of error. If some data was read before an error, + then that data is returned until exhausted, after which the next call will + return NULL to signal the error. + + gzgets can be used on a file being concurrently written, and on a non- + blocking device, both as for gzread(). However lines may be broken in the + middle, leaving it up to the application to reassemble them as needed. */ ZEXTERN int ZEXPORT gzputc(gzFile file, int c); @@ -1512,11 +1611,19 @@ ZEXTERN int ZEXPORT gzputc(gzFile file, int c); ZEXTERN int ZEXPORT gzgetc(gzFile file); /* - Read and decompress one byte from file. gzgetc returns this byte or -1 - in case of end of file or error. This is implemented as a macro for speed. - As such, it does not do all of the checking the other functions do. I.e. - it does not check to see if file is NULL, nor whether the structure file - points to has been clobbered or not. + Read and decompress one byte from file. gzgetc returns this byte or -1 in + case of end of file or error. If some data was read before an error, then + that data is returned until exhausted, after which the next call will return + -1 to signal the error. + + This is implemented as a macro for speed. As such, it does not do all of + the checking the other functions do. I.e. it does not check to see if file + is NULL, nor whether the structure file points to has been clobbered or not. + + gzgetc can be used to read a gzip file on a non-blocking device. If the + input stalls and there is no uncompressed data to return, then gzgetc() will + return -1, and errno will be EAGAIN or EWOULDBLOCK. gzread() can then be + called again. */ ZEXTERN int ZEXPORT gzungetc(int c, gzFile file); @@ -1529,6 +1636,11 @@ ZEXTERN int ZEXPORT gzungetc(int c, gzFile file); output buffer size of pushed characters is allowed. (See gzbuffer above.) The pushed character will be discarded if the stream is repositioned with gzseek() or gzrewind(). + + gzungetc(-1, file) will force any pending seek to execute. Then gztell() + will report the position, even if the requested seek reached end of file. + This can be used to determine the number of uncompressed bytes in a gzip + file without having to read it into a buffer. */ ZEXTERN int ZEXPORT gzflush(gzFile file, int flush); @@ -1558,7 +1670,8 @@ ZEXTERN z_off_t ZEXPORT gzseek(gzFile file, If the file is opened for reading, this function is emulated but can be extremely slow. If the file is opened for writing, only forward seeks are supported; gzseek then compresses a sequence of zeroes up to the new - starting position. + starting position. For reading or writing, any actual seeking is deferred + until the next read or write operation, or close operation when writing. gzseek returns the resulting offset location as measured in bytes from the beginning of the uncompressed stream, or -1 in case of error, in @@ -1566,7 +1679,7 @@ ZEXTERN z_off_t ZEXPORT gzseek(gzFile file, would be before the current position. */ -ZEXTERN int ZEXPORT gzrewind(gzFile file); +ZEXTERN int ZEXPORT gzrewind(gzFile file); /* Rewind file. This function is supported only for reading. @@ -1574,7 +1687,7 @@ ZEXTERN int ZEXPORT gzrewind(gzFile file); */ /* -ZEXTERN z_off_t ZEXPORT gztell(gzFile file); +ZEXTERN z_off_t ZEXPORT gztell(gzFile file); Return the starting position for the next gzread or gzwrite on file. This position represents a number of bytes in the uncompressed data stream, @@ -1619,8 +1732,11 @@ ZEXTERN int ZEXPORT gzdirect(gzFile file); If gzdirect() is used immediately after gzopen() or gzdopen() it will cause buffers to be allocated to allow reading the file to determine if it - is a gzip file. Therefore if gzbuffer() is used, it should be called before - gzdirect(). + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). If the input is being written concurrently or the device is non- + blocking, then gzdirect() may give a different answer once four bytes of + input have been accumulated, which is what is needed to confirm or deny a + gzip header. Before this, gzdirect() will return true (1). When writing, gzdirect() returns true (1) if transparent writing was requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: @@ -1630,7 +1746,7 @@ ZEXTERN int ZEXPORT gzdirect(gzFile file); gzip file reading and decompression, which may not be desired.) */ -ZEXTERN int ZEXPORT gzclose(gzFile file); +ZEXTERN int ZEXPORT gzclose(gzFile file); /* Flush all pending output for file, if necessary, close file and deallocate the (de)compression state. Note that once file is closed, you @@ -1658,9 +1774,10 @@ ZEXTERN int ZEXPORT gzclose_w(gzFile file); ZEXTERN const char * ZEXPORT gzerror(gzFile file, int *errnum); /* Return the error message for the last error which occurred on file. - errnum is set to zlib error number. If an error occurred in the file system - and not in the compression library, errnum is set to Z_ERRNO and the - application may consult errno to get the exact error code. + If errnum is not NULL, *errnum is set to zlib error number. If an error + occurred in the file system and not in the compression library, *errnum is + set to Z_ERRNO and the application may consult errno to get the exact error + code. The application must not modify the returned string. Future calls to this function may invalidate the previously returned string. If file is @@ -1711,7 +1828,8 @@ ZEXTERN uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len); ZEXTERN uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, z_size_t len); /* - Same as adler32(), but with a size_t length. + Same as adler32(), but with a size_t length. Note that a long is 32 bits + on Windows. */ /* @@ -1747,7 +1865,8 @@ ZEXTERN uLong ZEXPORT crc32(uLong crc, const Bytef *buf, uInt len); ZEXTERN uLong ZEXPORT crc32_z(uLong crc, const Bytef *buf, z_size_t len); /* - Same as crc32(), but with a size_t length. + Same as crc32(), but with a size_t length. Note that a long is 32 bits on + Windows. */ /* @@ -1757,14 +1876,14 @@ ZEXTERN uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2); seq1 and seq2 with lengths len1 and len2, CRC-32 check values were calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. len2 must be non-negative. + len2. len2 must be non-negative, otherwise zero is returned. */ /* ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t len2); Return the operator corresponding to length len2, to be used with - crc32_combine_op(). len2 must be non-negative. + crc32_combine_op(). len2 must be non-negative, otherwise zero is returned. */ ZEXTERN uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op); @@ -1917,9 +2036,9 @@ ZEXTERN int ZEXPORT gzgetc_(gzFile file); /* backward compatibility */ ZEXTERN z_off_t ZEXPORT gzseek64(gzFile, z_off_t, int); ZEXTERN z_off_t ZEXPORT gztell64(gzFile); ZEXTERN z_off_t ZEXPORT gzoffset64(gzFile); - ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t); - ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t); - ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off_t); + ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off64_t); + ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off64_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off64_t); # endif #else ZEXTERN gzFile ZEXPORT gzopen(const char *, const char *); diff --git a/deps/zlib/zlib.map b/deps/zlib/zlib.map index 31544f2e93da1a..7a9100f035052b 100644 --- a/deps/zlib/zlib.map +++ b/deps/zlib/zlib.map @@ -98,3 +98,19 @@ ZLIB_1.2.12 { crc32_combine_gen64; crc32_combine_op; } ZLIB_1.2.9; + +ZLIB_1.3.1.2 { + deflateUsed; +} ZLIB_1.2.12; + +ZLIB_1.3.2 { + global: + compressBound_z; + deflateBound_z; + compress_z; + compress2_z; + uncompress_z; + uncompress2_z; + local: + inflate_fixed; +} ZLIB_1.3.1.2; diff --git a/deps/zlib/zlib.pc.cmakein b/deps/zlib/zlib.pc.cmakein index a5e642938c6985..a392727c542b38 100644 --- a/deps/zlib/zlib.pc.cmakein +++ b/deps/zlib/zlib.pc.cmakein @@ -1,12 +1,13 @@ prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=@CMAKE_INSTALL_PREFIX@ -libdir=@INSTALL_LIB_DIR@ -sharedlibdir=@INSTALL_LIB_DIR@ -includedir=@INSTALL_INC_DIR@ +libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ +sharedlibdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${exec_prefix}/@CMAKE_INSTALL_INCLUDEDIR@ Name: zlib Description: zlib compression library -Version: @VERSION@ +Version: @zlib_VERSION@ +License: Zlib Requires: Libs: -L${libdir} -L${sharedlibdir} -lz diff --git a/deps/zlib/zlibConfig.cmake.in b/deps/zlib/zlibConfig.cmake.in new file mode 100644 index 00000000000000..8252ab34ca325f --- /dev/null +++ b/deps/zlib/zlibConfig.cmake.in @@ -0,0 +1,18 @@ +@PACKAGE_INIT@ + +set(_ZLIB_supported_components "shared" "static") + +if(ZLIB_FIND_COMPONENTS) + foreach(_comp ${ZLIB_FIND_COMPONENTS}) + if(NOT _comp IN_LIST _ZLIB_supported_components) + set(ZLIB_FOUND False) + set(ZLIB_NOT_FOUND_MESSAGE "Unsupported component: ${_comp}") + endif(NOT _comp IN_LIST _ZLIB_supported_components) + + include("${CMAKE_CURRENT_LIST_DIR}/ZLIB-${_comp}.cmake") + endforeach(_comp ${ZLIB_FIND_COMPONENTS}) +else(ZLIB_FIND_COMPONENTS) + foreach(_component_config IN LISTS _ZLIB_supported_components) + include("${CMAKE_CURRENT_LIST_DIR}/ZLIB-${_component_config}.cmake") + endforeach(_component_config IN LISTS _ZLIB_supported_components) +endif(ZLIB_FIND_COMPONENTS) diff --git a/deps/zlib/zutil.c b/deps/zlib/zutil.c index b1c5d2d3c6daf5..0e30c566429e7f 100644 --- a/deps/zlib/zutil.c +++ b/deps/zlib/zutil.c @@ -1,5 +1,5 @@ /* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-2017 Jean-loup Gailly + * Copyright (C) 1995-2026 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -86,28 +86,36 @@ uLong ZEXPORT zlibCompileFlags(void) { flags += 1L << 21; #endif #if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifdef NO_vsnprintf - flags += 1L << 25; -# ifdef HAS_vsprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_vsnprintf_void - flags += 1L << 26; -# endif -# endif +# ifdef NO_vsnprintf +# ifdef ZLIB_INSECURE + flags += 1L << 25; +# else + flags += 1L << 27; +# endif +# ifdef HAS_vsprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_vsnprintf_void + flags += 1L << 26; +# endif +# endif #else flags += 1L << 24; -# ifdef NO_snprintf - flags += 1L << 25; -# ifdef HAS_sprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_snprintf_void - flags += 1L << 26; -# endif -# endif +# ifdef NO_snprintf +# ifdef ZLIB_INSECURE + flags += 1L << 25; +# else + flags += 1L << 27; +# endif +# ifdef HAS_sprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_snprintf_void + flags += 1L << 26; +# endif +# endif #endif return flags; } @@ -142,28 +150,33 @@ const char * ZEXPORT zError(int err) { #ifndef HAVE_MEMCPY -void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len) { - if (len == 0) return; - do { - *dest++ = *source++; /* ??? to be unrolled */ - } while (--len != 0); +void ZLIB_INTERNAL zmemcpy(void FAR *dst, const void FAR *src, z_size_t n) { + uchf *p = dst; + const uchf *q = src; + while (n) { + *p++ = *q++; + n--; + } } -int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len) { - uInt j; - - for (j = 0; j < len; j++) { - if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; +int ZLIB_INTERNAL zmemcmp(const void FAR *s1, const void FAR *s2, z_size_t n) { + const uchf *p = s1, *q = s2; + while (n) { + if (*p++ != *q++) + return (int)p[-1] - (int)q[-1]; + n--; } return 0; } -void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len) { - if (len == 0) return; - do { - *dest++ = 0; /* ??? to be unrolled */ - } while (--len != 0); +void ZLIB_INTERNAL zmemzero(void FAR *b, z_size_t len) { + uchf *p = b; + while (len) { + *p++ = 0; + len--; + } } + #endif #ifndef Z_SOLO diff --git a/deps/zlib/zutil.h b/deps/zlib/zutil.h index 045a35a4f55522..64cd7a41ecd631 100644 --- a/deps/zlib/zutil.h +++ b/deps/zlib/zutil.h @@ -1,5 +1,5 @@ /* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler + * Copyright (C) 1995-2026 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -51,6 +51,10 @@ define "local" for the non-static meaning of "static", for readability (compile with -Dlocal if your debugger can't find static symbols) */ +extern const char deflate_copyright[]; +extern const char inflate_copyright[]; +extern const char inflate9_copyright[]; + typedef unsigned char uch; typedef uch FAR uchf; typedef unsigned short ush; @@ -63,6 +67,8 @@ typedef unsigned long ulg; # define Z_U8 unsigned long # elif (ULLONG_MAX == 0xffffffffffffffff) # define Z_U8 unsigned long long +# elif (ULONG_LONG_MAX == 0xffffffffffffffff) +# define Z_U8 unsigned long long # elif (UINT_MAX == 0xffffffffffffffff) # define Z_U8 unsigned # endif @@ -78,7 +84,9 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ /* To be used only when the state is known to be valid */ /* common constants */ - +#if MAX_WBITS < 9 || MAX_WBITS > 15 +# error MAX_WBITS must be in 9..15 +#endif #ifndef DEF_WBITS # define DEF_WBITS MAX_WBITS #endif @@ -156,7 +164,7 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # define OS_CODE 7 #endif -#ifdef __acorn +#if defined(__acorn) || defined(__riscos) # define OS_CODE 13 #endif @@ -183,11 +191,10 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ #endif /* provide prototypes for these when building zlib without LFS */ -#if !defined(_WIN32) && \ - (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) - ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t); - ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t); - ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off_t); +#ifndef Z_LARGE64 + ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off64_t); + ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off64_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off64_t); #endif /* common defaults */ @@ -226,9 +233,9 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # define zmemzero(dest, len) memset(dest, 0, len) # endif #else - void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len); - int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len); - void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len); + void ZLIB_INTERNAL zmemcpy(void FAR *, const void FAR *, z_size_t); + int ZLIB_INTERNAL zmemcmp(const void FAR *, const void FAR *, z_size_t); + void ZLIB_INTERNAL zmemzero(void FAR *, z_size_t); #endif /* Diagnostic functions */ @@ -272,4 +279,74 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ #define zalign(x) __attribute__((aligned((x)))) #endif +#ifdef Z_ONCE +/* + Create a local z_once() function depending on the availability of atomics. + */ + +/* Check for the availability of atomics. */ +#if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \ + !defined(__STDC_NO_ATOMICS__) + +#include +typedef struct { + atomic_flag begun; + atomic_int done; +} z_once_t; +#define Z_ONCE_INIT {ATOMIC_FLAG_INIT, 0} + +/* + Run the provided init() function exactly once, even if multiple threads + invoke once() at the same time. The state must be a once_t initialized with + Z_ONCE_INIT. + */ +local void z_once(z_once_t *state, void (*init)(void)) { + if (!atomic_load(&state->done)) { + if (atomic_flag_test_and_set(&state->begun)) + while (!atomic_load(&state->done)) + ; + else { + init(); + atomic_store(&state->done, 1); + } + } +} + +#else /* no atomics */ + +#warning zlib not thread-safe + +typedef struct z_once_s { + volatile int begun; + volatile int done; +} z_once_t; +#define Z_ONCE_INIT {0, 0} + +/* Test and set. Alas, not atomic, but tries to limit the period of + vulnerability. */ +local int test_and_set(int volatile *flag) { + int was; + + was = *flag; + *flag = 1; + return was; +} + +/* Run the provided init() function once. This is not thread-safe. */ +local void z_once(z_once_t *state, void (*init)(void)) { + if (!state->done) { + if (test_and_set(&state->begun)) + while (!state->done) + ; + else { + init(); + state->done = 1; + } + } +} + +#endif /* ?atomics */ + +#endif /* Z_ONCE */ + #endif /* ZUTIL_H */ diff --git a/src/zlib_version.h b/src/zlib_version.h index 7ce58e3077bade..e06e2526f3bdb2 100644 --- a/src/zlib_version.h +++ b/src/zlib_version.h @@ -2,5 +2,5 @@ // Refer to tools/dep_updaters/update-zlib.sh #ifndef SRC_ZLIB_VERSION_H_ #define SRC_ZLIB_VERSION_H_ -#define ZLIB_VERSION "1.3.1-e00f703" +#define ZLIB_VERSION "1.3.2.1-motley-3246f1b" #endif // SRC_ZLIB_VERSION_H_