From 3bee0c5ffcd272d0cf7135cbfc3b011becfd6e8d Mon Sep 17 00:00:00 2001 From: gangatp Date: Mon, 18 Dec 2023 22:26:34 +0530 Subject: [PATCH] updating libzip to 1.10.1 --- .gitmodules | 3 + CMakeLists.txt | 40 ++- Include/Common/OPC/NMR_OpcPackageReader.h | 2 +- .../Common/Platform/NMR_ImportStream_ZIP.h | 2 +- Include/Libraries/libzip/config.h | 62 ---- Include/Libraries/libzip/zipconf.h | 51 --- .../libzip/Include}/compat.h | 52 ++- .../libzip => Libraries/libzip/Include}/zip.h | 94 ++++-- .../libzip/Include}/zip_source_file.h | 6 +- .../libzip/Include}/zip_source_file_stdio.h | 4 +- .../libzip/Include}/zip_source_file_win32.h | 10 +- .../libzip/Include}/zipint.h | 112 +++++-- .../libzip/Source/unix}/zip_random_unix.c | 10 +- .../unix}/zip_source_file_stdio_named.c | 223 +++++++++---- .../libzip/Source/win/zip_random_win32.c | 79 +++-- .../Source/win}/zip_source_file_win32.c | 10 +- .../Source/win/zip_source_file_win32_ansi.c | 87 +++++ .../Source/win}/zip_source_file_win32_named.c | 3 +- .../Source/win}/zip_source_file_win32_utf16.c | 8 +- .../Source/win}/zip_source_file_win32_utf8.c | 4 +- .../libzip/Source}/zip_add.c | 4 +- .../libzip/Source}/zip_add_dir.c | 4 +- .../libzip/Source}/zip_add_entry.c | 4 +- .../libzip/Source}/zip_algorithm_deflate.c | 39 ++- .../libzip/Source}/zip_buffer.c | 36 +- .../libzip/Source}/zip_close.c | 131 +++++--- .../libzip/Source}/zip_delete.c | 4 +- .../libzip/Source}/zip_dir_add.c | 8 +- .../libzip/Source}/zip_dirent.c | 250 ++++++++------ .../libzip/Source}/zip_discard.c | 4 +- .../libzip/Source}/zip_entry.c | 4 +- Libraries/libzip/Source/zip_err_str.c | 79 +++++ .../libzip/Source}/zip_error.c | 30 +- .../libzip/Source}/zip_error_clear.c | 4 +- .../libzip/Source}/zip_error_get.c | 4 +- .../libzip/Source}/zip_error_get_sys_type.c | 9 +- Libraries/libzip/Source/zip_error_strerror.c | 128 +++++++ .../libzip/Source}/zip_error_to_str.c | 33 +- .../libzip/Source}/zip_extra_field.c | 15 +- .../libzip/Source}/zip_extra_field_api.c | 16 +- .../libzip/Source}/zip_fclose.c | 4 +- .../libzip/Source}/zip_fdopen.c | 9 +- .../libzip/Source}/zip_file_add.c | 4 +- .../libzip/Source}/zip_file_error_clear.c | 4 +- .../libzip/Source}/zip_file_error_get.c | 4 +- .../libzip/Source}/zip_file_get_comment.c | 4 +- .../zip_file_get_external_attributes.c | 4 +- .../libzip/Source}/zip_file_get_offset.c | 10 +- .../libzip/Source}/zip_file_rename.c | 4 +- .../libzip/Source}/zip_file_replace.c | 4 +- .../libzip/Source}/zip_file_set_comment.c | 8 +- .../libzip/Source}/zip_file_set_encryption.c | 8 +- .../zip_file_set_external_attributes.c | 8 +- .../libzip/Source}/zip_file_set_mtime.c | 13 +- .../libzip/Source}/zip_file_strerror.c | 4 +- .../libzip/Source}/zip_fopen.c | 4 +- .../libzip/Source}/zip_fopen_encrypted.c | 4 +- .../libzip/Source}/zip_fopen_index.c | 4 +- .../Source}/zip_fopen_index_encrypted.c | 10 +- .../libzip/Source}/zip_fread.c | 9 +- .../libzip/Source}/zip_fseek.c | 16 +- .../libzip/Source}/zip_ftell.c | 6 +- .../libzip/Source}/zip_get_archive_comment.c | 4 +- .../libzip/Source}/zip_get_archive_flag.c | 4 +- .../zip_get_encryption_implementation.c | 5 +- .../libzip/Source}/zip_get_file_comment.c | 4 +- .../libzip/Source}/zip_get_name.c | 4 +- .../libzip/Source}/zip_get_num_entries.c | 4 +- .../libzip/Source}/zip_get_num_files.c | 4 +- .../libzip/Source}/zip_hash.c | 4 +- .../libzip/Source}/zip_io_util.c | 22 +- .../libzip/Source}/zip_libzip_version.c | 4 +- .../libzip/Source}/zip_memdup.c | 6 +- .../libzip/Source}/zip_name_locate.c | 34 +- .../libzip/Source}/zip_new.c | 4 +- .../libzip/Source}/zip_open.c | 228 +++++++++---- .../libzip/Source}/zip_pkware.c | 2 +- .../libzip/Source}/zip_progress.c | 2 +- .../libzip/Source}/zip_rename.c | 4 +- .../libzip/Source}/zip_replace.c | 4 +- .../libzip/Source}/zip_set_archive_comment.c | 8 +- .../libzip/Source}/zip_set_archive_flag.c | 23 +- .../libzip/Source}/zip_set_default_password.c | 4 +- .../libzip/Source}/zip_set_file_comment.c | 4 +- .../libzip/Source}/zip_set_file_compression.c | 10 +- .../libzip/Source}/zip_set_name.c | 4 +- .../libzip/Source}/zip_source_accept_empty.c | 8 +- .../libzip/Source}/zip_source_begin_write.c | 9 +- .../Source}/zip_source_begin_write_cloning.c | 9 +- .../libzip/Source}/zip_source_buffer.c | 83 ++--- .../libzip/Source}/zip_source_call.c | 4 +- .../libzip/Source}/zip_source_close.c | 4 +- .../libzip/Source}/zip_source_commit_write.c | 9 +- .../libzip/Source}/zip_source_compress.c | 32 +- .../libzip/Source}/zip_source_crc.c | 34 +- .../libzip/Source}/zip_source_error.c | 4 +- .../libzip/Source}/zip_source_file_common.c | 36 +- .../libzip/Source}/zip_source_file_stdio.c | 34 +- .../libzip/Source}/zip_source_free.c | 4 +- .../libzip/Source}/zip_source_function.c | 5 +- .../Source}/zip_source_get_file_attributes.c | 6 +- .../libzip/Source}/zip_source_is_deleted.c | 4 +- .../libzip/Source}/zip_source_layered.c | 24 +- .../libzip/Source}/zip_source_open.c | 6 +- .../Source/zip_source_pass_to_lower_layer.c | 91 +++-- .../libzip/Source}/zip_source_pkware_decode.c | 11 +- .../libzip/Source}/zip_source_pkware_encode.c | 45 ++- .../libzip/Source}/zip_source_read.c | 4 +- .../libzip/Source}/zip_source_remove.c | 9 +- .../Source}/zip_source_rollback_write.c | 8 +- .../libzip/Source}/zip_source_seek.c | 4 +- .../libzip/Source}/zip_source_seek_write.c | 9 +- .../libzip/Source}/zip_source_stat.c | 10 +- .../libzip/Source}/zip_source_supports.c | 13 +- .../libzip/Source}/zip_source_tell.c | 4 +- .../libzip/Source}/zip_source_tell_write.c | 9 +- .../libzip/Source}/zip_source_window.c | 109 ++++-- .../libzip/Source}/zip_source_write.c | 4 +- .../libzip/Source}/zip_source_zip.c | 33 +- Libraries/libzip/Source/zip_source_zip_new.c | 312 ++++++++++++++++++ .../libzip/Source}/zip_stat.c | 4 +- .../libzip/Source}/zip_stat_index.c | 39 ++- .../libzip/Source}/zip_stat_init.c | 4 +- .../libzip/Source}/zip_strerror.c | 4 +- .../libzip/Source}/zip_string.c | 6 +- .../libzip/Source}/zip_unchange.c | 29 +- .../libzip/Source}/zip_unchange_all.c | 4 +- .../libzip/Source}/zip_unchange_archive.c | 4 +- .../libzip/Source}/zip_unchange_data.c | 4 +- .../libzip/Source}/zip_utf-8.c | 4 +- Libraries/libzip/libzip_v1.10.1.txt | 1 + README.md | 6 +- Source/CMakeLists.txt | 6 +- Source/Libraries/libzip/zip_err_str.c | 84 ----- Source/Libraries/libzip/zip_source_zip_new.c | 191 ----------- Tests/codecoverage/run_codecoverage.sh | 2 +- submodules/README.md | 4 + submodules/libzip | 1 + submodules/update_libs.bat | 36 ++ submodules/update_libs.sh | 48 +++ 140 files changed, 2351 insertions(+), 1329 deletions(-) delete mode 100644 Include/Libraries/libzip/config.h delete mode 100644 Include/Libraries/libzip/zipconf.h rename {Include/Libraries/libzip => Libraries/libzip/Include}/compat.h (75%) rename {Include/Libraries/libzip => Libraries/libzip/Include}/zip.h (80%) rename {Include/Libraries/libzip => Libraries/libzip/Include}/zip_source_file.h (96%) rename {Include/Libraries/libzip => Libraries/libzip/Include}/zip_source_file_stdio.h (94%) rename {Include/Libraries/libzip => Libraries/libzip/Include}/zip_source_file_win32.h (89%) rename {Include/Libraries/libzip => Libraries/libzip/Include}/zipint.h (83%) rename {Source/Libraries/libzip/Unix => Libraries/libzip/Source/unix}/zip_random_unix.c (93%) rename {Source/Libraries/libzip/Unix => Libraries/libzip/Source/unix}/zip_source_file_stdio_named.c (65%) rename Source/Libraries/libzip/zip_error_strerror.c => Libraries/libzip/Source/win/zip_random_win32.c (57%) rename {Source/Libraries/libzip/Win => Libraries/libzip/Source/win}/zip_source_file_win32.c (96%) create mode 100644 Libraries/libzip/Source/win/zip_source_file_win32_ansi.c rename {Source/Libraries/libzip/Win => Libraries/libzip/Source/win}/zip_source_file_win32_named.c (99%) rename {Source/Libraries/libzip/Win => Libraries/libzip/Source/win}/zip_source_file_win32_utf16.c (94%) rename {Source/Libraries/libzip/Win => Libraries/libzip/Source/win}/zip_source_file_win32_utf8.c (96%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_add.c (94%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_add_dir.c (94%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_add_entry.c (96%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_algorithm_deflate.c (83%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_buffer.c (92%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_close.c (82%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_delete.c (95%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_dir_add.c (92%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_dirent.c (85%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_discard.c (95%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_entry.c (94%) create mode 100644 Libraries/libzip/Source/zip_err_str.c rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_error.c (85%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_error_clear.c (93%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_error_get.c (94%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_error_get_sys_type.c (89%) create mode 100644 Libraries/libzip/Source/zip_error_strerror.c rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_error_to_str.c (71%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_extra_field.c (95%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_extra_field_api.c (95%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_fclose.c (94%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_fdopen.c (92%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_file_add.c (94%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_file_error_clear.c (93%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_file_error_get.c (93%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_file_get_comment.c (94%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_file_get_external_attributes.c (94%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_file_get_offset.c (92%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_file_rename.c (95%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_file_replace.c (97%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_file_set_comment.c (93%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_file_set_encryption.c (94%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_file_set_external_attributes.c (93%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_file_set_mtime.c (83%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_file_strerror.c (93%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_fopen.c (94%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_fopen_encrypted.c (94%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_fopen_index.c (93%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_fopen_index_encrypted.c (89%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_fread.c (90%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_fseek.c (84%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_ftell.c (91%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_get_archive_comment.c (94%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_get_archive_flag.c (94%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_get_encryption_implementation.c (95%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_get_file_comment.c (94%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_get_name.c (94%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_get_num_entries.c (94%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_get_num_files.c (94%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_hash.c (99%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_io_util.c (85%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_libzip_version.c (93%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_memdup.c (92%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_name_locate.c (72%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_new.c (95%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_open.c (77%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_pkware.c (98%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_progress.c (99%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_rename.c (93%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_replace.c (93%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_set_archive_comment.c (92%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_set_archive_flag.c (78%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_set_default_password.c (94%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_set_file_comment.c (94%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_set_file_compression.c (92%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_set_name.c (97%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_accept_empty.c (90%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_begin_write.c (89%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_begin_write_cloning.c (89%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_buffer.c (90%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_call.c (95%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_close.c (94%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_commit_write.c (90%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_compress.c (92%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_crc.c (80%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_error.c (93%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_file_common.c (91%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_file_stdio.c (87%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_free.c (95%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_function.c (93%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_get_file_attributes.c (96%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_is_deleted.c (93%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_layered.c (70%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_open.c (93%) rename Source/Libraries/libzip/Unix/zip_mkstempm.c => Libraries/libzip/Source/zip_source_pass_to_lower_layer.c (53%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_pkware_decode.c (95%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_pkware_encode.c (86%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_read.c (96%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_remove.c (89%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_rollback_write.c (91%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_seek.c (96%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_seek_write.c (89%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_stat.c (87%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_supports.c (83%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_tell.c (95%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_tell_write.c (88%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_window.c (66%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_write.c (94%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_source_zip.c (68%) create mode 100644 Libraries/libzip/Source/zip_source_zip_new.c rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_stat.c (94%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_stat_index.c (66%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_stat_init.c (96%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_strerror.c (93%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_string.c (96%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_unchange.c (77%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_unchange_all.c (94%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_unchange_archive.c (94%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_unchange_data.c (94%) rename {Source/Libraries/libzip => Libraries/libzip/Source}/zip_utf-8.c (98%) create mode 100644 Libraries/libzip/libzip_v1.10.1.txt delete mode 100644 Source/Libraries/libzip/zip_err_str.c delete mode 100644 Source/Libraries/libzip/zip_source_zip_new.c create mode 160000 submodules/libzip diff --git a/.gitmodules b/.gitmodules index ed2779ca9..b804a6518 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,3 +16,6 @@ [submodule "submodules/cpp-base64"] path = submodules/cpp-base64 url = https://github.com/ReneNyffenegger/cpp-base64.git +[submodule "submodules/libzip"] + path = submodules/libzip + url = https://github.com/nih-at/libzip.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 36f92518e..0ab053490 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -129,14 +129,40 @@ target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/I target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Include) if (USE_INCLUDED_LIBZIP) - target_compile_options(${PROJECT_NAME} PRIVATE "-DZIP_STATIC") - target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Include/Libraries/libzip) + target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Libraries/libzip/Include) + if(MSVC) + target_compile_definitions(${PROJECT_NAME} PRIVATE _CRT_SECURE_NO_WARNINGS) + target_compile_definitions(${PROJECT_NAME} PRIVATE _CRT_NONSTDC_NO_DEPRECATE) + endif() + if(WIN32) + target_link_libraries(${PROJECT_NAME} PRIVATE advapi32) + # disable win32 build failing 'initializing': conversion from 'zip_uint64_t' to 'size_t', possible loss of data + if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4") + target_compile_options(${PROJECT_NAME} PRIVATE /wd4244) + endif() + endif() + + # create libzip autogenerated platform specific headers + if(NOT EXISTS ${CMAKE_BINARY_DIR}/libzip) + execute_process( + COMMAND ${CMAKE_COMMAND} "-DZLIB_INCLUDE_DIR=${CMAKE_CURRENT_SOURCE_DIR}/submodules/zlib" + "-DZLIB_LIBRARY=zlibstatic" "-DENABLE_COMMONCRYPTO=OFF" "-DENABLE_GNUTLS=OFF" "-DENABLE_MBEDTLS=OFF" + "-DENABLE_OPENSSL=OFF" "-DENABLE_WINDOWS_CRYPTO=OFF" + "-DENABLE_BZIP2=OFF" "-DENABLE_LZMA=OFF" "-DENABLE_ZSTD=OFF" + "-DBUILD_TOOLS=OFF" "-DBUILD_REGRESS=OFF" + "-DBUILD_EXAMPLES=OFF" "-DBUILD_DOC=OFF" "-DBUILD_SHARED_LIBS=OFF" "-DLIBZIP_DO_INSTALL=OFF" + "-S" "${CMAKE_CURRENT_SOURCE_DIR}/submodules/libzip" "-B" "${CMAKE_CURRENT_BINARY_DIR}/libzip" + RESULT_VARIABLE CMD_ERROR + OUTPUT_QUIET) + MESSAGE( STATUS "CMD_ERROR:" ${CMD_ERROR}) + endif() + target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/libzip) if (UNIX OR MINGW) - target_compile_options(${PROJECT_NAME} PRIVATE "-DHAVE_FSEEKO") - target_compile_options(${PROJECT_NAME} PRIVATE "-DHAVE_FTELLO") - target_compile_options(${PROJECT_NAME} PRIVATE "-DHAVE_STRCASECMP") - target_compile_options(${PROJECT_NAME} PRIVATE "-DHAVE_UNISTD_H") + target_compile_options(${PROJECT_NAME} PRIVATE "-DHAVE_FSEEKO") + target_compile_options(${PROJECT_NAME} PRIVATE "-DHAVE_FTELLO") + target_compile_options(${PROJECT_NAME} PRIVATE "-DHAVE_STRCASECMP") + target_compile_options(${PROJECT_NAME} PRIVATE "-DHAVE_UNISTD_H") endif() else() @@ -144,6 +170,8 @@ else() pkg_check_modules(LIBZIP REQUIRED libzip) target_link_libraries(${PROJECT_NAME} ${LIBZIP_LIBRARIES}) endif() + + if (USE_INCLUDED_ZLIB) target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Libraries/zlib/Include) else() diff --git a/Include/Common/OPC/NMR_OpcPackageReader.h b/Include/Common/OPC/NMR_OpcPackageReader.h index 81f0a0ed2..3e1987609 100644 --- a/Include/Common/OPC/NMR_OpcPackageReader.h +++ b/Include/Common/OPC/NMR_OpcPackageReader.h @@ -40,7 +40,7 @@ NMR_OpcPackageReader.h defines an OPC Package reader in a portable way. #include "Common/OPC/NMR_OpcPackageRelationship.h" #include "Common/3MF_ProgressMonitor.h" #include "Common/NMR_ModelWarnings.h" -#include "Libraries/libzip/zip.h" +#include "zip.h" #include #include #include diff --git a/Include/Common/Platform/NMR_ImportStream_ZIP.h b/Include/Common/Platform/NMR_ImportStream_ZIP.h index e834e24dd..a7509e51b 100644 --- a/Include/Common/Platform/NMR_ImportStream_ZIP.h +++ b/Include/Common/Platform/NMR_ImportStream_ZIP.h @@ -35,7 +35,7 @@ This is a stream class for importing from a libZIP object. #define __NMR_IMPORTSTREAM_ZIP #include "Common/Platform/NMR_ImportStream.h" -#include "Libraries/libzip/zip.h" +#include "zip.h" #define IMPORTSTREAM_ZIP_CHUNKSIZE (1024 * 1024) diff --git a/Include/Libraries/libzip/config.h b/Include/Libraries/libzip/config.h deleted file mode 100644 index 5112dd967..000000000 --- a/Include/Libraries/libzip/config.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef HAD_CONFIG_H -#define HAD_CONFIG_H -#ifndef _HAD_ZIPCONF_H -#include "zipconf.h" -#endif -/* BEGIN DEFINES */ -/* #undef HAVE___PROGNAME */ -#define HAVE__CLOSE -#define HAVE__DUP -#define HAVE__FDOPEN -#define HAVE__FILENO -#define HAVE__SETMODE -/* #undef HAVE__SNPRINTF */ -#define HAVE__STRDUP -#define HAVE__STRICMP -#define HAVE__STRTOI64 -#define HAVE__STRTOUI64 -/* #undef HAVE__UMASK */ -#define HAVE__UNLINK -/* #undef HAVE_ARC4RANDOM */ -/* #undef HAVE_CLONEFILE */ -/* #undef HAVE_COMMONCRYPTO */ -/* #define HAVE_CRYPTO */ -/* #undef HAVE_FICLONERANGE */ -#define HAVE_FILENO -/* #undef HAVE_FSEEKO */ -/* #undef HAVE_FTELLO */ -/* #undef HAVE_GETPROGNAME */ -/* #undef HAVE_GNUTLS */ -/* #undef HAVE_LIBBZ2 */ -/* #undef HAVE_LIBLZMA */ -/* #undef HAVE_LIBZSTD */ -/* #undef HAVE_LOCALTIME_R */ -/* #undef HAVE_MBEDTLS */ -/* #undef HAVE_MKSTEMP */ -/* #undef HAVE_NULLABLE */ -/* #undef HAVE_OPENSSL */ -#define HAVE_SETMODE -/* #undef HAVE_STRCASECMP */ -#define HAVE_STRDUP -#define HAVE_STRICMP -#define HAVE_STRTOLL -#define HAVE_STRTOULL -/* #undef HAVE_STRUCT_TM_TM_ZONE */ -#define HAVE_STDBOOL_H -/* #undef HAVE_STRINGS_H */ -/* #undef HAVE_UNISTD_H */ -/* #define HAVE_WINDOWS_CRYPTO */ -#define SIZEOF_OFF_T 4 -#define SIZEOF_SIZE_T 8 -/* #undef HAVE_DIRENT_H */ -/* #undef HAVE_FTS_H */ -/* #undef HAVE_NDIR_H */ -/* #undef HAVE_SYS_DIR_H */ -/* #undef HAVE_SYS_NDIR_H */ -/* #undef WORDS_BIGENDIAN */ -#define HAVE_SHARED -/* END DEFINES */ -#define PACKAGE "libzip" -#define VERSION "1.7.3.1" - -#endif /* HAD_CONFIG_H */ diff --git a/Include/Libraries/libzip/zipconf.h b/Include/Libraries/libzip/zipconf.h deleted file mode 100644 index f6e9ed0e4..000000000 --- a/Include/Libraries/libzip/zipconf.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef _HAD_ZIPCONF_H -#define _HAD_ZIPCONF_H - -/* - zipconf.h -- platform specific include file - - This file was generated automatically by CMake - based on ../cmake-zipconf.h.in. - */ - -#define LIBZIP_VERSION "1.7.3.1" -#define LIBZIP_VERSION_MAJOR 1 -#define LIBZIP_VERSION_MINOR 7 -#define LIBZIP_VERSION_MICRO 3 - -/* #undef ZIP_STATIC */ - -#define _Nullable -#define _Nonnull - -#if !defined(__STDC_FORMAT_MACROS) -#define __STDC_FORMAT_MACROS 1 -#endif -#include - -typedef int8_t zip_int8_t; -typedef uint8_t zip_uint8_t; -typedef int16_t zip_int16_t; -typedef uint16_t zip_uint16_t; -typedef int32_t zip_int32_t; -typedef uint32_t zip_uint32_t; -typedef int64_t zip_int64_t; -typedef uint64_t zip_uint64_t; - -#define ZIP_INT8_MIN (-ZIP_INT8_MAX-1) -#define ZIP_INT8_MAX 0x7f -#define ZIP_UINT8_MAX 0xff - -#define ZIP_INT16_MIN (-ZIP_INT16_MAX-1) -#define ZIP_INT16_MAX 0x7fff -#define ZIP_UINT16_MAX 0xffff - -#define ZIP_INT32_MIN (-ZIP_INT32_MAX-1L) -#define ZIP_INT32_MAX 0x7fffffffL -#define ZIP_UINT32_MAX 0xffffffffLU - -#define ZIP_INT64_MIN (-ZIP_INT64_MAX-1LL) -#define ZIP_INT64_MAX 0x7fffffffffffffffLL -#define ZIP_UINT64_MAX 0xffffffffffffffffULL - -#endif /* zipconf.h */ diff --git a/Include/Libraries/libzip/compat.h b/Libraries/libzip/Include/compat.h similarity index 75% rename from Include/Libraries/libzip/compat.h rename to Libraries/libzip/Include/compat.h index 257e0ab45..384a611ff 100644 --- a/Include/Libraries/libzip/compat.h +++ b/Libraries/libzip/Include/compat.h @@ -3,10 +3,10 @@ /* compat.h -- compatibility defines. - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -41,6 +41,9 @@ /* to have *_MAX definitions for all types when compiling with g++ */ #define __STDC_LIMIT_MACROS +/* to have ISO C secure library functions */ +#define __STDC_WANT_LIB_EXT1__ 1 + #ifdef _WIN32 #ifndef ZIP_EXTERN #ifndef ZIP_STATIC @@ -94,9 +97,12 @@ typedef char bool; #if !defined(HAVE_FILENO) && defined(HAVE__FILENO) #define fileno _fileno #endif -#if defined(HAVE__SNPRINTF) +#if !defined(HAVE_SNPRINTF) && defined(HAVE__SNPRINTF) #define snprintf _snprintf #endif +#if !defined(HAVE__SNWPRINTF_S) +#define _snwprintf_s(buf, bufsz, len, fmt, ...) (_snwprintf((buf), (len), (fmt), __VA_ARGS__)) +#endif #if defined(HAVE__STRDUP) #if !defined(HAVE_STRDUP) || defined(_WIN32) #undef strdup @@ -125,6 +131,33 @@ typedef char bool; #define ftello(s) ((long)ftell((s))) #endif +#ifdef HAVE_LOCALTIME_S +#ifdef _WIN32 +/* Windows is incompatible to the C11 standard, hurray! */ +#define zip_localtime(t, tm) (localtime_s((tm), (t)) == 0 ? tm : NULL) +#else +#define zip_localtime localtime_s +#endif +#else +#ifdef HAVE_LOCALTIME_R +#define zip_localtime localtime_r +#else +#define zip_localtime(t, tm) (localtime(t)) +#endif +#endif + +#ifndef HAVE_MEMCPY_S +#define memcpy_s(dest, destsz, src, count) (memcpy((dest), (src), (count)) == NULL) +#endif + +#ifndef HAVE_SNPRINTF_S +#ifdef HAVE__SNPRINTF_S +#define snprintf_s(buf, bufsz, fmt, ...) (_snprintf_s((buf), (bufsz), (bufsz), (fmt), __VA_ARGS__)) +#else +#define snprintf_s snprintf +#endif +#endif + #if !defined(HAVE_STRCASECMP) #if defined(HAVE__STRICMP) #define strcasecmp _stricmp @@ -133,6 +166,19 @@ typedef char bool; #endif #endif +#ifndef HAVE_STRNCPY_S +#define strncpy_s(dest, destsz, src, count) (strncpy((dest), (src), (count)), 0) +#endif + +#ifndef HAVE_STRERROR_S +#define strerrorlen_s(errnum) (strlen(strerror(errnum))) +#define strerror_s(buf, bufsz, errnum) ((void)strncpy_s((buf), (bufsz), strerror(errnum), (bufsz)), (buf)[(bufsz)-1] = '\0', strerrorlen_s(errnum) >= (bufsz)) +#else +#ifndef HAVE_STRERRORLEN_S +#define strerrorlen_s(errnum) 8192 +#endif +#endif + #if SIZEOF_OFF_T == 8 #define ZIP_OFF_MAX ZIP_INT64_MAX #define ZIP_OFF_MIN ZIP_INT64_MIN diff --git a/Include/Libraries/libzip/zip.h b/Libraries/libzip/Include/zip.h similarity index 80% rename from Include/Libraries/libzip/zip.h rename to Libraries/libzip/Include/zip.h index 4a1bf8912..0d31d4068 100644 --- a/Include/Libraries/libzip/zip.h +++ b/Libraries/libzip/Include/zip.h @@ -3,10 +3,10 @@ /* zip.h -- exported declarations. - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -58,6 +58,16 @@ extern "C" { #endif #endif +#ifndef ZIP_DEPRECATED +#if defined(__GNUC__) || defined(__clang__) +#define ZIP_DEPRECATED(x) __attribute__((deprecated(x))) +#elif defined(_MSC_VER) +#define ZIP_DEPRECATED(x) __declspec(deprecated(x)) +#else +#define ZIP_DEPRECATED(x) +#endif +#endif + #include #include #include @@ -77,7 +87,7 @@ extern "C" { #define ZIP_FL_NODIR 2u /* ignore directory component */ #define ZIP_FL_COMPRESSED 4u /* read compressed data */ #define ZIP_FL_UNCHANGED 8u /* use original data, ignoring changes */ -#define ZIP_FL_RECOMPRESS 16u /* force recompression of data */ +/* 16u was ZIP_FL_RECOMPRESS, which is deprecated */ #define ZIP_FL_ENCRYPTED 32u /* read encrypted data (implies ZIP_FL_COMPRESSED) */ #define ZIP_FL_ENC_GUESS 0u /* guess string encoding (is default) */ #define ZIP_FL_ENC_RAW 64u /* get unmodified string */ @@ -91,7 +101,10 @@ extern "C" { /* archive global flags flags */ -#define ZIP_AFL_RDONLY 2u /* read only -- cannot be cleared */ +#define ZIP_AFL_RDONLY 2u /* read only -- cannot be cleared */ +#define ZIP_AFL_IS_TORRENTZIP 4u /* current archive is torrentzipped */ +#define ZIP_AFL_WANT_TORRENTZIP 8u /* write archive in torrentzip format */ +#define ZIP_AFL_CREATE_OR_KEEP_FILE_FOR_EMPTY_ARCHIVE 16u /* don't remove file if archive is empty */ /* create a new extra field */ @@ -99,6 +112,10 @@ extern "C" { #define ZIP_EXTRA_FIELD_ALL ZIP_UINT16_MAX #define ZIP_EXTRA_FIELD_NEW ZIP_UINT16_MAX +/* length parameter to various functions */ + +#define ZIP_LENGTH_TO_END 0 +#define ZIP_LENGTH_UNCHECKED (-2) /* only supported by zip_source_file and its variants */ /* libzip error codes */ @@ -123,7 +140,7 @@ extern "C" { #define ZIP_ER_INVAL 18 /* N Invalid argument */ #define ZIP_ER_NOZIP 19 /* N Not a zip archive */ #define ZIP_ER_INTERNAL 20 /* N Internal error */ -#define ZIP_ER_INCONS 21 /* N Zip archive inconsistent */ +#define ZIP_ER_INCONS 21 /* L Zip archive inconsistent */ #define ZIP_ER_REMOVE 22 /* S Can't remove file */ #define ZIP_ER_DELETED 23 /* N Entry has been deleted */ #define ZIP_ER_ENCRNOTSUPP 24 /* N Encryption method not supported */ @@ -135,12 +152,15 @@ extern "C" { #define ZIP_ER_TELL 30 /* S Tell error */ #define ZIP_ER_COMPRESSED_DATA 31 /* N Compressed data invalid */ #define ZIP_ER_CANCELLED 32 /* N Operation cancelled */ +#define ZIP_ER_DATA_LENGTH 33 /* N Unexpected length of data */ +#define ZIP_ER_NOT_ALLOWED 34 /* N Not allowed in torrentzip */ /* type of system error value */ -#define ZIP_ET_NONE 0 /* sys_err unused */ -#define ZIP_ET_SYS 1 /* sys_err is errno */ -#define ZIP_ET_ZLIB 2 /* sys_err is zlib error code */ +#define ZIP_ET_NONE 0 /* sys_err unused */ +#define ZIP_ET_SYS 1 /* sys_err is errno */ +#define ZIP_ET_ZLIB 2 /* sys_err is zlib error code */ +#define ZIP_ET_LIBZIP 3 /* sys_err is libzip error code */ /* compression methods */ @@ -235,12 +255,15 @@ enum zip_source_cmd { ZIP_SOURCE_RESERVED_1, /* previously used internally */ ZIP_SOURCE_BEGIN_WRITE_CLONING, /* like ZIP_SOURCE_BEGIN_WRITE, but keep part of original file */ ZIP_SOURCE_ACCEPT_EMPTY, /* whether empty files are valid archives */ - ZIP_SOURCE_GET_FILE_ATTRIBUTES /* get additional file attributes */ + ZIP_SOURCE_GET_FILE_ATTRIBUTES, /* get additional file attributes */ + ZIP_SOURCE_SUPPORTS_REOPEN /* allow reading from changed entry */ }; typedef enum zip_source_cmd zip_source_cmd_t; #define ZIP_SOURCE_MAKE_COMMAND_BITMASK(cmd) (((zip_int64_t)1) << (cmd)) +#define ZIP_SOURCE_CHECK_SUPPORTED(supported, cmd) (((supported) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(cmd)) != 0) + /* clang-format off */ #define ZIP_SOURCE_SUPPORTS_READABLE (ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_OPEN) \ @@ -344,24 +367,29 @@ typedef struct zip_buffer_fragment zip_buffer_fragment_t; typedef zip_uint32_t zip_flags_t; typedef zip_int64_t (*zip_source_callback)(void *_Nullable, void *_Nullable, zip_uint64_t, zip_source_cmd_t); +typedef zip_int64_t (*zip_source_layered_callback)(zip_source_t *_Nonnull, void *_Nullable, void *_Nullable, zip_uint64_t, enum zip_source_cmd); typedef void (*zip_progress_callback)(zip_t *_Nonnull, double, void *_Nullable); typedef int (*zip_cancel_callback)(zip_t *_Nonnull, void *_Nullable); #ifndef ZIP_DISABLE_DEPRECATED +#define ZIP_FL_RECOMPRESS 16u /* force recompression of data */ + typedef void (*zip_progress_callback_t)(double); -ZIP_EXTERN void zip_register_progress_callback(zip_t *_Nonnull, zip_progress_callback_t _Nullable); /* use zip_register_progress_callback_with_state */ - -ZIP_EXTERN zip_int64_t zip_add(zip_t *_Nonnull, const char *_Nonnull, zip_source_t *_Nonnull); /* use zip_file_add */ -ZIP_EXTERN zip_int64_t zip_add_dir(zip_t *_Nonnull, const char *_Nonnull); /* use zip_dir_add */ -ZIP_EXTERN const char *_Nullable zip_get_file_comment(zip_t *_Nonnull, zip_uint64_t, int *_Nullable, int); /* use zip_file_get_comment */ -ZIP_EXTERN int zip_get_num_files(zip_t *_Nonnull); /* use zip_get_num_entries instead */ -ZIP_EXTERN int zip_rename(zip_t *_Nonnull, zip_uint64_t, const char *_Nonnull); /* use zip_file_rename */ -ZIP_EXTERN int zip_replace(zip_t *_Nonnull, zip_uint64_t, zip_source_t *_Nonnull); /* use zip_file_replace */ -ZIP_EXTERN int zip_set_file_comment(zip_t *_Nonnull, zip_uint64_t, const char *_Nullable, int); /* use zip_file_set_comment */ -ZIP_EXTERN int zip_error_get_sys_type(int); /* use zip_error_system_type */ -ZIP_EXTERN void zip_error_get(zip_t *_Nonnull, int *_Nullable, int *_Nullable); /* use zip_get_error, zip_error_code_zip / zip_error_code_system */ -ZIP_EXTERN int zip_error_to_str(char *_Nonnull, zip_uint64_t, int, int); /* use zip_error_init_with_code / zip_error_strerror */ -ZIP_EXTERN void zip_file_error_get(zip_file_t *_Nonnull, int *_Nullable, int *_Nullable); /* use zip_file_get_error, zip_error_code_zip / zip_error_code_system */ +ZIP_DEPRECATED("use 'zip_register_progress_callback_with_state' instead") ZIP_EXTERN void zip_register_progress_callback(zip_t *_Nonnull, zip_progress_callback_t _Nullable); + +ZIP_DEPRECATED("use 'zip_file_add' instead") ZIP_EXTERN zip_int64_t zip_add(zip_t *_Nonnull, const char *_Nonnull, zip_source_t *_Nonnull); +ZIP_DEPRECATED("use 'zip_dir_add' instead") ZIP_EXTERN zip_int64_t zip_add_dir(zip_t *_Nonnull, const char *_Nonnull); +ZIP_DEPRECATED("use 'zip_file_get_comment' instead") ZIP_EXTERN const char *_Nullable zip_get_file_comment(zip_t *_Nonnull, zip_uint64_t, int *_Nullable, int); +ZIP_DEPRECATED("use 'zip_get_num_entries' instead") ZIP_EXTERN int zip_get_num_files(zip_t *_Nonnull); +ZIP_DEPRECATED("use 'zip_file_rename' instead") ZIP_EXTERN int zip_rename(zip_t *_Nonnull, zip_uint64_t, const char *_Nonnull); +ZIP_DEPRECATED("use 'zip_file_replace' instead") ZIP_EXTERN int zip_replace(zip_t *_Nonnull, zip_uint64_t, zip_source_t *_Nonnull); +ZIP_DEPRECATED("use 'zip_file_set_comment' instead") ZIP_EXTERN int zip_set_file_comment(zip_t *_Nonnull, zip_uint64_t, const char *_Nullable, int); +ZIP_DEPRECATED("use 'zip_error_init_with_code' and 'zip_error_system_type' instead") ZIP_EXTERN int zip_error_get_sys_type(int); +ZIP_DEPRECATED("use 'zip_get_error' instead") ZIP_EXTERN void zip_error_get(zip_t *_Nonnull, int *_Nullable, int *_Nullable); +ZIP_DEPRECATED("use 'zip_error_strerror' instead") ZIP_EXTERN int zip_error_to_str(char *_Nonnull, zip_uint64_t, int, int); +ZIP_DEPRECATED("use 'zip_file_get_error' instead") ZIP_EXTERN void zip_file_error_get(zip_file_t *_Nonnull, int *_Nullable, int *_Nullable); +ZIP_DEPRECATED("use 'zip_source_zip_file' instead") ZIP_EXTERN zip_source_t *_Nullable zip_source_zip(zip_t *_Nonnull, zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_int64_t); +ZIP_DEPRECATED("use 'zip_source_zip_file_create' instead") ZIP_EXTERN zip_source_t *_Nullable zip_source_zip_create(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_int64_t, zip_error_t *_Nullable); #endif ZIP_EXTERN int zip_close(zip_t *_Nonnull); @@ -377,6 +405,7 @@ ZIP_EXTERN void zip_error_fini(zip_error_t *_Nonnull); ZIP_EXTERN void zip_error_init(zip_error_t *_Nonnull); ZIP_EXTERN void zip_error_init_with_code(zip_error_t *_Nonnull, int); ZIP_EXTERN void zip_error_set(zip_error_t *_Nullable, int, int); +ZIP_EXTERN void zip_error_set_from_source(zip_error_t *_Nonnull, zip_source_t *_Nullable); ZIP_EXTERN const char *_Nonnull zip_error_strerror(zip_error_t *_Nonnull); ZIP_EXTERN int zip_error_system_type(const zip_error_t *_Nonnull); ZIP_EXTERN zip_int64_t zip_error_to_data(const zip_error_t *_Nonnull, void *_Nonnull, zip_uint64_t); @@ -396,6 +425,7 @@ ZIP_EXTERN const zip_uint8_t *_Nullable zip_file_extra_field_get_by_id(zip_t *_N ZIP_EXTERN const char *_Nullable zip_file_get_comment(zip_t *_Nonnull, zip_uint64_t, zip_uint32_t *_Nullable, zip_flags_t); ZIP_EXTERN zip_error_t *_Nonnull zip_file_get_error(zip_file_t *_Nonnull); ZIP_EXTERN int zip_file_get_external_attributes(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint8_t *_Nullable, zip_uint32_t *_Nullable); +ZIP_EXTERN int zip_file_is_seekable(zip_file_t *_Nonnull); ZIP_EXTERN int zip_file_rename(zip_t *_Nonnull, zip_uint64_t, const char *_Nonnull, zip_flags_t); ZIP_EXTERN int zip_file_replace(zip_t *_Nonnull, zip_uint64_t, zip_source_t *_Nonnull, zip_flags_t); ZIP_EXTERN int zip_file_set_comment(zip_t *_Nonnull, zip_uint64_t, const char *_Nullable, zip_uint16_t, zip_flags_t); @@ -443,9 +473,13 @@ ZIP_EXTERN zip_source_t *_Nullable zip_source_function(zip_t *_Nonnull, zip_sour ZIP_EXTERN zip_source_t *_Nullable zip_source_function_create(zip_source_callback _Nonnull, void *_Nullable, zip_error_t *_Nullable); ZIP_EXTERN int zip_source_get_file_attributes(zip_source_t *_Nonnull, zip_file_attributes_t *_Nonnull); ZIP_EXTERN int zip_source_is_deleted(zip_source_t *_Nonnull); +ZIP_EXTERN int zip_source_is_seekable(zip_source_t *_Nonnull); ZIP_EXTERN void zip_source_keep(zip_source_t *_Nonnull); +ZIP_EXTERN zip_source_t *_Nullable zip_source_layered(zip_t *_Nullable, zip_source_t *_Nonnull, zip_source_layered_callback _Nonnull, void *_Nullable); +ZIP_EXTERN zip_source_t *_Nullable zip_source_layered_create(zip_source_t *_Nonnull, zip_source_layered_callback _Nonnull, void *_Nullable, zip_error_t *_Nullable); ZIP_EXTERN zip_int64_t zip_source_make_command_bitmap(zip_source_cmd_t, ...); ZIP_EXTERN int zip_source_open(zip_source_t *_Nonnull); +ZIP_EXTERN zip_int64_t zip_source_pass_to_lower_layer(zip_source_t *_Nonnull, void *_Nullable, zip_uint64_t, zip_source_cmd_t); ZIP_EXTERN zip_int64_t zip_source_read(zip_source_t *_Nonnull, void *_Nonnull, zip_uint64_t); ZIP_EXTERN void zip_source_rollback_write(zip_source_t *_Nonnull); ZIP_EXTERN int zip_source_seek(zip_source_t *_Nonnull, zip_int64_t, int); @@ -455,15 +489,17 @@ ZIP_EXTERN int zip_source_stat(zip_source_t *_Nonnull, zip_stat_t *_Nonnull); ZIP_EXTERN zip_int64_t zip_source_tell(zip_source_t *_Nonnull); ZIP_EXTERN zip_int64_t zip_source_tell_write(zip_source_t *_Nonnull); #ifdef _WIN32 -ZIP_EXTERN zip_source_t *zip_source_win32a(zip_t *, const char *, zip_uint64_t, zip_int64_t); -ZIP_EXTERN zip_source_t *zip_source_win32a_create(const char *, zip_uint64_t, zip_int64_t, zip_error_t *); -ZIP_EXTERN zip_source_t *zip_source_win32handle(zip_t *, void *, zip_uint64_t, zip_int64_t); -ZIP_EXTERN zip_source_t *zip_source_win32handle_create(void *, zip_uint64_t, zip_int64_t, zip_error_t *); -ZIP_EXTERN zip_source_t *zip_source_win32w(zip_t *, const wchar_t *, zip_uint64_t, zip_int64_t); -ZIP_EXTERN zip_source_t *zip_source_win32w_create(const wchar_t *, zip_uint64_t, zip_int64_t, zip_error_t *); +ZIP_EXTERN zip_source_t *_Nullable zip_source_win32a(zip_t *_Nonnull, const char *_Nonnull, zip_uint64_t, zip_int64_t); +ZIP_EXTERN zip_source_t *_Nullable zip_source_win32a_create(const char *_Nonnull, zip_uint64_t, zip_int64_t, zip_error_t *_Nullable); +ZIP_EXTERN zip_source_t *_Nullable zip_source_win32handle(zip_t *_Nonnull, void *_Nonnull, zip_uint64_t, zip_int64_t); +ZIP_EXTERN zip_source_t *_Nullable zip_source_win32handle_create(void *_Nonnull, zip_uint64_t, zip_int64_t, zip_error_t *_Nullable); +ZIP_EXTERN zip_source_t *_Nullable zip_source_win32w(zip_t *_Nonnull, const wchar_t *_Nonnull, zip_uint64_t, zip_int64_t); +ZIP_EXTERN zip_source_t *_Nullable zip_source_win32w_create(const wchar_t *_Nonnull, zip_uint64_t, zip_int64_t, zip_error_t *_Nullable); #endif +ZIP_EXTERN zip_source_t *_Nullable zip_source_window_create(zip_source_t *_Nonnull, zip_uint64_t, zip_int64_t, zip_error_t *_Nullable); ZIP_EXTERN zip_int64_t zip_source_write(zip_source_t *_Nonnull, const void *_Nullable, zip_uint64_t); -ZIP_EXTERN zip_source_t *_Nullable zip_source_zip(zip_t *_Nonnull, zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_int64_t); +ZIP_EXTERN zip_source_t *_Nullable zip_source_zip_file(zip_t *_Nonnull, zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_int64_t, const char *_Nullable); +ZIP_EXTERN zip_source_t *_Nullable zip_source_zip_file_create(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_int64_t, const char *_Nullable, zip_error_t *_Nullable); ZIP_EXTERN int zip_stat(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t, zip_stat_t *_Nonnull); ZIP_EXTERN int zip_stat_index(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_stat_t *_Nonnull); ZIP_EXTERN void zip_stat_init(zip_stat_t *_Nonnull); diff --git a/Include/Libraries/libzip/zip_source_file.h b/Libraries/libzip/Include/zip_source_file.h similarity index 96% rename from Include/Libraries/libzip/zip_source_file.h rename to Libraries/libzip/Include/zip_source_file.h index 43a464533..cca9fd2b5 100644 --- a/Include/Libraries/libzip/zip_source_file.h +++ b/Libraries/libzip/Include/zip_source_file.h @@ -1,9 +1,9 @@ /* zip_source_file.h -- header for common file operations - Copyright (C) 2020 Dieter Baron and Thomas Klausner + Copyright (C) 2020-2022 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -34,7 +34,7 @@ struct zip_source_file_stat { zip_uint64_t size; /* must be valid for regular files */ time_t mtime; /* must always be valid, is initialized to current time */ - bool exists; /* must always be vaild */ + bool exists; /* must always be valid */ bool regular_file; /* must always be valid */ }; diff --git a/Include/Libraries/libzip/zip_source_file_stdio.h b/Libraries/libzip/Include/zip_source_file_stdio.h similarity index 94% rename from Include/Libraries/libzip/zip_source_file_stdio.h rename to Libraries/libzip/Include/zip_source_file_stdio.h index 1bf698ce2..802e6071f 100644 --- a/Include/Libraries/libzip/zip_source_file_stdio.h +++ b/Libraries/libzip/Include/zip_source_file_stdio.h @@ -6,7 +6,7 @@ Copyright (C) 2020 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -42,6 +42,4 @@ bool _zip_stdio_op_seek(zip_source_file_context_t *ctx, void *f, zip_int64_t off bool _zip_stdio_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st); zip_int64_t _zip_stdio_op_tell(zip_source_file_context_t *ctx, void *f); -FILE *_zip_fopen_close_on_exec(const char *name, bool writeable); - #endif /* _HAD_ZIP_SOURCE_FILE_STDIO_H */ diff --git a/Include/Libraries/libzip/zip_source_file_win32.h b/Libraries/libzip/Include/zip_source_file_win32.h similarity index 89% rename from Include/Libraries/libzip/zip_source_file_win32.h rename to Libraries/libzip/Include/zip_source_file_win32.h index 88e45b1f9..d86069eca 100644 --- a/Include/Libraries/libzip/zip_source_file_win32.h +++ b/Libraries/libzip/Include/zip_source_file_win32.h @@ -6,7 +6,7 @@ Copyright (C) 2020 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -73,4 +73,12 @@ zip_int64_t _zip_win32_op_tell(zip_source_file_context_t *ctx, void *f); bool _zip_filetime_to_time_t(FILETIME ft, time_t *t); int _zip_win32_error_to_errno(DWORD win32err); +#ifdef __clang__ +#define DONT_WARN_INCOMPATIBLE_FN_PTR_BEGIN _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wincompatible-function-pointer-types\"") +#define DONT_WARN_INCOMPATIBLE_FN_PTR_END _Pragma("GCC diagnostic pop") +#else +#define DONT_WARN_INCOMPATIBLE_FN_PTR_BEGIN +#define DONT_WARN_INCOMPATIBLE_FN_PTR_END +#endif + #endif /* _HAD_ZIP_SOURCE_FILE_WIN32_H */ diff --git a/Include/Libraries/libzip/zipint.h b/Libraries/libzip/Include/zipint.h similarity index 83% rename from Include/Libraries/libzip/zipint.h rename to Libraries/libzip/Include/zipint.h index 65e602c73..4887b6c5c 100644 --- a/Include/Libraries/libzip/zipint.h +++ b/Libraries/libzip/Include/zipint.h @@ -3,10 +3,10 @@ /* zipint.h -- internal declarations. - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -42,7 +42,9 @@ #include #endif -#ifndef _ZIP_COMPILING_DEPRECATED +#ifdef _ZIP_COMPILING_DEPRECATED +#define ZIP_DEPRECATED(x) +#else #define ZIP_DISABLE_DEPRECATED #endif @@ -67,6 +69,12 @@ #define EF_WINZIP_AES_SIZE 7 #define MAX_DATA_DESCRIPTOR_LENGTH 24 +#define TORRENTZIP_SIGNATURE "TORRENTZIPPED-" +#define TORRENTZIP_SIGNATURE_LENGTH 14 +#define TORRENTZIP_CRC_LENGTH 8 +#define TORRENTZIP_MEM_LEVEL 8 +#define TORRENTZIP_COMPRESSION_FLAGS ZIP_UINT16_MAX + #define ZIP_CRYPTO_PKWARE_HEADERLEN 12 #define ZIP_CM_REPLACED_DEFAULT (-2) @@ -76,7 +84,6 @@ #define WINZIP_AES_MAX_HEADER_LENGTH (16 + WINZIP_AES_PASSWORD_VERIFY_LENGTH) #define AES_BLOCK_SIZE 16 #define HMAC_LENGTH 10 -#define SHA1_LENGTH 20 #define SALT_LENGTH(method) ((method) == ZIP_EM_AES_128 ? 8 : ((method) == ZIP_EM_AES_192 ? 12 : 16)) #define ZIP_CM_IS_DEFAULT(x) ((x) == ZIP_CM_DEFAULT || (x) == ZIP_CM_REPLACED_DEFAULT) @@ -122,11 +129,11 @@ enum zip_compression_status { typedef enum zip_compression_status zip_compression_status_t; struct zip_compression_algorithm { - /* Return maxiumum compressed size for uncompressed data of given size. */ + /* Return maximum compressed size for uncompressed data of given size. */ zip_uint64_t (*maximum_compressed_size)(zip_uint64_t uncompressed_size); /* called once to create new context */ - void *(*allocate)(zip_uint16_t method, int compression_flags, zip_error_t *error); + void *(*allocate)(zip_uint16_t method, zip_uint32_t compression_flags, zip_error_t *error); /* called once to free context */ void (*deallocate)(void *ctx); @@ -170,25 +177,65 @@ const zip_uint8_t *zip_get_extra_field_by_id(zip_t *, int, int, zip_uint16_t, in user-supplied compression/encryption implementation is finished. Thus we will keep it private for now. */ -typedef zip_int64_t (*zip_source_layered_callback)(zip_source_t *, void *, void *, zip_uint64_t, enum zip_source_cmd); -zip_source_t *zip_source_compress(zip_t *za, zip_source_t *src, zip_int32_t cm, int compression_flags); -zip_source_t *zip_source_crc(zip_t *, zip_source_t *, int); +zip_source_t *zip_source_compress(zip_t *za, zip_source_t *src, zip_int32_t cm, zip_uint32_t compression_flags); +zip_source_t *zip_source_crc_create(zip_source_t *, int, zip_error_t *error); zip_source_t *zip_source_decompress(zip_t *za, zip_source_t *src, zip_int32_t cm); -zip_source_t *zip_source_layered(zip_t *, zip_source_t *, zip_source_layered_callback, void *); -zip_source_t *zip_source_layered_create(zip_source_t *src, zip_source_layered_callback cb, void *ud, zip_error_t *error); zip_source_t *zip_source_pkware_decode(zip_t *, zip_source_t *, zip_uint16_t, int, const char *); zip_source_t *zip_source_pkware_encode(zip_t *, zip_source_t *, zip_uint16_t, int, const char *); int zip_source_remove(zip_source_t *); zip_int64_t zip_source_supports(zip_source_t *src); -zip_source_t *zip_source_window(zip_t *, zip_source_t *, zip_uint64_t, zip_uint64_t); -// zip_source_t *zip_source_winzip_aes_decode(zip_t *, zip_source_t *, zip_uint16_t, int, const char *); -// zip_source_t *zip_source_winzip_aes_encode(zip_t *, zip_source_t *, zip_uint16_t, int, const char *); +bool zip_source_supports_reopen(zip_source_t *src); +zip_source_t *zip_source_winzip_aes_decode(zip_t *, zip_source_t *, zip_uint16_t, int, const char *); +zip_source_t *zip_source_winzip_aes_encode(zip_t *, zip_source_t *, zip_uint16_t, int, const char *); zip_source_t *zip_source_buffer_with_attributes(zip_t *za, const void *data, zip_uint64_t len, int freep, zip_file_attributes_t *attributes); +zip_source_t *zip_source_buffer_with_attributes_create(const void *data, zip_uint64_t len, int freep, zip_file_attributes_t *attributes, zip_error_t *error); /* error source for layered sources */ enum zip_les { ZIP_LES_NONE, ZIP_LES_UPPER, ZIP_LES_LOWER, ZIP_LES_INVAL }; +#define ZIP_DETAIL_ET_GLOBAL 0 +#define ZIP_DETAIL_ET_ENTRY 1 + +struct _zip_err_info { + int type; + const char *description; +}; + +extern const struct _zip_err_info _zip_err_str[]; +extern const int _zip_err_str_count; +extern const struct _zip_err_info _zip_err_details[]; +extern const int _zip_err_details_count; + +/* macros for libzip-internal errors */ +#define MAX_DETAIL_INDEX 0x7fffff +#define MAKE_DETAIL_WITH_INDEX(error, index) ((((index) > MAX_DETAIL_INDEX) ? MAX_DETAIL_INDEX : (int)(index)) << 8 | (error)) +#define GET_INDEX_FROM_DETAIL(error) (((error) >> 8) & MAX_DETAIL_INDEX) +#define GET_ERROR_FROM_DETAIL(error) ((error) & 0xff) +#define ADD_INDEX_TO_DETAIL(error, index) MAKE_DETAIL_WITH_INDEX(GET_ERROR_FROM_DETAIL(error), (index)) + +/* error code for libzip-internal errors */ +#define ZIP_ER_DETAIL_NO_DETAIL 0 /* G no detail */ +#define ZIP_ER_DETAIL_CDIR_OVERLAPS_EOCD 1 /* G central directory overlaps EOCD, or there is space between them */ +#define ZIP_ER_DETAIL_COMMENT_LENGTH_INVALID 2 /* G archive comment length incorrect */ +#define ZIP_ER_DETAIL_CDIR_LENGTH_INVALID 3 /* G central directory length invalid */ +#define ZIP_ER_DETAIL_CDIR_ENTRY_INVALID 4 /* E central header invalid */ +#define ZIP_ER_DETAIL_CDIR_WRONG_ENTRIES_COUNT 5 /* G central directory count of entries is incorrect */ +#define ZIP_ER_DETAIL_ENTRY_HEADER_MISMATCH 6 /* E local and central headers do not match */ +#define ZIP_ER_DETAIL_EOCD_LENGTH_INVALID 7 /* G wrong EOCD length */ +#define ZIP_ER_DETAIL_EOCD64_OVERLAPS_EOCD 8 /* G EOCD64 overlaps EOCD, or there is space between them */ +#define ZIP_ER_DETAIL_EOCD64_WRONG_MAGIC 9 /* G EOCD64 magic incorrect */ +#define ZIP_ER_DETAIL_EOCD64_MISMATCH 10 /* G EOCD64 and EOCD do not match */ +#define ZIP_ER_DETAIL_CDIR_INVALID 11 /* G invalid value in central directory */ +#define ZIP_ER_DETAIL_VARIABLE_SIZE_OVERFLOW 12 /* E variable size fields overflow header */ +#define ZIP_ER_DETAIL_INVALID_UTF8_IN_FILENAME 13 /* E invalid UTF-8 in filename */ +#define ZIP_ER_DETAIL_INVALID_UTF8_IN_COMMENT 13 /* E invalid UTF-8 in comment */ +#define ZIP_ER_DETAIL_INVALID_ZIP64_EF 14 /* E invalid Zip64 extra field */ +#define ZIP_ER_DETAIL_INVALID_WINZIPAES_EF 14 /* E invalid WinZip AES extra field */ +#define ZIP_ER_DETAIL_EF_TRAILING_GARBAGE 15 /* E garbage at end of extra fields */ +#define ZIP_ER_DETAIL_INVALID_EF_LENGTH 16 /* E extra field length is invalid */ +#define ZIP_ER_DETAIL_INVALID_FILE_LENGTH 17 /* E file length in header doesn't match actual file length */ + /* directory entry: general purpose bit flags */ #define ZIP_GPBF_ENCRYPTED 0x0001u /* is encrypted */ @@ -258,14 +305,14 @@ struct zip { zip_hash_t *names; /* hash table for name lookup */ zip_progress_t *progress; /* progress callback for zip_close() */ + + zip_uint32_t* write_crc; /* have _zip_write() compute CRC */ }; /* file in zip archive, part of API */ struct zip_file { - zip_t *za; /* zip archive containing this file */ zip_error_t error; /* error information */ - bool eof; zip_source_t *src; /* data source */ }; @@ -304,7 +351,7 @@ struct zip_dirent { zip_uint32_t ext_attrib; /* (c) external file attributes */ zip_uint64_t offset; /* (c) offset of local header */ - zip_uint16_t compression_level; /* level of compression to use (never valid in orig) */ + zip_uint32_t compression_level; /* level of compression to use (never valid in orig) */ zip_uint16_t encryption_method; /* encryption method, computed from other fields */ char *password; /* file specific encryption password */ }; @@ -414,7 +461,7 @@ struct zip_buffer { struct zip_filelist { zip_uint64_t idx; - /* TODO const char *name; */ + const char *name; }; typedef struct zip_filelist zip_filelist_t; @@ -427,10 +474,6 @@ struct _zip_pkware_keys { }; typedef struct _zip_pkware_keys zip_pkware_keys_t; -extern const char *const _zip_err_str[]; -extern const int _zip_nerr_str; -extern const int _zip_err_type[]; - #define ZIP_MAX(a, b) ((a) > (b) ? (a) : (b)) #define ZIP_MIN(a, b) ((a) < (b) ? (a) : (b)) @@ -439,6 +482,8 @@ extern const int _zip_err_type[]; #define ZIP_ENTRY_HAS_CHANGES(e) (ZIP_ENTRY_DATA_CHANGED(e) || (e)->deleted || ZIP_ENTRY_CHANGED((e), ZIP_DIRENT_ALL)) #define ZIP_IS_RDONLY(za) ((za)->ch_flags & ZIP_AFL_RDONLY) +#define ZIP_IS_TORRENTZIP(za) ((za)->flags & ZIP_AFL_IS_TORRENTZIP) +#define ZIP_WANT_TORRENTZIP(za) ((za)->ch_flags & ZIP_AFL_WANT_TORRENTZIP) #ifdef HAVE_EXPLICIT_MEMSET @@ -493,8 +538,11 @@ void _zip_dirent_finalize(zip_dirent_t *); void _zip_dirent_init(zip_dirent_t *); bool _zip_dirent_needs_zip64(const zip_dirent_t *, zip_flags_t); zip_dirent_t *_zip_dirent_new(void); +bool zip_dirent_process_ef_zip64(zip_dirent_t * zde, const zip_uint8_t * ef, zip_uint64_t got_len, bool local, zip_error_t * error); zip_int64_t _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, bool local, zip_error_t *error); void _zip_dirent_set_version_needed(zip_dirent_t *de, bool force_zip64); +void zip_dirent_torrentzip_normalize(zip_dirent_t *de); + zip_int32_t _zip_dirent_size(zip_source_t *src, zip_uint16_t, zip_error_t *); int _zip_dirent_write(zip_t *za, zip_dirent_t *dirent, zip_flags_t flags); @@ -516,7 +564,6 @@ void _zip_error_clear(zip_error_t *); void _zip_error_get(const zip_error_t *, int *, int *); void _zip_error_copy(zip_error_t *dst, const zip_error_t *src); -void _zip_error_set_from_source(zip_error_t *, zip_source_t *); const zip_uint8_t *_zip_extract_extra_field_by_id(zip_error_t *, zip_uint16_t, int, const zip_uint8_t *, zip_uint16_t, zip_uint16_t *); @@ -538,7 +585,7 @@ zip_hash_t *_zip_hash_new(zip_error_t *error); bool _zip_hash_reserve_capacity(zip_hash_t *hash, zip_uint64_t capacity, zip_error_t *error); bool _zip_hash_revert(zip_hash_t *hash, zip_error_t *error); -int _zip_mkstempm(char *path, int mode); +int _zip_mkstempm(char *path, int mode, bool create_file); zip_t *_zip_open(zip_source_t *, unsigned int, zip_error_t *); @@ -549,7 +596,7 @@ int _zip_progress_subrange(zip_progress_t *progress, double start, double end); int _zip_progress_update(zip_progress_t *progress, double value); /* this symbol is extern so it can be overridden for regression testing */ -//ZIP_EXTERN bool zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length); +ZIP_EXTERN bool zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length); zip_uint32_t zip_random_uint32(void); int _zip_read(zip_source_t *src, zip_uint8_t *data, zip_uint64_t length, zip_error_t *error); @@ -569,16 +616,15 @@ bool _zip_source_had_error(zip_source_t *); void _zip_source_invalidate(zip_source_t *src); zip_source_t *_zip_source_new(zip_error_t *error); int _zip_source_set_source_archive(zip_source_t *, zip_t *); -zip_source_t *_zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_uint64_t length, zip_stat_t *st, zip_file_attributes_t *attributes, zip_t *source_archive, zip_uint64_t source_index, zip_error_t *error); -zip_source_t *_zip_source_zip_new(zip_t *, zip_t *, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_uint64_t, const char *); +zip_source_t *_zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_int64_t length, zip_stat_t *st, zip_uint64_t st_invalid, zip_file_attributes_t *attributes, zip_t *source_archive, zip_uint64_t source_index, bool take_ownership, zip_error_t *error); int _zip_stat_merge(zip_stat_t *dst, const zip_stat_t *src, zip_error_t *error); -int _zip_string_equal(const zip_string_t *, const zip_string_t *); -void _zip_string_free(zip_string_t *); -zip_uint32_t _zip_string_crc32(const zip_string_t *); -const zip_uint8_t *_zip_string_get(zip_string_t *, zip_uint32_t *, zip_flags_t, zip_error_t *); -zip_uint16_t _zip_string_length(const zip_string_t *); -zip_string_t *_zip_string_new(const zip_uint8_t *, zip_uint16_t, zip_flags_t, zip_error_t *); +int _zip_string_equal(const zip_string_t *a, const zip_string_t *b); +void _zip_string_free(zip_string_t *string); +zip_uint32_t _zip_string_crc32(const zip_string_t *string); +const zip_uint8_t *_zip_string_get(zip_string_t *string, zip_uint32_t *lenp, zip_flags_t flags, zip_error_t *error); +zip_uint16_t _zip_string_length(const zip_string_t *string); +zip_string_t *_zip_string_new(const zip_uint8_t *raw, zip_uint16_t length, zip_flags_t flags, zip_error_t *error); int _zip_string_write(zip_t *za, const zip_string_t *string); bool _zip_winzip_aes_decrypt(zip_winzip_aes_t *ctx, zip_uint8_t *data, zip_uint64_t length); bool _zip_winzip_aes_encrypt(zip_winzip_aes_t *ctx, zip_uint8_t *data, zip_uint64_t length); diff --git a/Source/Libraries/libzip/Unix/zip_random_unix.c b/Libraries/libzip/Source/unix/zip_random_unix.c similarity index 93% rename from Source/Libraries/libzip/Unix/zip_random_unix.c rename to Libraries/libzip/Source/unix/zip_random_unix.c index 4aa9cc26e..867df7900 100644 --- a/Source/Libraries/libzip/Unix/zip_random_unix.c +++ b/Libraries/libzip/Source/unix/zip_random_unix.c @@ -1,9 +1,9 @@ /* zip_random_unix.c -- fill the user's buffer with random stuff (Unix version) - Copyright (C) 2016-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2016-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -83,6 +83,11 @@ zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length) { #ifndef HAVE_RANDOM_UINT32 #include +#ifndef HAVE_RANDOM +#define srandom srand +#define random rand +#endif + zip_uint32_t zip_random_uint32(void) { static bool seeded = false; @@ -95,6 +100,7 @@ zip_random_uint32(void) { if (!seeded) { srandom((unsigned int)time(NULL)); + seeded = true; } return (zip_uint32_t)random(); diff --git a/Source/Libraries/libzip/Unix/zip_source_file_stdio_named.c b/Libraries/libzip/Source/unix/zip_source_file_stdio_named.c similarity index 65% rename from Source/Libraries/libzip/Unix/zip_source_file_stdio_named.c rename to Libraries/libzip/Source/unix/zip_source_file_stdio_named.c index 5387c7663..1495d7dde 100644 --- a/Source/Libraries/libzip/Unix/zip_source_file_stdio_named.c +++ b/Libraries/libzip/Source/unix/zip_source_file_stdio_named.c @@ -1,9 +1,9 @@ /* zip_source_file_stdio_named.c -- source for stdio file opened by name - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -36,6 +36,7 @@ #include "zip_source_file.h" #include "zip_source_file_stdio.h" +#include #include #include #ifdef HAVE_UNISTD_H @@ -53,6 +54,8 @@ #define CAN_CLONE #endif +static int create_temp_file(zip_source_file_context_t *ctx, bool create_file); + static zip_int64_t _zip_stdio_op_commit_write(zip_source_file_context_t *ctx); static zip_int64_t _zip_stdio_op_create_temp_output(zip_source_file_context_t *ctx); #ifdef CAN_CLONE @@ -63,6 +66,7 @@ static zip_int64_t _zip_stdio_op_remove(zip_source_file_context_t *ctx); static void _zip_stdio_op_rollback_write(zip_source_file_context_t *ctx); static char *_zip_stdio_op_strdup(zip_source_file_context_t *ctx, const char *string); static zip_int64_t _zip_stdio_op_write(zip_source_file_context_t *ctx, const void *data, zip_uint64_t len); +static FILE *_zip_fopen_close_on_exec(const char *name, bool writeable); /* clang-format off */ static zip_source_file_operations_t ops_stdio_named = { @@ -97,7 +101,7 @@ zip_source_file(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t le ZIP_EXTERN zip_source_t * zip_source_file_create(const char *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error) { - if (fname == NULL || length < -1) { + if (fname == NULL || length < ZIP_LENGTH_UNCHECKED) { zip_error_set(error, ZIP_ER_INVAL, 0); return NULL; } @@ -123,82 +127,51 @@ _zip_stdio_op_commit_write(zip_source_file_context_t *ctx) { static zip_int64_t _zip_stdio_op_create_temp_output(zip_source_file_context_t *ctx) { - char *temp; - int tfd; - int mode; - FILE *tfp; - struct stat st; - - if ((temp = (char *)malloc(strlen(ctx->fname) + 8)) == NULL) { - zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0); - return -1; - } - - if (stat(ctx->fname, &st) == 0) { - mode = st.st_mode; - } - else { - mode = -1; - } - - sprintf(temp, "%s.XXXXXX", ctx->fname); - - if ((tfd = _zip_mkstempm(temp, mode)) == -1) { - zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); - free(temp); + int fd = create_temp_file(ctx, true); + + if (fd < 0) { return -1; } - - if ((tfp = fdopen(tfd, "r+b")) == NULL) { + + if ((ctx->fout = fdopen(fd, "r+b")) == NULL) { zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); - close(tfd); - (void)remove(temp); - free(temp); + close(fd); + (void)remove(ctx->tmpname); + free(ctx->tmpname); + ctx->tmpname = NULL; return -1; } - ctx->fout = tfp; - ctx->tmpname = temp; - return 0; } #ifdef CAN_CLONE static zip_int64_t _zip_stdio_op_create_temp_output_cloning(zip_source_file_context_t *ctx, zip_uint64_t offset) { - char *temp; FILE *tfp; - + if (offset > ZIP_OFF_MAX) { zip_error_set(&ctx->error, ZIP_ER_SEEK, E2BIG); return -1; } - - if ((temp = (char *)malloc(strlen(ctx->fname) + 8)) == NULL) { - zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0); - return -1; - } - sprintf(temp, "%s.XXXXXX", ctx->fname); - + #ifdef HAVE_CLONEFILE -#ifndef __clang_analyzer__ - /* we can't use mkstemp, since clonefile insists on creating the file */ - if (mktemp(temp) == NULL) { - zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); - free(temp); + /* clonefile insists on creating the file, so just create a name */ + if (create_temp_file(ctx, false) < 0) { return -1; } -#endif - - if (clonefile(ctx->fname, temp, 0) < 0) { + + if (clonefile(ctx->fname, ctx->tmpname, 0) < 0) { zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); - free(temp); + free(ctx->tmpname); + ctx->tmpname = NULL; return -1; } - if ((tfp = _zip_fopen_close_on_exec(temp, true)) == NULL) { + if ((tfp = _zip_fopen_close_on_exec(ctx->tmpname, true)) == NULL) { zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); - (void)remove(temp); - free(temp); + (void)remove(ctx->tmpname); + free(ctx->tmpname); + ctx->tmpname = NULL; return -1; } #else @@ -206,19 +179,16 @@ _zip_stdio_op_create_temp_output_cloning(zip_source_file_context_t *ctx, zip_uin int fd; struct file_clone_range range; struct stat st; - + if (fstat(fileno(ctx->f), &st) < 0) { zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); - free(temp); return -1; } - - if ((fd = mkstemp(temp)) < 0) { - zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); - free(temp); + + if ((fd = create_temp_file(ctx, true)) < 0) { return -1; } - + range.src_fd = fileno(ctx->f); range.src_offset = 0; range.src_length = ((offset + st.st_blksize - 1) / st.st_blksize) * st.st_blksize; @@ -229,16 +199,18 @@ _zip_stdio_op_create_temp_output_cloning(zip_source_file_context_t *ctx, zip_uin if (ioctl(fd, FICLONERANGE, &range) < 0) { zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); (void)close(fd); - (void)remove(temp); - free(temp); + (void)remove(ctx->tmpname); + free(ctx->tmpname); + ctx->tmpname = NULL; return -1; } if ((tfp = fdopen(fd, "r+b")) == NULL) { zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); (void)close(fd); - (void)remove(temp); - free(temp); + (void)remove(ctx->tmpname); + free(ctx->tmpname); + ctx->tmpname = NULL; return -1; } } @@ -246,19 +218,21 @@ _zip_stdio_op_create_temp_output_cloning(zip_source_file_context_t *ctx, zip_uin if (ftruncate(fileno(tfp), (off_t)offset) < 0) { (void)fclose(tfp); - (void)remove(temp); - free(temp); + (void)remove(ctx->tmpname); + free(ctx->tmpname); + ctx->tmpname = NULL; return -1; } if (fseeko(tfp, (off_t)offset, SEEK_SET) < 0) { - (void)fclose(tfp); - (void)remove(temp); - free(temp); zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); + (void)fclose(tfp); + (void)remove(ctx->tmpname); + free(ctx->tmpname); + ctx->tmpname = NULL; + return -1; } ctx->fout = tfp; - ctx->tmpname = temp; return 0; } @@ -311,3 +285,108 @@ _zip_stdio_op_write(zip_source_file_context_t *ctx, const void *data, zip_uint64 return (zip_int64_t)ret; } + + +static int create_temp_file(zip_source_file_context_t *ctx, bool create_file) { + char *temp; + int mode; + struct stat st; + int fd = 0; + char *start, *end; + + if (stat(ctx->fname, &st) == 0) { + mode = st.st_mode; + } + else { + mode = -1; + } + + size_t temp_size = strlen(ctx->fname) + 13; + if ((temp = (char *)malloc(temp_size)) == NULL) { + zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0); + return -1; + } + snprintf_s(temp, temp_size, "%s.XXXXXX.part", ctx->fname); + end = temp + strlen(temp) - 5; + start = end - 6; + + for (;;) { + zip_uint32_t value = zip_random_uint32(); + char *xs = start; + + while (xs < end) { + char digit = value % 36; + if (digit < 10) { + *(xs++) = digit + '0'; + } + else { + *(xs++) = digit - 10 + 'a'; + } + value /= 36; + } + + if (create_file) { + if ((fd = open(temp, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC, mode == -1 ? 0666 : (mode_t)mode)) >= 0) { + if (mode != -1) { + /* open() honors umask(), which we don't want in this case */ +#ifdef HAVE_FCHMOD + (void)fchmod(fd, (mode_t)mode); +#else + (void)chmod(temp, (mode_t)mode); +#endif + } + break; + } + if (errno != EEXIST) { + zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); + free(temp); + return -1; + } + } + else { + if (stat(temp, &st) < 0) { + if (errno == ENOENT) { + break; + } + else { + zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); + free(temp); + return -1; + } + } + } + } + + ctx->tmpname = temp; + + return fd; /* initialized to 0 if !create_file */ +} + + +/* + * fopen replacement that sets the close-on-exec flag + * some implementations support an fopen 'e' flag for that, + * but e.g. macOS doesn't. + */ +static FILE *_zip_fopen_close_on_exec(const char *name, bool writeable) { + int fd; + int flags; + FILE *fp; + + flags = O_CLOEXEC; + if (writeable) { + flags |= O_RDWR; + } + else { + flags |= O_RDONLY; + } + + /* mode argument needed on Windows */ + if ((fd = open(name, flags, 0666)) < 0) { + return NULL; + } + if ((fp = fdopen(fd, writeable ? "r+b" : "rb")) == NULL) { + return NULL; + } + return fp; +} diff --git a/Source/Libraries/libzip/zip_error_strerror.c b/Libraries/libzip/Source/win/zip_random_win32.c similarity index 57% rename from Source/Libraries/libzip/zip_error_strerror.c rename to Libraries/libzip/Source/win/zip_random_win32.c index d20b3b2fa..789b9c205 100644 --- a/Source/Libraries/libzip/zip_error_strerror.c +++ b/Libraries/libzip/Source/win/zip_random_win32.c @@ -1,9 +1,9 @@ /* - zip_error_sterror.c -- get string representation of struct zip_error - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + zip_random_win32.c -- fill the user's buffer with random stuff (Windows version) + Copyright (C) 2016-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -31,53 +31,52 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -#include -#include -#include -#include - #include "zipint.h" +#ifdef HAVE_CRYPTO +#include "zip_crypto.h" +#endif -ZIP_EXTERN const char * -zip_error_strerror(zip_error_t *err) { - const char *zs, *ss; - char buf[128], *s; +#include - zip_error_fini(err); +#ifndef HAVE_SECURE_RANDOM - if (err->zip_err < 0 || err->zip_err >= _zip_nerr_str) { - sprintf(buf, "Unknown error %d", err->zip_err); - zs = NULL; - ss = buf; - } - else { - zs = _zip_err_str[err->zip_err]; +#include - switch (_zip_err_type[err->zip_err]) { - case ZIP_ET_SYS: - ss = strerror(err->sys_err); - break; +ZIP_EXTERN bool +zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length) { + HCRYPTPROV hprov; + if (!CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { + return false; + } + if (!CryptGenRandom(hprov, length, buffer)) { + return false; + } + if (!CryptReleaseContext(hprov, 0)) { + return false; + } + return true; +} +#endif - case ZIP_ET_ZLIB: - ss = zError(err->sys_err); - break; +#ifndef HAVE_RANDOM_UINT32 +#include - default: - ss = NULL; - } - } +zip_uint32_t +zip_random_uint32(void) { + static bool seeded = false; - if (ss == NULL) - return zs; - else { - if ((s = (char *)malloc(strlen(ss) + (zs ? strlen(zs) + 2 : 0) + 1)) == NULL) - return _zip_err_str[ZIP_ER_MEMORY]; + zip_uint32_t value; - sprintf(s, "%s%s%s", (zs ? zs : ""), (zs ? ": " : ""), ss); - err->str = s; + if (zip_secure_random((zip_uint8_t *)&value, sizeof(value))) { + return value; + } - return s; + if (!seeded) { + srand((unsigned int)time(NULL)); + seeded = true; } + + return (zip_uint32_t)rand(); } +#endif diff --git a/Source/Libraries/libzip/Win/zip_source_file_win32.c b/Libraries/libzip/Source/win/zip_source_file_win32.c similarity index 96% rename from Source/Libraries/libzip/Win/zip_source_file_win32.c rename to Libraries/libzip/Source/win/zip_source_file_win32.c index 6547fc20e..624860b1c 100644 --- a/Source/Libraries/libzip/Win/zip_source_file_win32.c +++ b/Libraries/libzip/Source/win/zip_source_file_win32.c @@ -1,9 +1,9 @@ /* zip_source_file_win32.c -- read-only Windows file source implementation - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -69,7 +69,7 @@ zip_source_win32handle(zip_t *za, HANDLE h, zip_uint64_t start, zip_int64_t len) ZIP_EXTERN zip_source_t * zip_source_win32handle_create(HANDLE h, zip_uint64_t start, zip_int64_t length, zip_error_t *error) { - if (h == INVALID_HANDLE_VALUE || length < -1) { + if (h == INVALID_HANDLE_VALUE || length < ZIP_LENGTH_UNCHECKED) { zip_error_set(error, ZIP_ER_INVAL, 0); return NULL; } @@ -115,7 +115,7 @@ _zip_win32_op_seek(zip_source_file_context_t *ctx, void *f, zip_int64_t offset, break; default: zip_error_set(&ctx->error, ZIP_ER_SEEK, EINVAL); - return -1; + return false; } li.QuadPart = (LONGLONG)offset; @@ -184,7 +184,7 @@ _zip_stat_win32(zip_source_file_context_t *ctx, zip_source_file_stat_t *st, HAND zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError())); return false; } - if (_zip_filetime_to_time_t(mtimeft, &mtime) < 0) { + if (!_zip_filetime_to_time_t(mtimeft, &mtime)) { zip_error_set(&ctx->error, ZIP_ER_READ, ERANGE); return false; } diff --git a/Libraries/libzip/Source/win/zip_source_file_win32_ansi.c b/Libraries/libzip/Source/win/zip_source_file_win32_ansi.c new file mode 100644 index 000000000..58034cc2a --- /dev/null +++ b/Libraries/libzip/Source/win/zip_source_file_win32_ansi.c @@ -0,0 +1,87 @@ +/* + zip_source_file_win32_ansi.c -- source for Windows file opened by ANSI name + Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "zip_source_file_win32.h" + +static char *ansi_allocate_tempname(const char *name, size_t extra_chars, size_t *lengthp); +static void ansi_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i); + +/* clang-format off */ +DONT_WARN_INCOMPATIBLE_FN_PTR_BEGIN + +zip_win32_file_operations_t ops_ansi = { + ansi_allocate_tempname, + CreateFileA, + DeleteFileA, + GetFileAttributesA, + GetFileAttributesExA, + ansi_make_tempname, + MoveFileExA, + SetFileAttributesA, + strdup +}; + +DONT_WARN_INCOMPATIBLE_FN_PTR_END +/* clang-format on */ + +ZIP_EXTERN zip_source_t * +zip_source_win32a(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t len) { + if (za == NULL) + return NULL; + + return zip_source_win32a_create(fname, start, len, &za->error); +} + + +ZIP_EXTERN zip_source_t * +zip_source_win32a_create(const char *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error) { + if (fname == NULL || length < ZIP_LENGTH_UNCHECKED) { + zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + + return zip_source_file_common_new(fname, NULL, start, length, NULL, &_zip_source_file_win32_named_ops, &ops_ansi, error); +} + + +static char * +ansi_allocate_tempname(const char *name, size_t extra_chars, size_t *lengthp) { + *lengthp = strlen(name) + extra_chars; + return (char *)malloc(*lengthp); +} + + +static void +ansi_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i) { + snprintf_s(buf, len, "%s.%08x", name, i); +} diff --git a/Source/Libraries/libzip/Win/zip_source_file_win32_named.c b/Libraries/libzip/Source/win/zip_source_file_win32_named.c similarity index 99% rename from Source/Libraries/libzip/Win/zip_source_file_win32_named.c rename to Libraries/libzip/Source/win/zip_source_file_win32_named.c index 1fe559180..855e605a9 100644 --- a/Source/Libraries/libzip/Win/zip_source_file_win32_named.c +++ b/Libraries/libzip/Source/win/zip_source_file_win32_named.c @@ -3,7 +3,7 @@ Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -99,7 +99,6 @@ _zip_win32_named_op_create_temp_output(zip_source_file_context_t *ctx) { zip_uint32_t value, i; HANDLE th = INVALID_HANDLE_VALUE; - void *temp = NULL; PSECURITY_DESCRIPTOR psd = NULL; PSECURITY_ATTRIBUTES psa = NULL; SECURITY_ATTRIBUTES sa; diff --git a/Source/Libraries/libzip/Win/zip_source_file_win32_utf16.c b/Libraries/libzip/Source/win/zip_source_file_win32_utf16.c similarity index 94% rename from Source/Libraries/libzip/Win/zip_source_file_win32_utf16.c rename to Libraries/libzip/Source/win/zip_source_file_win32_utf16.c index 6aef2bb49..8f07d0210 100644 --- a/Source/Libraries/libzip/Win/zip_source_file_win32_utf16.c +++ b/Libraries/libzip/Source/win/zip_source_file_win32_utf16.c @@ -3,7 +3,7 @@ Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -39,6 +39,7 @@ static void utf16_make_tempname(char *buf, size_t len, const char *name, zip_uin static char *utf16_strdup(const char *string); /* clang-format off */ +DONT_WARN_INCOMPATIBLE_FN_PTR_BEGIN zip_win32_file_operations_t ops_utf16 = { utf16_allocate_tempname, @@ -52,6 +53,7 @@ zip_win32_file_operations_t ops_utf16 = { utf16_strdup }; +DONT_WARN_INCOMPATIBLE_FN_PTR_END /* clang-format on */ ZIP_EXTERN zip_source_t * @@ -65,7 +67,7 @@ zip_source_win32w(zip_t *za, const wchar_t *fname, zip_uint64_t start, zip_int64 ZIP_EXTERN zip_source_t * zip_source_win32w_create(const wchar_t *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error) { - if (fname == NULL || length < -1) { + if (fname == NULL || length < ZIP_LENGTH_UNCHECKED) { zip_error_set(error, ZIP_ER_INVAL, 0); return NULL; } @@ -101,7 +103,7 @@ static HANDLE __stdcall utf16_create_file(const char *name, DWORD access, DWORD static void utf16_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i) { - _snwprintf((wchar_t *)buf, len, L"%s.%08x", (const wchar_t *)name, i); + _snwprintf_s((wchar_t *)buf, len, len, L"%s.%08x", (const wchar_t *)name, i); } diff --git a/Source/Libraries/libzip/Win/zip_source_file_win32_utf8.c b/Libraries/libzip/Source/win/zip_source_file_win32_utf8.c similarity index 96% rename from Source/Libraries/libzip/Win/zip_source_file_win32_utf8.c rename to Libraries/libzip/Source/win/zip_source_file_win32_utf8.c index d6728e34f..d154f97ae 100644 --- a/Source/Libraries/libzip/Win/zip_source_file_win32_utf8.c +++ b/Libraries/libzip/Source/win/zip_source_file_win32_utf8.c @@ -3,7 +3,7 @@ Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -49,7 +49,7 @@ zip_source_file_create(const char *fname, zip_uint64_t start, zip_int64_t length wchar_t *wfname; zip_source_t *source; - if (fname == NULL || length < -1) { + if (fname == NULL || length < ZIP_LENGTH_UNCHECKED) { zip_error_set(error, ZIP_ER_INVAL, 0); return NULL; } diff --git a/Source/Libraries/libzip/zip_add.c b/Libraries/libzip/Source/zip_add.c similarity index 94% rename from Source/Libraries/libzip/zip_add.c rename to Libraries/libzip/Source/zip_add.c index ef04f1e51..9770139d6 100644 --- a/Source/Libraries/libzip/zip_add.c +++ b/Libraries/libzip/Source/zip_add.c @@ -1,9 +1,9 @@ /* zip_add.c -- add file via callback function - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_add_dir.c b/Libraries/libzip/Source/zip_add_dir.c similarity index 94% rename from Source/Libraries/libzip/zip_add_dir.c rename to Libraries/libzip/Source/zip_add_dir.c index 9999c8da2..c31fea365 100644 --- a/Source/Libraries/libzip/zip_add_dir.c +++ b/Libraries/libzip/Source/zip_add_dir.c @@ -1,9 +1,9 @@ /* zip_add_dir.c -- add directory - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_add_entry.c b/Libraries/libzip/Source/zip_add_entry.c similarity index 96% rename from Source/Libraries/libzip/zip_add_entry.c rename to Libraries/libzip/Source/zip_add_entry.c index 1c9fcff6a..bf12dd541 100644 --- a/Source/Libraries/libzip/zip_add_entry.c +++ b/Libraries/libzip/Source/zip_add_entry.c @@ -1,9 +1,9 @@ /* zip_add_entry.c -- create and init struct zip_entry - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_algorithm_deflate.c b/Libraries/libzip/Source/zip_algorithm_deflate.c similarity index 83% rename from Source/Libraries/libzip/zip_algorithm_deflate.c rename to Libraries/libzip/Source/zip_algorithm_deflate.c index 99d8a597b..3c85e2045 100644 --- a/Source/Libraries/libzip/zip_algorithm_deflate.c +++ b/Libraries/libzip/Source/zip_algorithm_deflate.c @@ -1,9 +1,9 @@ /* zip_algorithm_deflate.c -- deflate (de)compression routines - Copyright (C) 2017-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2017-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -40,7 +40,8 @@ struct ctx { zip_error_t *error; bool compress; - int compression_flags; + int level; + int mem_level; bool end_of_input; z_stream zstr; }; @@ -60,7 +61,7 @@ maximum_compressed_size(zip_uint64_t uncompressed_size) { static void * -allocate(bool compress, int compression_flags, zip_error_t *error) { +allocate(bool compress, zip_uint32_t compression_flags, zip_error_t *error) { struct ctx *ctx; if ((ctx = (struct ctx *)malloc(sizeof(*ctx))) == NULL) { @@ -70,10 +71,13 @@ allocate(bool compress, int compression_flags, zip_error_t *error) { ctx->error = error; ctx->compress = compress; - ctx->compression_flags = compression_flags; - if (ctx->compression_flags < 1 || ctx->compression_flags > 9) { - ctx->compression_flags = Z_BEST_COMPRESSION; + if (compression_flags >= 1 && compression_flags <= 9) { + ctx->level = (int)compression_flags; } + else { + ctx->level = Z_BEST_COMPRESSION; + } + ctx->mem_level = compression_flags == TORRENTZIP_COMPRESSION_FLAGS ? TORRENTZIP_MEM_LEVEL : MAX_MEM_LEVEL; ctx->end_of_input = false; ctx->zstr.zalloc = Z_NULL; @@ -85,13 +89,15 @@ allocate(bool compress, int compression_flags, zip_error_t *error) { static void * -compress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) { +compress_allocate(zip_uint16_t method, zip_uint32_t compression_flags, zip_error_t *error) { + (void)method; return allocate(true, compression_flags, error); } static void * -decompress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) { +decompress_allocate(zip_uint16_t method, zip_uint32_t compression_flags, zip_error_t *error) { + (void)method; return allocate(false, compression_flags, error); } @@ -112,10 +118,10 @@ general_purpose_bit_flags(void *ud) { return 0; } - if (ctx->compression_flags < 3) { + if (ctx->level < 3) { return 2 << 1; } - else if (ctx->compression_flags > 7) { + else if (ctx->level > 7) { return 1 << 1; } return 0; @@ -127,6 +133,9 @@ start(void *ud, zip_stat_t *st, zip_file_attributes_t *attributes) { struct ctx *ctx = (struct ctx *)ud; int ret; + (void)st; + (void)attributes; + ctx->zstr.avail_in = 0; ctx->zstr.next_in = NULL; ctx->zstr.avail_out = 0; @@ -134,7 +143,7 @@ start(void *ud, zip_stat_t *st, zip_file_attributes_t *attributes) { if (ctx->compress) { /* negative value to tell zlib not to write a header */ - ret = deflateInit2(&ctx->zstr, ctx->compression_flags, Z_DEFLATED, -MAX_WBITS, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY); + ret = deflateInit2(&ctx->zstr, ctx->level, Z_DEFLATED, -MAX_WBITS, ctx->mem_level, Z_DEFAULT_STRATEGY); } else { ret = inflateInit2(&ctx->zstr, -MAX_WBITS); @@ -198,10 +207,12 @@ end_of_input(void *ud) { static zip_compression_status_t process(void *ud, zip_uint8_t *data, zip_uint64_t *length) { struct ctx *ctx = (struct ctx *)ud; + uInt avail_out; int ret; - ctx->zstr.avail_out = (uInt)ZIP_MIN(UINT_MAX, *length); + avail_out = (uInt)ZIP_MIN(UINT_MAX, *length); + ctx->zstr.avail_out = avail_out; ctx->zstr.next_out = (Bytef *)data; if (ctx->compress) { @@ -211,7 +222,7 @@ process(void *ud, zip_uint8_t *data, zip_uint64_t *length) { ret = inflate(&ctx->zstr, Z_SYNC_FLUSH); } - *length = *length - ctx->zstr.avail_out; + *length = avail_out - ctx->zstr.avail_out; switch (ret) { case Z_OK: diff --git a/Source/Libraries/libzip/zip_buffer.c b/Libraries/libzip/Source/zip_buffer.c similarity index 92% rename from Source/Libraries/libzip/zip_buffer.c rename to Libraries/libzip/Source/zip_buffer.c index 802dbe248..e2103f04c 100644 --- a/Source/Libraries/libzip/zip_buffer.c +++ b/Libraries/libzip/Source/zip_buffer.c @@ -1,9 +1,9 @@ /* zip_buffer.c -- bounds checked access to memory buffer - Copyright (C) 2014-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -132,18 +132,20 @@ _zip_buffer_left(zip_buffer_t *buffer) { zip_uint64_t _zip_buffer_read(zip_buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length) { + zip_uint64_t copied; + if (_zip_buffer_left(buffer) < length) { length = _zip_buffer_left(buffer); } - // Check for 32bit overflow - uint64_t maxMemSize = SIZE_MAX; - if (length >= maxMemSize) - return 0; - - memcpy(data, _zip_buffer_get(buffer, length), (size_t) length); + copied = 0; + while (copied < length) { + size_t n = ZIP_MIN(length - copied, SIZE_MAX); + (void)memcpy_s(data + copied, n, _zip_buffer_get(buffer, n), n); + copied += n; + } - return length; + return copied; } @@ -152,14 +154,14 @@ _zip_buffer_new(zip_uint8_t *data, zip_uint64_t size) { bool free_data = (data == NULL); zip_buffer_t *buffer; - if (data == NULL) { - - // Check for 32bit overflow - uint64_t maxMemSize = SIZE_MAX; - if (size >= maxMemSize) - return NULL; +#if ZIP_UINT64_MAX > SIZE_MAX + if (size > SIZE_MAX) { + return NULL; + } +#endif - if ((data = (zip_uint8_t *)malloc((size_t) size)) == NULL) { + if (data == NULL) { + if ((data = (zip_uint8_t *)malloc((size_t)size)) == NULL) { return NULL; } } @@ -232,7 +234,7 @@ _zip_buffer_put(zip_buffer_t *buffer, const void *src, size_t length) { return -1; } - memcpy(dst, src, length); + (void)memcpy_s(dst, length, src, length); return 0; } diff --git a/Source/Libraries/libzip/zip_close.c b/Libraries/libzip/Source/zip_close.c similarity index 82% rename from Source/Libraries/libzip/zip_close.c rename to Libraries/libzip/Source/zip_close.c index 313324150..ddc2c2456 100644 --- a/Source/Libraries/libzip/zip_close.c +++ b/Libraries/libzip/Source/zip_close.c @@ -1,9 +1,9 @@ /* zip_close.c -- close zip archive and update changes - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -45,6 +45,7 @@ static int add_data(zip_t *, zip_source_t *, zip_dirent_t *, zip_uint32_t); static int copy_data(zip_t *, zip_uint64_t); static int copy_source(zip_t *, zip_source_t *, zip_int64_t); +static int torrentzip_compare_names(const void *a, const void *b); static int write_cdir(zip_t *, const zip_filelist_t *, zip_uint64_t); static int write_data_descriptor(zip_t *za, const zip_dirent_t *dirent, int is_zip64); @@ -61,12 +62,12 @@ zip_close(zip_t *za) { changed = _zip_changed(za, &survivors); - /* don't create zip files with no entries */ - if (survivors == 0) { + if (survivors == 0 && !(za->ch_flags & ZIP_AFL_CREATE_OR_KEEP_FILE_FOR_EMPTY_ARCHIVE)) { + /* don't create zip files with no entries */ if ((za->open_flags & ZIP_TRUNCATE) || changed) { if (zip_source_remove(za->src) < 0) { if (!((zip_error_code_zip(zip_source_error(za->src)) == ZIP_ER_REMOVE) && (zip_error_code_system(zip_source_error(za->src)) == ENOENT))) { - _zip_error_set_from_source(&za->error, za->src); + zip_error_set_from_source(&za->error, za->src); return -1; } } @@ -75,7 +76,8 @@ zip_close(zip_t *za) { return 0; } - if (!changed) { + /* Always write empty archive if we are told to keep it, otherwise it wouldn't be created if the file doesn't already exist. */ + if (!changed && survivors > 0) { zip_discard(za); return 0; } @@ -105,6 +107,7 @@ zip_close(zip_t *za) { } filelist[j].idx = i; + filelist[j].name = zip_get_name(za, i, 0); j++; } if (j < survivors) { @@ -113,7 +116,11 @@ zip_close(zip_t *za) { return -1; } - if ((zip_source_supports(za->src) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE_CLONING)) == 0) { + if (ZIP_WANT_TORRENTZIP(za)) { + qsort(filelist, (size_t)survivors, sizeof(filelist[0]), torrentzip_compare_names); + } + + if (ZIP_WANT_TORRENTZIP(za) || (zip_source_supports(za->src) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE_CLONING)) == 0) { unchanged_offset = 0; } else { @@ -146,7 +153,7 @@ zip_close(zip_t *za) { } if (unchanged_offset == 0) { if (zip_source_begin_write(za->src) < 0) { - _zip_error_set_from_source(&za->error, za->src); + zip_error_set_from_source(&za->error, za->src); free(filelist); return -1; } @@ -178,7 +185,7 @@ zip_close(zip_t *za) { continue; } - new_data = (ZIP_ENTRY_DATA_CHANGED(entry) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_COMP_METHOD) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_ENCRYPTION_METHOD)); + new_data = (ZIP_ENTRY_DATA_CHANGED(entry) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_COMP_METHOD) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_ENCRYPTION_METHOD)) || (ZIP_WANT_TORRENTZIP(za) && !ZIP_IS_TORRENTZIP(za)); /* create new local directory entry */ if (entry->changes == NULL) { @@ -195,8 +202,12 @@ zip_close(zip_t *za) { break; } + if (ZIP_WANT_TORRENTZIP(za)) { + zip_dirent_torrentzip_normalize(entry->changes); + } + if ((off = zip_source_tell_write(za->src)) < 0) { - _zip_error_set_from_source(&za->error, za->src); + zip_error_set_from_source(&za->error, za->src); error = 1; break; } @@ -207,7 +218,7 @@ zip_close(zip_t *za) { zs = NULL; if (!ZIP_ENTRY_DATA_CHANGED(entry)) { - if ((zs = _zip_source_zip_new(za, za, i, ZIP_FL_UNCHANGED, 0, 0, NULL)) == NULL) { + if ((zs = zip_source_zip_file_create(za, i, ZIP_FL_UNCHANGED, 0, -1, NULL, &za->error)) == NULL) { error = 1; break; } @@ -240,7 +251,7 @@ zip_close(zip_t *za) { break; } if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) { - _zip_error_set_from_source(&za->error, za->src); + zip_error_set_from_source(&za->error, za->src); error = 1; break; } @@ -267,7 +278,7 @@ zip_close(zip_t *za) { if (!error) { if (zip_source_commit_write(za->src) != 0) { - _zip_error_set_from_source(&za->error, za->src); + zip_error_set_from_source(&za->error, za->src); error = 1; } _zip_progress_end(za->progress); @@ -296,7 +307,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) { bool needs_recompress, needs_decompress, needs_crc, needs_compress, needs_reencrypt, needs_decrypt, needs_encrypt; if (zip_source_stat(src, &st) < 0) { - _zip_error_set_from_source(&za->error, src); + zip_error_set_from_source(&za->error, src); return -1; } @@ -324,6 +335,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) { flags = ZIP_EF_LOCAL; if ((st.valid & ZIP_STAT_SIZE) == 0) { + /* TODO: not valid for torrentzip */ flags |= ZIP_FL_FORCE_ZIP64; data_length = -1; } @@ -350,6 +362,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) { } if (max_compressed_size > 0xffffffffu) { + /* TODO: not valid for torrentzip */ flags |= ZIP_FL_FORCE_ZIP64; } } @@ -360,7 +373,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) { } if ((offstart = zip_source_tell_write(za->src)) < 0) { - _zip_error_set_from_source(&za->error, za->src); + zip_error_set_from_source(&za->error, za->src); return -1; } @@ -370,7 +383,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) { return -1; } - needs_recompress = st.comp_method != ZIP_CM_ACTUAL(de->comp_method); + needs_recompress = ZIP_WANT_TORRENTZIP(za) || st.comp_method != ZIP_CM_ACTUAL(de->comp_method); needs_decompress = needs_recompress && (st.comp_method != ZIP_CM_STORE); /* in these cases we can compute the CRC ourselves, so we do */ needs_crc = (st.comp_method == ZIP_CM_STORE) || needs_decompress; @@ -383,6 +396,11 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) { src_final = src; zip_source_keep(src_final); + if (!needs_decrypt && st.encryption_method == ZIP_EM_TRAD_PKWARE && (de->changed & ZIP_DIRENT_LAST_MOD)) { + /* PKWare encryption uses the last modification time for password verification, therefore we can't change it without re-encrypting. Ignoring the requested modification time change seems more sensible than failing to close the archive. */ + de->changed &= ~ZIP_DIRENT_LAST_MOD; + } + if (needs_decrypt) { zip_encryption_implementation impl; @@ -397,7 +415,6 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) { return -1; } - zip_source_free(src_final); src_final = src_tmp; } @@ -407,17 +424,15 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) { return -1; } - zip_source_free(src_final); src_final = src_tmp; } if (needs_crc) { - if ((src_tmp = zip_source_crc(za, src_final, 0)) == NULL) { + if ((src_tmp = zip_source_crc_create(src_final, 0, &za->error)) == NULL) { zip_source_free(src_final); return -1; } - zip_source_free(src_final); src_final = src_tmp; } @@ -427,7 +442,6 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) { return -1; } - zip_source_free(src_final); src_final = src_tmp; } @@ -448,34 +462,48 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) { zip_source_free(src_final); return -1; } + + if (de->encryption_method == ZIP_EM_TRAD_PKWARE) { + de->bitflags |= ZIP_GPBF_DATA_DESCRIPTOR; + + /* PKWare encryption uses last_mod, make sure it gets the right value. */ + if (de->changed & ZIP_DIRENT_LAST_MOD) { + zip_stat_t st_mtime; + zip_stat_init(&st_mtime); + st_mtime.valid = ZIP_STAT_MTIME; + st_mtime.mtime = de->last_mod; + if ((src_tmp = _zip_source_window_new(src_final, 0, -1, &st_mtime, 0, NULL, NULL, 0, true, &za->error)) == NULL) { + zip_source_free(src_final); + return -1; + } + src_final = src_tmp; + } + } + if ((src_tmp = impl(za, src_final, de->encryption_method, ZIP_CODEC_ENCODE, password)) == NULL) { /* error set by impl */ zip_source_free(src_final); return -1; } - if (de->encryption_method == ZIP_EM_TRAD_PKWARE) { - de->bitflags |= ZIP_GPBF_DATA_DESCRIPTOR; - } - zip_source_free(src_final); src_final = src_tmp; } if ((offdata = zip_source_tell_write(za->src)) < 0) { - _zip_error_set_from_source(&za->error, za->src); + zip_error_set_from_source(&za->error, za->src); return -1; } ret = copy_source(za, src_final, data_length); if (zip_source_stat(src_final, &st) < 0) { - _zip_error_set_from_source(&za->error, src_final); + zip_error_set_from_source(&za->error, src_final); ret = -1; } if (zip_source_get_file_attributes(src_final, &attributes) != 0) { - _zip_error_set_from_source(&za->error, src_final); + zip_error_set_from_source(&za->error, src_final); ret = -1; } @@ -486,12 +514,12 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) { } if ((offend = zip_source_tell_write(za->src)) < 0) { - _zip_error_set_from_source(&za->error, za->src); + zip_error_set_from_source(&za->error, za->src); return -1; } if (zip_source_seek_write(za->src, offstart, SEEK_SET) < 0) { - _zip_error_set_from_source(&za->error, za->src); + zip_error_set_from_source(&za->error, za->src); return -1; } @@ -512,6 +540,10 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) { de->comp_size = (zip_uint64_t)(offend - offdata); _zip_dirent_apply_attributes(de, &attributes, (flags & ZIP_FL_FORCE_ZIP64) != 0, changed); + if (ZIP_WANT_TORRENTZIP(za)) { + zip_dirent_torrentzip_normalize(de); + } + if ((ret = _zip_dirent_write(za, de, flags)) < 0) return -1; @@ -522,7 +554,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) { } if (zip_source_seek_write(za->src, offend, SEEK_SET) < 0) { - _zip_error_set_from_source(&za->error, za->src); + zip_error_set_from_source(&za->error, za->src); return -1; } @@ -539,7 +571,6 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) { static int copy_data(zip_t *za, zip_uint64_t len) { DEFINE_BYTE_ARRAY(buf, BUFSIZE); - size_t n; double total = (double)len; if (!byte_array_init(buf, BUFSIZE)) { @@ -547,12 +578,9 @@ copy_data(zip_t *za, zip_uint64_t len) { return -1; } - uint64_t maxMemSize = SIZE_MAX; - if (len >= maxMemSize) - return -1; - while (len > 0) { - n = len > BUFSIZE ? BUFSIZE : (size_t) len; + zip_uint64_t n = ZIP_MIN(len, BUFSIZE); + if (_zip_read(za->src, buf, n, &za->error) < 0) { byte_array_fini(buf); return -1; @@ -583,7 +611,7 @@ copy_source(zip_t *za, zip_source_t *src, zip_int64_t data_length) { int ret; if (zip_source_open(src) < 0) { - _zip_error_set_from_source(&za->error, src); + zip_error_set_from_source(&za->error, src); return -1; } @@ -610,7 +638,7 @@ copy_source(zip_t *za, zip_source_t *src, zip_int64_t data_length) { } if (n < 0) { - _zip_error_set_from_source(&za->error, src); + zip_error_set_from_source(&za->error, src); ret = -1; } @@ -623,17 +651,15 @@ copy_source(zip_t *za, zip_source_t *src, zip_int64_t data_length) { static int write_cdir(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors) { - zip_int64_t cd_start, end, size; - - if ((cd_start = zip_source_tell_write(za->src)) < 0) { + if (zip_source_tell_write(za->src) < 0) { return -1; } - if ((size = _zip_cdir_write(za, filelist, survivors)) < 0) { + if (_zip_cdir_write(za, filelist, survivors) < 0) { return -1; } - if ((end = zip_source_tell_write(za->src)) < 0) { + if (zip_source_tell_write(za->src) < 0) { return -1; } @@ -649,7 +675,7 @@ _zip_changed(const zip_t *za, zip_uint64_t *survivorsp) { changed = 0; survivors = 0; - if (za->comment_changed || za->ch_flags != za->flags) { + if (za->comment_changed || (ZIP_WANT_TORRENTZIP(za) && !ZIP_IS_TORRENTZIP(za))) { changed = 1; } @@ -702,3 +728,18 @@ write_data_descriptor(zip_t *za, const zip_dirent_t *de, int is_zip64) { return ret; } + + +static int torrentzip_compare_names(const void *a, const void *b) { + const char *aname = ((const zip_filelist_t *)a)->name; + const char *bname = ((const zip_filelist_t *)b)->name; + + if (aname == NULL) { + return (bname != NULL) * -1; + } + else if (bname == NULL) { + return 1; + } + + return strcasecmp(aname, bname); +} \ No newline at end of file diff --git a/Source/Libraries/libzip/zip_delete.c b/Libraries/libzip/Source/zip_delete.c similarity index 95% rename from Source/Libraries/libzip/zip_delete.c rename to Libraries/libzip/Source/zip_delete.c index 4ff4c1abe..676c16bf2 100644 --- a/Source/Libraries/libzip/zip_delete.c +++ b/Libraries/libzip/Source/zip_delete.c @@ -1,9 +1,9 @@ /* zip_delete.c -- delete file from zip archive - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_dir_add.c b/Libraries/libzip/Source/zip_dir_add.c similarity index 92% rename from Source/Libraries/libzip/zip_dir_add.c rename to Libraries/libzip/Source/zip_dir_add.c index da1e4a422..c01081916 100644 --- a/Source/Libraries/libzip/zip_dir_add.c +++ b/Libraries/libzip/Source/zip_dir_add.c @@ -1,9 +1,9 @@ /* zip_dir_add.c -- add directory - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -61,11 +61,11 @@ zip_dir_add(zip_t *za, const char *name, zip_flags_t flags) { len = strlen(name); if (name[len - 1] != '/') { - if ((s = (char *)malloc(len + 2)) == NULL) { + if (len > SIZE_MAX - 2 || (s = (char *)malloc(len + 2)) == NULL) { zip_error_set(&za->error, ZIP_ER_MEMORY, 0); return -1; } - strcpy(s, name); + (void)strncpy_s(s, len + 2, name, len); s[len] = '/'; s[len + 1] = '\0'; } diff --git a/Source/Libraries/libzip/zip_dirent.c b/Libraries/libzip/Source/zip_dirent.c similarity index 85% rename from Source/Libraries/libzip/zip_dirent.c rename to Libraries/libzip/Source/zip_dirent.c index 5226a6e1f..45a2a6a29 100644 --- a/Source/Libraries/libzip/zip_dirent.c +++ b/Libraries/libzip/Source/zip_dirent.c @@ -1,9 +1,9 @@ /* zip_dirent.c -- read directory entry (local or central), clean dirent - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -37,6 +37,7 @@ #include #include #include +#include #include "zipint.h" @@ -127,15 +128,21 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor zip_uint64_t i; bool is_zip64; int ret; + zip_uint32_t cdir_crc; if ((off = zip_source_tell_write(za->src)) < 0) { - _zip_error_set_from_source(&za->error, za->src); + zip_error_set_from_source(&za->error, za->src); return -1; } offset = (zip_uint64_t)off; is_zip64 = false; + if (ZIP_WANT_TORRENTZIP(za)) { + cdir_crc = (zip_uint32_t)crc32(0, NULL, 0); + za->write_crc = &cdir_crc; + } + for (i = 0; i < survivors; i++) { zip_entry_t *entry = za->entry + filelist[i].idx; @@ -145,15 +152,17 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor is_zip64 = true; } + za->write_crc = NULL; + if ((off = zip_source_tell_write(za->src)) < 0) { - _zip_error_set_from_source(&za->error, za->src); + zip_error_set_from_source(&za->error, za->src); return -1; } size = (zip_uint64_t)off - offset; - if (offset > ZIP_UINT32_MAX || survivors > ZIP_UINT16_MAX) + if (offset > ZIP_UINT32_MAX || survivors > ZIP_UINT16_MAX) { is_zip64 = true; - + } if ((buffer = _zip_buffer_new(buf, sizeof(buf))) == NULL) { zip_error_set(&za->error, ZIP_ER_MEMORY, 0); @@ -186,7 +195,13 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor comment = za->comment_changed ? za->comment_changes : za->comment_orig; - _zip_buffer_put_16(buffer, (zip_uint16_t)(comment ? comment->length : 0)); + if (ZIP_WANT_TORRENTZIP(za)) { + _zip_buffer_put_16(buffer, TORRENTZIP_SIGNATURE_LENGTH + TORRENTZIP_CRC_LENGTH); + } + else { + _zip_buffer_put_16(buffer, (zip_uint16_t)(comment ? comment->length : 0)); + } + if (!_zip_buffer_ok(buffer)) { zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); @@ -201,7 +216,15 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor _zip_buffer_free(buffer); - if (comment) { + if (ZIP_WANT_TORRENTZIP(za)) { + char torrentzip_comment[TORRENTZIP_SIGNATURE_LENGTH + TORRENTZIP_CRC_LENGTH + 1]; + snprintf(torrentzip_comment, sizeof(torrentzip_comment), TORRENTZIP_SIGNATURE "%08X", cdir_crc); + + if (_zip_write(za, torrentzip_comment, strlen(torrentzip_comment)) < 0) { + return -1; + } + } + else if (comment != NULL) { if (_zip_write(za, comment->raw, comment->length) < 0) { return -1; } @@ -219,7 +242,7 @@ _zip_dirent_clone(const zip_dirent_t *sde) { return NULL; if (sde) - memcpy(tde, sde, sizeof(*sde)); + (void)memcpy_s(tde, sizeof(*tde), sde, sizeof(*sde)); else _zip_dirent_init(tde); @@ -421,7 +444,7 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo if (from_buffer) { if (_zip_buffer_left(buffer) < variable_size) { - zip_error_set(error, ZIP_ER_INCONS, 0); + zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_VARIABLE_SIZE_OVERFLOW); return -1; } } @@ -437,7 +460,7 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo zde->filename = _zip_read_string(buffer, src, filename_len, 1, error); if (!zde->filename) { if (zip_error_code_zip(error) == ZIP_ER_EOF) { - zip_error_set(error, ZIP_ER_INCONS, 0); + zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_VARIABLE_SIZE_OVERFLOW); } if (!from_buffer) { _zip_buffer_free(buffer); @@ -447,7 +470,7 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) { if (_zip_guess_encoding(zde->filename, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) { - zip_error_set(error, ZIP_ER_INCONS, 0); + zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_INVALID_UTF8_IN_FILENAME); if (!from_buffer) { _zip_buffer_free(buffer); } @@ -487,7 +510,7 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo } if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) { if (_zip_guess_encoding(zde->comment, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) { - zip_error_set(error, ZIP_ER_INCONS, 0); + zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_INVALID_UTF8_IN_COMMENT); if (!from_buffer) { _zip_buffer_free(buffer); } @@ -503,76 +526,18 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo if (zde->uncomp_size == ZIP_UINT32_MAX || zde->comp_size == ZIP_UINT32_MAX || zde->offset == ZIP_UINT32_MAX) { zip_uint16_t got_len; - zip_buffer_t *ef_buffer; const zip_uint8_t *ef = _zip_ef_get_by_id(zde->extra_fields, &got_len, ZIP_EF_ZIP64, 0, local ? ZIP_EF_LOCAL : ZIP_EF_CENTRAL, error); - /* TODO: if got_len == 0 && !ZIP64_EOCD: no error, 0xffffffff is valid value */ - if (ef == NULL) { - if (!from_buffer) { - _zip_buffer_free(buffer); - } - return -1; - } - - if ((ef_buffer = _zip_buffer_new((zip_uint8_t *)ef, got_len)) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - if (!from_buffer) { - _zip_buffer_free(buffer); - } - return -1; - } - - if (zde->uncomp_size == ZIP_UINT32_MAX) { - zde->uncomp_size = _zip_buffer_get_64(ef_buffer); - } - else if (local) { - /* From appnote.txt: This entry in the Local header MUST - include BOTH original and compressed file size fields. */ - (void)_zip_buffer_skip(ef_buffer, 8); /* error is caught by _zip_buffer_eof() call */ - } - if (zde->comp_size == ZIP_UINT32_MAX) { - zde->comp_size = _zip_buffer_get_64(ef_buffer); - } - if (!local) { - if (zde->offset == ZIP_UINT32_MAX) { - zde->offset = _zip_buffer_get_64(ef_buffer); - } - if (zde->disk_number == ZIP_UINT16_MAX) { - zde->disk_number = _zip_buffer_get_32(ef_buffer); - } - } - - if (!_zip_buffer_eof(ef_buffer)) { - /* accept additional fields if values match */ - bool ok = true; - switch (got_len) { - case 28: - _zip_buffer_set_offset(ef_buffer, 24); - if (zde->disk_number != _zip_buffer_get_32(ef_buffer)) { - ok = false; - } - /* fallthrough */ - case 24: - _zip_buffer_set_offset(ef_buffer, 0); - if ((zde->uncomp_size != _zip_buffer_get_64(ef_buffer)) || (zde->comp_size != _zip_buffer_get_64(ef_buffer)) || (zde->offset != _zip_buffer_get_64(ef_buffer))) { - ok = false; - } - break; - - default: - ok = false; - } - if (!ok) { - zip_error_set(error, ZIP_ER_INCONS, 0); - _zip_buffer_free(ef_buffer); + if (ef != NULL) { + if (!zip_dirent_process_ef_zip64(zde, ef, got_len, local, error)) { if (!from_buffer) { _zip_buffer_free(buffer); } return -1; } } - _zip_buffer_free(ef_buffer); } + if (!_zip_buffer_ok(buffer)) { zip_error_set(error, ZIP_ER_INTERNAL, 0); if (!from_buffer) { @@ -599,6 +564,65 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo return (zip_int64_t)size + (zip_int64_t)variable_size; } +bool zip_dirent_process_ef_zip64(zip_dirent_t* zde, const zip_uint8_t* ef, zip_uint64_t got_len, bool local, zip_error_t* error) { + zip_buffer_t *ef_buffer; + + if ((ef_buffer = _zip_buffer_new((zip_uint8_t *)ef, got_len)) == NULL) { + zip_error_set(error, ZIP_ER_MEMORY, 0); + return false; + } + + if (zde->uncomp_size == ZIP_UINT32_MAX) { + zde->uncomp_size = _zip_buffer_get_64(ef_buffer); + } + else if (local) { + /* From appnote.txt: This entry in the Local header MUST + include BOTH original and compressed file size fields. */ + (void)_zip_buffer_skip(ef_buffer, 8); /* error is caught by _zip_buffer_eof() call */ + } + if (zde->comp_size == ZIP_UINT32_MAX) { + zde->comp_size = _zip_buffer_get_64(ef_buffer); + } + if (!local) { + if (zde->offset == ZIP_UINT32_MAX) { + zde->offset = _zip_buffer_get_64(ef_buffer); + } + if (zde->disk_number == ZIP_UINT16_MAX) { + zde->disk_number = _zip_buffer_get_32(ef_buffer); + } + } + + if (!_zip_buffer_eof(ef_buffer)) { + /* accept additional fields if values match */ + bool ok = true; + switch (got_len) { + case 28: + _zip_buffer_set_offset(ef_buffer, 24); + if (zde->disk_number != _zip_buffer_get_32(ef_buffer)) { + ok = false; + } + /* fallthrough */ + case 24: + _zip_buffer_set_offset(ef_buffer, 0); + if ((zde->uncomp_size != _zip_buffer_get_64(ef_buffer)) || (zde->comp_size != _zip_buffer_get_64(ef_buffer)) || (zde->offset != _zip_buffer_get_64(ef_buffer))) { + ok = false; + } + break; + + default: + ok = false; + } + if (!ok) { + zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_INVALID_ZIP64_EF); + _zip_buffer_free(ef_buffer); + return false; + } + } + _zip_buffer_free(ef_buffer); + + return true; +} + static zip_string_t * _zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str) { @@ -651,7 +675,7 @@ _zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error) { ef = _zip_ef_get_by_id(de->extra_fields, &ef_len, ZIP_EF_WINZIP_AES, 0, ZIP_EF_BOTH, NULL); if (ef == NULL || ef_len < 7) { - zip_error_set(error, ZIP_ER_INCONS, 0); + zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_INVALID_WINZIPAES_EF); return false; } @@ -664,19 +688,18 @@ _zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error) { crc_valid = true; switch (_zip_buffer_get_16(buffer)) { - case 1: - break; + case 1: + break; - case 2: - if (de->uncomp_size < 20 /* TODO: constant */) { + case 2: crc_valid = false; - } - break; - - default: - zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0); - _zip_buffer_free(buffer); - return false; + /* TODO: When checking consistency, check that crc is 0. */ + break; + + default: + zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0); + _zip_buffer_free(buffer); + return false; } /* vendor */ @@ -704,7 +727,7 @@ _zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error) { } if (ef_len != 7) { - zip_error_set(error, ZIP_ER_INCONS, 0); + zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_INVALID_WINZIPAES_EF); _zip_buffer_free(buffer); return false; } @@ -729,7 +752,7 @@ _zip_dirent_size(zip_source_t *src, zip_uint16_t flags, zip_error_t *error) { size = local ? LENTRYSIZE : CDENTRYSIZE; if (zip_source_seek(src, local ? 26 : 28, SEEK_CUR) < 0) { - _zip_error_set_from_source(error, src); + zip_error_set_from_source(error, src); return -1; } @@ -902,7 +925,13 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) { _zip_buffer_put_16(buffer, (zip_uint16_t)de->comp_method); } - _zip_u2d_time(de->last_mod, &dostime, &dosdate); + if (ZIP_WANT_TORRENTZIP(za)) { + dostime = 0xbc00; + dosdate = 0x2198; + } + else { + _zip_u2d_time(de->last_mod, &dostime, &dosdate); + } _zip_buffer_put_16(buffer, dostime); _zip_buffer_put_16(buffer, dosdate); @@ -938,12 +967,15 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) { } _zip_buffer_put_16(buffer, _zip_string_length(de->filename)); - /* TODO: check for overflow */ - ef_total_size = (zip_uint32_t)_zip_ef_size(de->extra_fields, flags) + (zip_uint32_t)_zip_ef_size(ef, ZIP_EF_BOTH); + ef_total_size = (zip_uint32_t)_zip_ef_size(ef, ZIP_EF_BOTH); + if (!ZIP_WANT_TORRENTZIP(za)) { + /* TODO: check for overflow */ + ef_total_size += (zip_uint32_t)_zip_ef_size(de->extra_fields, flags); + } _zip_buffer_put_16(buffer, (zip_uint16_t)ef_total_size); if ((flags & ZIP_FL_LOCAL) == 0) { - _zip_buffer_put_16(buffer, _zip_string_length(de->comment)); + _zip_buffer_put_16(buffer, ZIP_WANT_TORRENTZIP(za) ? 0 : _zip_string_length(de->comment)); _zip_buffer_put_16(buffer, (zip_uint16_t)de->disk_number); _zip_buffer_put_16(buffer, de->int_attrib); _zip_buffer_put_32(buffer, de->ext_attrib); @@ -982,13 +1014,13 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) { } } _zip_ef_free(ef); - if (de->extra_fields) { + if (de->extra_fields && !ZIP_WANT_TORRENTZIP(za)) { if (_zip_ef_write(za, de->extra_fields, flags) < 0) { return -1; } } - if ((flags & ZIP_FL_LOCAL) == 0) { + if ((flags & ZIP_FL_LOCAL) == 0 && !ZIP_WANT_TORRENTZIP(za)) { if (de->comment) { if (_zip_string_write(za, de->comment) < 0) { return -1; @@ -1090,15 +1122,10 @@ _zip_get_dirent(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_error_t *err void _zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate) { struct tm *tpm; - -#ifdef HAVE_LOCALTIME_R struct tm tm; - tpm = localtime_r(&intime, &tm); -#else - tpm = localtime(&intime); -#endif + tpm = zip_localtime(&intime, &tm); if (tpm == NULL) { - /* if localtime() fails, return an arbitrary date (1980-01-01 00:00:00) */ + /* if localtime fails, return an arbitrary date (1980-01-01 00:00:00) */ *ddate = (1 << 5) + 1; *dtime = 0; return; @@ -1109,8 +1136,6 @@ _zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate) { *ddate = (zip_uint16_t)(((tpm->tm_year + 1900 - 1980) << 9) + ((tpm->tm_mon + 1) << 5) + tpm->tm_mday); *dtime = (zip_uint16_t)(((tpm->tm_hour) << 11) + ((tpm->tm_min) << 5) + ((tpm->tm_sec) >> 1)); - - return; } @@ -1161,3 +1186,22 @@ _zip_dirent_apply_attributes(zip_dirent_t *de, zip_file_attributes_t *attributes de->version_madeby = (de->version_madeby & 0xff) | (zip_uint16_t)(attributes->host_system << 8); } } + + +/* _zip_dirent_torrent_normalize(de); + Set values suitable for torrentzip. +*/ + +void zip_dirent_torrentzip_normalize(zip_dirent_t *de) { + de->version_madeby = 0; + de->version_needed = 20; /* 2.0 */ + de->bitflags = 2; /* maximum compression */ + de->comp_method = ZIP_CM_DEFLATE; + de->compression_level = TORRENTZIP_COMPRESSION_FLAGS; + de->disk_number = 0; + de->int_attrib = 0; + de->ext_attrib = 0; + + /* last_mod, extra_fields, and comment are normalized in zip_dirent_write() directly */ + +} diff --git a/Source/Libraries/libzip/zip_discard.c b/Libraries/libzip/Source/zip_discard.c similarity index 95% rename from Source/Libraries/libzip/zip_discard.c rename to Libraries/libzip/Source/zip_discard.c index a29a2884b..d1dc4f8b0 100644 --- a/Source/Libraries/libzip/zip_discard.c +++ b/Libraries/libzip/Source/zip_discard.c @@ -1,9 +1,9 @@ /* zip_discard.c -- discard and free struct zip - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_entry.c b/Libraries/libzip/Source/zip_entry.c similarity index 94% rename from Source/Libraries/libzip/zip_entry.c rename to Libraries/libzip/Source/zip_entry.c index 837b59c13..35a36e4a1 100644 --- a/Source/Libraries/libzip/zip_entry.c +++ b/Libraries/libzip/Source/zip_entry.c @@ -1,9 +1,9 @@ /* zip_entry.c -- struct zip_entry helper functions - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Libraries/libzip/Source/zip_err_str.c b/Libraries/libzip/Source/zip_err_str.c new file mode 100644 index 000000000..28af773bc --- /dev/null +++ b/Libraries/libzip/Source/zip_err_str.c @@ -0,0 +1,79 @@ +/* + This file was generated automatically by CMake + from zip.h and zipint.h; make changes there. +*/ + +#include "zipint.h" + +#define L ZIP_ET_LIBZIP +#define N ZIP_ET_NONE +#define S ZIP_ET_SYS +#define Z ZIP_ET_ZLIB + +#define E ZIP_DETAIL_ET_ENTRY +#define G ZIP_DETAIL_ET_GLOBAL + +const struct _zip_err_info _zip_err_str[] = { + { N, "No error" }, + { N, "Multi-disk zip archives not supported" }, + { S, "Renaming temporary file failed" }, + { S, "Closing zip archive failed" }, + { S, "Seek error" }, + { S, "Read error" }, + { S, "Write error" }, + { N, "CRC error" }, + { N, "Containing zip archive was closed" }, + { N, "No such file" }, + { N, "File already exists" }, + { S, "Can't open file" }, + { S, "Failure to create temporary file" }, + { Z, "Zlib error" }, + { N, "Malloc failure" }, + { N, "Entry has been changed" }, + { N, "Compression method not supported" }, + { N, "Premature end of file" }, + { N, "Invalid argument" }, + { N, "Not a zip archive" }, + { N, "Internal error" }, + { L, "Zip archive inconsistent" }, + { S, "Can't remove file" }, + { N, "Entry has been deleted" }, + { N, "Encryption method not supported" }, + { N, "Read-only archive" }, + { N, "No password provided" }, + { N, "Wrong password provided" }, + { N, "Operation not supported" }, + { N, "Resource still in use" }, + { S, "Tell error" }, + { N, "Compressed data invalid" }, + { N, "Operation cancelled" }, + { N, "Unexpected length of data" }, + { N, "Not allowed in torrentzip" }, +}; + +const int _zip_err_str_count = sizeof(_zip_err_str)/sizeof(_zip_err_str[0]); + +const struct _zip_err_info _zip_err_details[] = { + { G, "no detail" }, + { G, "central directory overlaps EOCD, or there is space between them" }, + { G, "archive comment length incorrect" }, + { G, "central directory length invalid" }, + { E, "central header invalid" }, + { G, "central directory count of entries is incorrect" }, + { E, "local and central headers do not match" }, + { G, "wrong EOCD length" }, + { G, "EOCD64 overlaps EOCD, or there is space between them" }, + { G, "EOCD64 magic incorrect" }, + { G, "EOCD64 and EOCD do not match" }, + { G, "invalid value in central directory" }, + { E, "variable size fields overflow header" }, + { E, "invalid UTF-8 in filename" }, + { E, "invalid UTF-8 in comment" }, + { E, "invalid Zip64 extra field" }, + { E, "invalid WinZip AES extra field" }, + { E, "garbage at end of extra fields" }, + { E, "extra field length is invalid" }, + { E, "file length in header doesn't match actual file length" }, +}; + +const int _zip_err_details_count = sizeof(_zip_err_details)/sizeof(_zip_err_details[0]); diff --git a/Source/Libraries/libzip/zip_error.c b/Libraries/libzip/Source/zip_error.c similarity index 85% rename from Source/Libraries/libzip/zip_error.c rename to Libraries/libzip/Source/zip_error.c index 9381d5bf8..c498e0860 100644 --- a/Source/Libraries/libzip/zip_error.c +++ b/Libraries/libzip/Source/zip_error.c @@ -1,9 +1,9 @@ /* zip_error.c -- zip_error_t helper functions - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -67,23 +67,24 @@ zip_error_init_with_code(zip_error_t *error, int ze) { zip_error_init(error); error->zip_err = ze; switch (zip_error_system_type(error)) { - case ZIP_ET_SYS: - error->sys_err = errno; - break; - - default: - error->sys_err = 0; - break; + case ZIP_ET_SYS: + case ZIP_ET_LIBZIP: + error->sys_err = errno; + break; + + default: + error->sys_err = 0; + break; } } ZIP_EXTERN int zip_error_system_type(const zip_error_t *error) { - if (error->zip_err < 0 || error->zip_err >= _zip_nerr_str) + if (error->zip_err < 0 || error->zip_err >= _zip_err_str_count) return ZIP_ET_NONE; - return _zip_err_type[error->zip_err]; + return _zip_err_str[error->zip_err].type; } @@ -131,7 +132,12 @@ zip_error_set(zip_error_t *err, int ze, int se) { void -_zip_error_set_from_source(zip_error_t *err, zip_source_t *src) { +zip_error_set_from_source(zip_error_t *err, zip_source_t *src) { + if (src == NULL) { + zip_error_set(err, ZIP_ER_INVAL, 0); + return; + } + _zip_error_copy(err, zip_source_error(src)); } diff --git a/Source/Libraries/libzip/zip_error_clear.c b/Libraries/libzip/Source/zip_error_clear.c similarity index 93% rename from Source/Libraries/libzip/zip_error_clear.c rename to Libraries/libzip/Source/zip_error_clear.c index 9bcd506ec..94ff5062d 100644 --- a/Source/Libraries/libzip/zip_error_clear.c +++ b/Libraries/libzip/Source/zip_error_clear.c @@ -1,9 +1,9 @@ /* zip_error_clear.c -- clear zip error - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_error_get.c b/Libraries/libzip/Source/zip_error_get.c similarity index 94% rename from Source/Libraries/libzip/zip_error_get.c rename to Libraries/libzip/Source/zip_error_get.c index 9d0ec03ff..c0418f0d0 100644 --- a/Source/Libraries/libzip/zip_error_get.c +++ b/Libraries/libzip/Source/zip_error_get.c @@ -1,9 +1,9 @@ /* zip_error_get.c -- get zip error - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_error_get_sys_type.c b/Libraries/libzip/Source/zip_error_get_sys_type.c similarity index 89% rename from Source/Libraries/libzip/zip_error_get_sys_type.c rename to Libraries/libzip/Source/zip_error_get_sys_type.c index 3c9998c57..a22ffb036 100644 --- a/Source/Libraries/libzip/zip_error_get_sys_type.c +++ b/Libraries/libzip/Source/zip_error_get_sys_type.c @@ -1,9 +1,9 @@ /* zip_error_get_sys_type.c -- return type of system error code - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -37,8 +37,9 @@ ZIP_EXTERN int zip_error_get_sys_type(int ze) { - if (ze < 0 || ze >= _zip_nerr_str) + if (ze < 0 || ze >= _zip_err_str_count) { return 0; + } - return _zip_err_type[ze]; + return _zip_err_str[ze].type; } diff --git a/Libraries/libzip/Source/zip_error_strerror.c b/Libraries/libzip/Source/zip_error_strerror.c new file mode 100644 index 000000000..fe04cbb4f --- /dev/null +++ b/Libraries/libzip/Source/zip_error_strerror.c @@ -0,0 +1,128 @@ +/* + zip_error_sterror.c -- get string representation of struct zip_error + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include +#include +#include +#include + +#include "zipint.h" + +ZIP_EXTERN const char * +zip_error_strerror(zip_error_t *err) { + const char *zip_error_string, *system_error_string; + char *s; + char *system_error_buffer = NULL; + + zip_error_fini(err); + + if (err->zip_err < 0 || err->zip_err >= _zip_err_str_count) { + system_error_buffer = (char *)malloc(128); + snprintf_s(system_error_buffer, 128, "Unknown error %d", err->zip_err); + system_error_buffer[128 - 1] = '\0'; /* make sure string is NUL-terminated */ + zip_error_string = NULL; + system_error_string = system_error_buffer; + } + else { + zip_error_string = _zip_err_str[err->zip_err].description; + + switch (_zip_err_str[err->zip_err].type) { + case ZIP_ET_SYS: { + size_t len = strerrorlen_s(err->sys_err) + 1; + system_error_buffer = malloc(len); + strerror_s(system_error_buffer, len, err->sys_err); + system_error_string = system_error_buffer; + break; + } + + case ZIP_ET_ZLIB: + system_error_string = zError(err->sys_err); + break; + + case ZIP_ET_LIBZIP: { + zip_uint8_t error = GET_ERROR_FROM_DETAIL(err->sys_err); + int index = GET_INDEX_FROM_DETAIL(err->sys_err); + + if (error == 0) { + system_error_string = NULL; + } + else if (error >= _zip_err_details_count) { + system_error_buffer = (char *)malloc(128); + snprintf_s(system_error_buffer, 128, "invalid detail error %u", error); + system_error_buffer[128 - 1] = '\0'; /* make sure string is NUL-terminated */ + system_error_string = system_error_buffer; + } + else if (_zip_err_details[error].type == ZIP_DETAIL_ET_ENTRY && index < MAX_DETAIL_INDEX) { + system_error_buffer = (char *)malloc(128); + snprintf_s(system_error_buffer, 128, "entry %d: %s", index, _zip_err_details[error].description); + system_error_buffer[128 - 1] = '\0'; /* make sure string is NUL-terminated */ + system_error_string = system_error_buffer; + } + else { + system_error_string = _zip_err_details[error].description; + } + break; + } + + default: + system_error_string = NULL; + } + } + + if (system_error_string == NULL) { + free(system_error_buffer); + return zip_error_string; + } + else { + size_t length = strlen(system_error_string); + if (zip_error_string) { + size_t length_error = strlen(zip_error_string); + if (length + length_error + 2 < length) { + free(system_error_buffer); + return _zip_err_str[ZIP_ER_MEMORY].description; + } + length += length_error + 2; + } + if (length == SIZE_MAX || (s = (char *)malloc(length + 1)) == NULL) { + free(system_error_buffer); + return _zip_err_str[ZIP_ER_MEMORY].description; + } + + snprintf_s(s, length + 1, "%s%s%s", (zip_error_string ? zip_error_string : ""), (zip_error_string ? ": " : ""), system_error_string); + err->str = s; + + free(system_error_buffer); + return s; + } +} diff --git a/Source/Libraries/libzip/zip_error_to_str.c b/Libraries/libzip/Source/zip_error_to_str.c similarity index 71% rename from Source/Libraries/libzip/zip_error_to_str.c rename to Libraries/libzip/Source/zip_error_to_str.c index d13e7a9bb..b60b78813 100644 --- a/Source/Libraries/libzip/zip_error_to_str.c +++ b/Libraries/libzip/Source/zip_error_to_str.c @@ -1,9 +1,9 @@ /* zip_error_to_str.c -- get string representation of zip error code - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -34,36 +34,25 @@ #include #include -#include #define _ZIP_COMPILING_DEPRECATED #include "zipint.h" -#define MAX_ERRORSTR_LEN (1ULL << 31) ZIP_EXTERN int zip_error_to_str(char *buf, zip_uint64_t len, int ze, int se) { - const char *zs, *ss; + zip_error_t error; + const char *error_string; + int ret; - size_t maxLen = (size_t) ((len < MAX_ERRORSTR_LEN) ? len : MAX_ERRORSTR_LEN); + zip_error_init(&error); + zip_error_set(&error, ze, se); - if (ze < 0 || ze >= _zip_nerr_str) - return snprintf(buf, maxLen, "Unknown error %d", ze); + error_string = zip_error_strerror(&error); - zs = _zip_err_str[ze]; + ret = snprintf_s(buf, ZIP_MIN(len, SIZE_MAX), error_string, strlen(error_string)); - switch (_zip_err_type[ze]) { - case ZIP_ET_SYS: - ss = strerror(se); - break; + zip_error_fini(&error); - case ZIP_ET_ZLIB: - ss = zError(se); - break; - - default: - ss = NULL; - } - - return snprintf(buf, maxLen, "%s%s%s", zs, (ss ? ": " : ""), (ss ? ss : "")); + return ret; } diff --git a/Source/Libraries/libzip/zip_extra_field.c b/Libraries/libzip/Source/zip_extra_field.c similarity index 95% rename from Source/Libraries/libzip/zip_extra_field.c rename to Libraries/libzip/Source/zip_extra_field.c index e45e1c1fc..7aed12adb 100644 --- a/Source/Libraries/libzip/zip_extra_field.c +++ b/Libraries/libzip/Source/zip_extra_field.c @@ -1,9 +1,9 @@ /* zip_extra_field.c -- manipulate extra fields - Copyright (C) 2012-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2012-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -219,7 +219,7 @@ _zip_ef_parse(const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags, zip_ ef_data = _zip_buffer_get(buffer, flen); if (ef_data == NULL) { - zip_error_set(error, ZIP_ER_INCONS, 0); + zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_INVALID_EF_LENGTH); _zip_buffer_free(buffer); _zip_ef_free(ef_head); return false; @@ -243,11 +243,12 @@ _zip_ef_parse(const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags, zip_ if (!_zip_buffer_eof(buffer)) { /* Android APK files align stored file data with padding in extra fields; ignore. */ /* see https://android.googlesource.com/platform/build/+/master/tools/zipalign/ZipAlign.cpp */ - zip_uint64_t glen = _zip_buffer_left(buffer); + /* buffer is at most 64k long, so this can't overflow. */ + size_t glen = _zip_buffer_left(buffer); zip_uint8_t *garbage; garbage = _zip_buffer_get(buffer, glen); - if ((glen >= 4) || (garbage == NULL) || (memcmp(garbage, "\0\0\0", (size_t) glen) != 0)) { - zip_error_set(error, ZIP_ER_INCONS, 0); + if (glen >= 4 || garbage == NULL || memcmp(garbage, "\0\0\0", (size_t)glen) != 0) { + zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EF_TRAILING_GARBAGE); _zip_buffer_free(buffer); _zip_ef_free(ef_head); return false; @@ -370,7 +371,7 @@ _zip_read_local_ef(zip_t *za, zip_uint64_t idx) { } if (zip_source_seek(za->src, (zip_int64_t)(e->orig->offset + 26), SEEK_SET) < 0) { - _zip_error_set_from_source(&za->error, za->src); + zip_error_set_from_source(&za->error, za->src); return -1; } diff --git a/Source/Libraries/libzip/zip_extra_field_api.c b/Libraries/libzip/Source/zip_extra_field_api.c similarity index 95% rename from Source/Libraries/libzip/zip_extra_field_api.c rename to Libraries/libzip/Source/zip_extra_field_api.c index cf2b0e7f1..560c71bb2 100644 --- a/Source/Libraries/libzip/zip_extra_field_api.c +++ b/Libraries/libzip/Source/zip_extra_field_api.c @@ -1,9 +1,9 @@ /* zip_extra_field_api.c -- public extra fields API functions - Copyright (C) 2012-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2012-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -56,6 +56,10 @@ zip_file_extra_field_delete(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_idx, zi zip_error_set(&za->error, ZIP_ER_RDONLY, 0); return -1; } + if (ZIP_WANT_TORRENTZIP(za)) { + zip_error_set(&za->error, ZIP_ER_NOT_ALLOWED, 0); + return -1; + } if (_zip_file_extra_field_prepare_for_change(za, idx) < 0) return -1; @@ -88,6 +92,10 @@ zip_file_extra_field_delete_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_i zip_error_set(&za->error, ZIP_ER_RDONLY, 0); return -1; } + if (ZIP_WANT_TORRENTZIP(za)) { + zip_error_set(&za->error, ZIP_ER_NOT_ALLOWED, 0); + return -1; + } if (_zip_file_extra_field_prepare_for_change(za, idx) < 0) return -1; @@ -236,6 +244,10 @@ zip_file_extra_field_set(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_ui zip_error_set(&za->error, ZIP_ER_RDONLY, 0); return -1; } + if (ZIP_WANT_TORRENTZIP(za)) { + zip_error_set(&za->error, ZIP_ER_NOT_ALLOWED, 0); + return -1; + } if (ZIP_EF_IS_INTERNAL(ef_id)) { zip_error_set(&za->error, ZIP_ER_INVAL, 0); diff --git a/Source/Libraries/libzip/zip_fclose.c b/Libraries/libzip/Source/zip_fclose.c similarity index 94% rename from Source/Libraries/libzip/zip_fclose.c rename to Libraries/libzip/Source/zip_fclose.c index 4d6fc59ce..b820d98bd 100644 --- a/Source/Libraries/libzip/zip_fclose.c +++ b/Libraries/libzip/Source/zip_fclose.c @@ -1,9 +1,9 @@ /* zip_fclose.c -- close file in zip archive - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_fdopen.c b/Libraries/libzip/Source/zip_fdopen.c similarity index 92% rename from Source/Libraries/libzip/zip_fdopen.c rename to Libraries/libzip/Source/zip_fdopen.c index 14f243fbb..e72c55dca 100644 --- a/Source/Libraries/libzip/zip_fdopen.c +++ b/Libraries/libzip/Source/zip_fdopen.c @@ -1,9 +1,9 @@ /* zip_fdopen.c -- open read-only archive from file descriptor - Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -51,6 +51,10 @@ zip_fdopen(int fd_orig, int _flags, int *zep) { return NULL; } +#ifndef ENABLE_FDOPEN + _zip_set_open_error(zep, NULL, ZIP_ER_OPNOTSUPP); + return NULL; +#else /* We dup() here to avoid messing with the passed in fd. We could not restore it to the original state in case of error. */ @@ -83,4 +87,5 @@ zip_fdopen(int fd_orig, int _flags, int *zep) { zip_error_fini(&error); close(fd_orig); return za; +#endif } diff --git a/Source/Libraries/libzip/zip_file_add.c b/Libraries/libzip/Source/zip_file_add.c similarity index 94% rename from Source/Libraries/libzip/zip_file_add.c rename to Libraries/libzip/Source/zip_file_add.c index 40386c095..c2c41e156 100644 --- a/Source/Libraries/libzip/zip_file_add.c +++ b/Libraries/libzip/Source/zip_file_add.c @@ -1,9 +1,9 @@ /* zip_file_add.c -- add file via callback function - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_file_error_clear.c b/Libraries/libzip/Source/zip_file_error_clear.c similarity index 93% rename from Source/Libraries/libzip/zip_file_error_clear.c rename to Libraries/libzip/Source/zip_file_error_clear.c index 863dae762..a10bff80c 100644 --- a/Source/Libraries/libzip/zip_file_error_clear.c +++ b/Libraries/libzip/Source/zip_file_error_clear.c @@ -1,9 +1,9 @@ /* zip_file_error_clear.c -- clear zip file error - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_file_error_get.c b/Libraries/libzip/Source/zip_file_error_get.c similarity index 93% rename from Source/Libraries/libzip/zip_file_error_get.c rename to Libraries/libzip/Source/zip_file_error_get.c index a47797646..b93117bb9 100644 --- a/Source/Libraries/libzip/zip_file_error_get.c +++ b/Libraries/libzip/Source/zip_file_error_get.c @@ -1,9 +1,9 @@ /* zip_file_error_get.c -- get zip file error - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_file_get_comment.c b/Libraries/libzip/Source/zip_file_get_comment.c similarity index 94% rename from Source/Libraries/libzip/zip_file_get_comment.c rename to Libraries/libzip/Source/zip_file_get_comment.c index 746186a71..fa998f02e 100644 --- a/Source/Libraries/libzip/zip_file_get_comment.c +++ b/Libraries/libzip/Source/zip_file_get_comment.c @@ -1,9 +1,9 @@ /* zip_file_get_comment.c -- get file comment - Copyright (C) 2006-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_file_get_external_attributes.c b/Libraries/libzip/Source/zip_file_get_external_attributes.c similarity index 94% rename from Source/Libraries/libzip/zip_file_get_external_attributes.c rename to Libraries/libzip/Source/zip_file_get_external_attributes.c index 6d4e0e490..a79bb3ed2 100644 --- a/Source/Libraries/libzip/zip_file_get_external_attributes.c +++ b/Libraries/libzip/Source/zip_file_get_external_attributes.c @@ -1,9 +1,9 @@ /* zip_file_get_external_attributes.c -- get opsys/external attributes - Copyright (C) 2013-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2013-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_file_get_offset.c b/Libraries/libzip/Source/zip_file_get_offset.c similarity index 92% rename from Source/Libraries/libzip/zip_file_get_offset.c rename to Libraries/libzip/Source/zip_file_get_offset.c index eb9b0178c..72f4880e7 100644 --- a/Source/Libraries/libzip/zip_file_get_offset.c +++ b/Libraries/libzip/Source/zip_file_get_offset.c @@ -1,9 +1,9 @@ /* zip_file_get_offset.c -- get offset of file data in archive. - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -57,7 +57,7 @@ _zip_file_get_offset(const zip_t *za, zip_uint64_t idx, zip_error_t *error) { offset = za->entry[idx].orig->offset; if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) { - _zip_error_set_from_source(error, za->src); + zip_error_set_from_source(error, za->src); return 0; } @@ -93,11 +93,11 @@ _zip_file_get_end(const zip_t *za, zip_uint64_t index, zip_error_t *error) { if (entry->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) { zip_uint8_t buf[4]; if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) { - _zip_error_set_from_source(error, za->src); + zip_error_set_from_source(error, za->src); return 0; } if (zip_source_read(za->src, buf, 4) != 4) { - _zip_error_set_from_source(error, za->src); + zip_error_set_from_source(error, za->src); return 0; } if (memcmp(buf, DATADES_MAGIC, 4) == 0) { diff --git a/Source/Libraries/libzip/zip_file_rename.c b/Libraries/libzip/Source/zip_file_rename.c similarity index 95% rename from Source/Libraries/libzip/zip_file_rename.c rename to Libraries/libzip/Source/zip_file_rename.c index a830b6aa8..9ac25814a 100644 --- a/Source/Libraries/libzip/zip_file_rename.c +++ b/Libraries/libzip/Source/zip_file_rename.c @@ -1,9 +1,9 @@ /* zip_file_rename.c -- rename file in zip archive - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_file_replace.c b/Libraries/libzip/Source/zip_file_replace.c similarity index 97% rename from Source/Libraries/libzip/zip_file_replace.c rename to Libraries/libzip/Source/zip_file_replace.c index c824d7fba..4262d453e 100644 --- a/Source/Libraries/libzip/zip_file_replace.c +++ b/Libraries/libzip/Source/zip_file_replace.c @@ -1,9 +1,9 @@ /* zip_file_replace.c -- replace file via callback function - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_file_set_comment.c b/Libraries/libzip/Source/zip_file_set_comment.c similarity index 93% rename from Source/Libraries/libzip/zip_file_set_comment.c rename to Libraries/libzip/Source/zip_file_set_comment.c index 8c76f25ac..570f8e821 100644 --- a/Source/Libraries/libzip/zip_file_set_comment.c +++ b/Libraries/libzip/Source/zip_file_set_comment.c @@ -1,9 +1,9 @@ /* zip_file_set_comment.c -- set comment for file in archive - Copyright (C) 2006-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -50,6 +50,10 @@ zip_file_set_comment(zip_t *za, zip_uint64_t idx, const char *comment, zip_uint1 zip_error_set(&za->error, ZIP_ER_RDONLY, 0); return -1; } + if (ZIP_WANT_TORRENTZIP(za)) { + zip_error_set(&za->error, ZIP_ER_NOT_ALLOWED, 0); + return -1; + } if (len > 0 && comment == NULL) { zip_error_set(&za->error, ZIP_ER_INVAL, 0); diff --git a/Source/Libraries/libzip/zip_file_set_encryption.c b/Libraries/libzip/Source/zip_file_set_encryption.c similarity index 94% rename from Source/Libraries/libzip/zip_file_set_encryption.c rename to Libraries/libzip/Source/zip_file_set_encryption.c index 6025e4a82..1cdcd4ab6 100644 --- a/Source/Libraries/libzip/zip_file_set_encryption.c +++ b/Libraries/libzip/Source/zip_file_set_encryption.c @@ -1,9 +1,9 @@ /* zip_file_set_encryption.c -- set encryption for file in archive - Copyright (C) 2016-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2016-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -51,6 +51,10 @@ zip_file_set_encryption(zip_t *za, zip_uint64_t idx, zip_uint16_t method, const zip_error_set(&za->error, ZIP_ER_RDONLY, 0); return -1; } + if (ZIP_WANT_TORRENTZIP(za)) { + zip_error_set(&za->error, ZIP_ER_NOT_ALLOWED, 0); + return -1; + } if (method != ZIP_EM_NONE && _zip_get_encryption_implementation(method, ZIP_CODEC_ENCODE) == NULL) { zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0); diff --git a/Source/Libraries/libzip/zip_file_set_external_attributes.c b/Libraries/libzip/Source/zip_file_set_external_attributes.c similarity index 93% rename from Source/Libraries/libzip/zip_file_set_external_attributes.c rename to Libraries/libzip/Source/zip_file_set_external_attributes.c index 0662f60d2..2e0429b8c 100644 --- a/Source/Libraries/libzip/zip_file_set_external_attributes.c +++ b/Libraries/libzip/Source/zip_file_set_external_attributes.c @@ -1,9 +1,9 @@ /* zip_file_set_external_attributes.c -- set external attributes for entry - Copyright (C) 2013-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2013-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -47,6 +47,10 @@ zip_file_set_external_attributes(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_error_set(&za->error, ZIP_ER_RDONLY, 0); return -1; } + if (ZIP_WANT_TORRENTZIP(za)) { + zip_error_set(&za->error, ZIP_ER_NOT_ALLOWED, 0); + return -1; + } e = za->entry + idx; diff --git a/Source/Libraries/libzip/zip_file_set_mtime.c b/Libraries/libzip/Source/zip_file_set_mtime.c similarity index 83% rename from Source/Libraries/libzip/zip_file_set_mtime.c rename to Libraries/libzip/Source/zip_file_set_mtime.c index 2753d595e..4126f5a16 100644 --- a/Source/Libraries/libzip/zip_file_set_mtime.c +++ b/Libraries/libzip/Source/zip_file_set_mtime.c @@ -1,9 +1,9 @@ /* zip_file_set_mtime.c -- set modification time of entry. - Copyright (C) 2014-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2014-2022 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -51,9 +51,18 @@ zip_file_set_mtime(zip_t *za, zip_uint64_t idx, time_t mtime, zip_flags_t flags) zip_error_set(&za->error, ZIP_ER_RDONLY, 0); return -1; } + if (ZIP_WANT_TORRENTZIP(za)) { + zip_error_set(&za->error, ZIP_ER_NOT_ALLOWED, 0); + return -1; + } e = za->entry + idx; + if (e->orig != NULL && e->orig->encryption_method == ZIP_EM_TRAD_PKWARE && !ZIP_ENTRY_CHANGED(e, ZIP_DIRENT_ENCRYPTION_METHOD) && !ZIP_ENTRY_DATA_CHANGED(e)) { + zip_error_set(&za->error, ZIP_ER_OPNOTSUPP, 0); + return -1; + } + if (e->changes == NULL) { if ((e->changes = _zip_dirent_clone(e->orig)) == NULL) { zip_error_set(&za->error, ZIP_ER_MEMORY, 0); diff --git a/Source/Libraries/libzip/zip_file_strerror.c b/Libraries/libzip/Source/zip_file_strerror.c similarity index 93% rename from Source/Libraries/libzip/zip_file_strerror.c rename to Libraries/libzip/Source/zip_file_strerror.c index 2dcdba72b..5b5a00924 100644 --- a/Source/Libraries/libzip/zip_file_strerror.c +++ b/Libraries/libzip/Source/zip_file_strerror.c @@ -1,9 +1,9 @@ /* zip_file_sterror.c -- get string representation of zip file error - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_fopen.c b/Libraries/libzip/Source/zip_fopen.c similarity index 94% rename from Source/Libraries/libzip/zip_fopen.c rename to Libraries/libzip/Source/zip_fopen.c index 2da0cc5f0..e3cde9be0 100644 --- a/Source/Libraries/libzip/zip_fopen.c +++ b/Libraries/libzip/Source/zip_fopen.c @@ -1,9 +1,9 @@ /* zip_fopen.c -- open file in zip archive for reading - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_fopen_encrypted.c b/Libraries/libzip/Source/zip_fopen_encrypted.c similarity index 94% rename from Source/Libraries/libzip/zip_fopen_encrypted.c rename to Libraries/libzip/Source/zip_fopen_encrypted.c index 80160152a..d5880dcb9 100644 --- a/Source/Libraries/libzip/zip_fopen_encrypted.c +++ b/Libraries/libzip/Source/zip_fopen_encrypted.c @@ -1,9 +1,9 @@ /* zip_fopen_encrypted.c -- open file for reading with password - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_fopen_index.c b/Libraries/libzip/Source/zip_fopen_index.c similarity index 93% rename from Source/Libraries/libzip/zip_fopen_index.c rename to Libraries/libzip/Source/zip_fopen_index.c index 5fd5f1a61..a449b83a0 100644 --- a/Source/Libraries/libzip/zip_fopen_index.c +++ b/Libraries/libzip/Source/zip_fopen_index.c @@ -1,9 +1,9 @@ /* zip_fopen_index.c -- open file in zip archive for reading by index - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_fopen_index_encrypted.c b/Libraries/libzip/Source/zip_fopen_index_encrypted.c similarity index 89% rename from Source/Libraries/libzip/zip_fopen_index_encrypted.c rename to Libraries/libzip/Source/zip_fopen_index_encrypted.c index 280a5bd0c..40483709e 100644 --- a/Source/Libraries/libzip/zip_fopen_index_encrypted.c +++ b/Libraries/libzip/Source/zip_fopen_index_encrypted.c @@ -1,9 +1,9 @@ /* zip_fopen_index_encrypted.c -- open file for reading by index w/ password - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -49,11 +49,11 @@ zip_fopen_index_encrypted(zip_t *za, zip_uint64_t index, zip_flags_t flags, cons password = NULL; } - if ((src = _zip_source_zip_new(za, za, index, flags, 0, 0, password)) == NULL) + if ((src = zip_source_zip_file_create(za, index, flags, 0, -1, password, &za->error)) == NULL) return NULL; if (zip_source_open(src) < 0) { - _zip_error_set_from_source(&za->error, src); + zip_error_set_from_source(&za->error, src); zip_source_free(src); return NULL; } @@ -78,9 +78,7 @@ _zip_file_new(zip_t *za) { return NULL; } - zf->za = za; zip_error_init(&zf->error); - zf->eof = 0; zf->src = NULL; return zf; diff --git a/Source/Libraries/libzip/zip_fread.c b/Libraries/libzip/Source/zip_fread.c similarity index 90% rename from Source/Libraries/libzip/zip_fread.c rename to Libraries/libzip/Source/zip_fread.c index ecf0c3b00..5b7da46ae 100644 --- a/Source/Libraries/libzip/zip_fread.c +++ b/Libraries/libzip/Source/zip_fread.c @@ -1,9 +1,9 @@ /* zip_fread.c -- read from file - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -50,11 +50,12 @@ zip_fread(zip_file_t *zf, void *outbuf, zip_uint64_t toread) { return -1; } - if ((zf->eof) || (toread == 0)) + if (toread == 0) { return 0; + } if ((n = zip_source_read(zf->src, outbuf, toread)) < 0) { - _zip_error_set_from_source(&zf->error, zf->src); + zip_error_set_from_source(&zf->error, zf->src); return -1; } diff --git a/Source/Libraries/libzip/zip_fseek.c b/Libraries/libzip/Source/zip_fseek.c similarity index 84% rename from Source/Libraries/libzip/zip_fseek.c rename to Libraries/libzip/Source/zip_fseek.c index 21f344a6e..e68ffd367 100644 --- a/Source/Libraries/libzip/zip_fseek.c +++ b/Libraries/libzip/Source/zip_fseek.c @@ -1,9 +1,9 @@ /* zip_fseek.c -- seek in file - Copyright (C) 2016-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2016-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -43,9 +43,19 @@ zip_fseek(zip_file_t *zf, zip_int64_t offset, int whence) { return -1; if (zip_source_seek(zf->src, offset, whence) < 0) { - _zip_error_set_from_source(&zf->error, zf->src); + zip_error_set_from_source(&zf->error, zf->src); return -1; } return 0; } + + +ZIP_EXTERN int +zip_file_is_seekable(zip_file_t *zfile) { + if (!zfile) { + return -1; + } + + return zip_source_is_seekable(zfile->src); +} diff --git a/Source/Libraries/libzip/zip_ftell.c b/Libraries/libzip/Source/zip_ftell.c similarity index 91% rename from Source/Libraries/libzip/zip_ftell.c rename to Libraries/libzip/Source/zip_ftell.c index 2b36770af..bf3b03d34 100644 --- a/Source/Libraries/libzip/zip_ftell.c +++ b/Libraries/libzip/Source/zip_ftell.c @@ -1,9 +1,9 @@ /* zip_ftell.c -- tell position in file - Copyright (C) 2016-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2016-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -46,7 +46,7 @@ zip_ftell(zip_file_t *zf) { res = zip_source_tell(zf->src); if (res < 0) { - _zip_error_set_from_source(&zf->error, zf->src); + zip_error_set_from_source(&zf->error, zf->src); return -1; } diff --git a/Source/Libraries/libzip/zip_get_archive_comment.c b/Libraries/libzip/Source/zip_get_archive_comment.c similarity index 94% rename from Source/Libraries/libzip/zip_get_archive_comment.c rename to Libraries/libzip/Source/zip_get_archive_comment.c index 18a4b6106..ea9a00ab5 100644 --- a/Source/Libraries/libzip/zip_get_archive_comment.c +++ b/Libraries/libzip/Source/zip_get_archive_comment.c @@ -1,9 +1,9 @@ /* zip_get_archive_comment.c -- get archive comment - Copyright (C) 2006-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_get_archive_flag.c b/Libraries/libzip/Source/zip_get_archive_flag.c similarity index 94% rename from Source/Libraries/libzip/zip_get_archive_flag.c rename to Libraries/libzip/Source/zip_get_archive_flag.c index 3185ac53a..fc200bdc4 100644 --- a/Source/Libraries/libzip/zip_get_archive_flag.c +++ b/Libraries/libzip/Source/zip_get_archive_flag.c @@ -1,9 +1,9 @@ /* zip_get_archive_flag.c -- get archive global flag - Copyright (C) 2008-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2008-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_get_encryption_implementation.c b/Libraries/libzip/Source/zip_get_encryption_implementation.c similarity index 95% rename from Source/Libraries/libzip/zip_get_encryption_implementation.c rename to Libraries/libzip/Source/zip_get_encryption_implementation.c index 3270b84d6..72e48fe87 100644 --- a/Source/Libraries/libzip/zip_get_encryption_implementation.c +++ b/Libraries/libzip/Source/zip_get_encryption_implementation.c @@ -1,9 +1,9 @@ /* zip_get_encryption_implementation.c -- get encryption implementation - Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -34,6 +34,7 @@ #include "zipint.h" + zip_encryption_implementation _zip_get_encryption_implementation(zip_uint16_t em, int operation) { switch (em) { diff --git a/Source/Libraries/libzip/zip_get_file_comment.c b/Libraries/libzip/Source/zip_get_file_comment.c similarity index 94% rename from Source/Libraries/libzip/zip_get_file_comment.c rename to Libraries/libzip/Source/zip_get_file_comment.c index 28429bc87..d58e22ba6 100644 --- a/Source/Libraries/libzip/zip_get_file_comment.c +++ b/Libraries/libzip/Source/zip_get_file_comment.c @@ -1,9 +1,9 @@ /* zip_get_file_comment.c -- get file comment - Copyright (C) 2006-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_get_name.c b/Libraries/libzip/Source/zip_get_name.c similarity index 94% rename from Source/Libraries/libzip/zip_get_name.c rename to Libraries/libzip/Source/zip_get_name.c index 1a4bab8f3..4828d7810 100644 --- a/Source/Libraries/libzip/zip_get_name.c +++ b/Libraries/libzip/Source/zip_get_name.c @@ -1,9 +1,9 @@ /* zip_get_name.c -- get filename for a file in zip file - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_get_num_entries.c b/Libraries/libzip/Source/zip_get_num_entries.c similarity index 94% rename from Source/Libraries/libzip/zip_get_num_entries.c rename to Libraries/libzip/Source/zip_get_num_entries.c index 3b18c7479..667dc5117 100644 --- a/Source/Libraries/libzip/zip_get_num_entries.c +++ b/Libraries/libzip/Source/zip_get_num_entries.c @@ -1,9 +1,9 @@ /* zip_get_num_entries.c -- get number of entries in archive - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_get_num_files.c b/Libraries/libzip/Source/zip_get_num_files.c similarity index 94% rename from Source/Libraries/libzip/zip_get_num_files.c rename to Libraries/libzip/Source/zip_get_num_files.c index 23d7c9c96..140e34f90 100644 --- a/Source/Libraries/libzip/zip_get_num_files.c +++ b/Libraries/libzip/Source/zip_get_num_files.c @@ -1,9 +1,9 @@ /* zip_get_num_files.c -- get number of files in archive - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_hash.c b/Libraries/libzip/Source/zip_hash.c similarity index 99% rename from Source/Libraries/libzip/zip_hash.c rename to Libraries/libzip/Source/zip_hash.c index 56e8d78ca..d3a954ec5 100644 --- a/Source/Libraries/libzip/zip_hash.c +++ b/Libraries/libzip/Source/zip_hash.c @@ -1,9 +1,9 @@ /* zip_hash.c -- hash table string -> uint64 - Copyright (C) 2015-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2015-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_io_util.c b/Libraries/libzip/Source/zip_io_util.c similarity index 85% rename from Source/Libraries/libzip/zip_io_util.c rename to Libraries/libzip/Source/zip_io_util.c index 3678dd59d..9fcd10b4b 100644 --- a/Source/Libraries/libzip/zip_io_util.c +++ b/Libraries/libzip/Source/zip_io_util.c @@ -1,9 +1,9 @@ /* zip_io_util.c -- I/O helper functions - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -31,8 +31,10 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include +#include #include "zipint.h" @@ -46,7 +48,7 @@ _zip_read(zip_source_t *src, zip_uint8_t *b, zip_uint64_t length, zip_error_t *e } if ((n = zip_source_read(src, b, length)) < 0) { - _zip_error_set_from_source(error, src); + zip_error_set_from_source(error, src); return -1; } @@ -81,7 +83,7 @@ _zip_read_data(zip_buffer_t *buffer, zip_source_t *src, size_t length, bool nulp free(r); return NULL; } - memcpy(r, data, length); + (void)memcpy_s(r, length, data, length); } else { if (_zip_read(src, r, length, error) < 0) { @@ -122,7 +124,7 @@ _zip_write(zip_t *za, const void *data, zip_uint64_t length) { zip_int64_t n; if ((n = zip_source_write(za->src, data, length)) < 0) { - _zip_error_set_from_source(&za->error, za->src); + zip_error_set_from_source(&za->error, za->src); return -1; } if ((zip_uint64_t)n != length) { @@ -130,5 +132,15 @@ _zip_write(zip_t *za, const void *data, zip_uint64_t length) { return -1; } + if (za->write_crc != NULL) { + zip_uint64_t position = 0; + while (position < length) { + zip_uint64_t nn = ZIP_MIN(UINT_MAX, length - position); + + *za->write_crc = (zip_uint32_t)crc32(*za->write_crc, (const Bytef *)data + position, (uInt)nn); + position += nn; + } + } + return 0; } diff --git a/Source/Libraries/libzip/zip_libzip_version.c b/Libraries/libzip/Source/zip_libzip_version.c similarity index 93% rename from Source/Libraries/libzip/zip_libzip_version.c rename to Libraries/libzip/Source/zip_libzip_version.c index df1e55b9c..4200727fc 100644 --- a/Source/Libraries/libzip/zip_libzip_version.c +++ b/Libraries/libzip/Source/zip_libzip_version.c @@ -1,9 +1,9 @@ /* zip_libzip_version.c -- return run-time version of library - Copyright (C) 2017-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2017-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_memdup.c b/Libraries/libzip/Source/zip_memdup.c similarity index 92% rename from Source/Libraries/libzip/zip_memdup.c rename to Libraries/libzip/Source/zip_memdup.c index 169186087..75d72c616 100644 --- a/Source/Libraries/libzip/zip_memdup.c +++ b/Libraries/libzip/Source/zip_memdup.c @@ -1,9 +1,9 @@ /* zip_memdup.c -- internal zip function, "strdup" with len - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -50,7 +50,7 @@ _zip_memdup(const void *mem, size_t len, zip_error_t *error) { return NULL; } - memcpy(ret, mem, len); + (void)memcpy_s(ret, len, mem, len); return ret; } diff --git a/Source/Libraries/libzip/zip_name_locate.c b/Libraries/libzip/Source/zip_name_locate.c similarity index 72% rename from Source/Libraries/libzip/zip_name_locate.c rename to Libraries/libzip/Source/zip_name_locate.c index 308d843c2..4248dc2d3 100644 --- a/Source/Libraries/libzip/zip_name_locate.c +++ b/Libraries/libzip/Source/zip_name_locate.c @@ -1,9 +1,9 @@ /* zip_name_locate.c -- get index by name - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -49,18 +49,38 @@ zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags) { zip_int64_t _zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags, zip_error_t *error) { int (*cmp)(const char *, const char *); + size_t fname_length; + zip_string_t *str = NULL; const char *fn, *p; zip_uint64_t i; - if (za == NULL) + if (za == NULL) { return -1; + } if (fname == NULL) { zip_error_set(error, ZIP_ER_INVAL, 0); return -1; } - if (flags & (ZIP_FL_NOCASE | ZIP_FL_NODIR | ZIP_FL_ENC_CP437)) { + fname_length = strlen(fname); + + if (fname_length > ZIP_UINT16_MAX) { + zip_error_set(error, ZIP_ER_INVAL, 0); + return -1; + } + + if ((flags & (ZIP_FL_ENC_UTF_8 | ZIP_FL_ENC_RAW)) == 0 && fname[0] != '\0') { + if ((str = _zip_string_new((const zip_uint8_t *)fname, (zip_uint16_t)strlen(fname), flags, error)) == NULL) { + return -1; + } + if ((fname = (const char *)_zip_string_get(str, NULL, 0, error)) == NULL) { + _zip_string_free(str); + return -1; + } + } + + if (flags & (ZIP_FL_NOCASE | ZIP_FL_NODIR | ZIP_FL_ENC_RAW | ZIP_FL_ENC_STRICT)) { /* can't use hash table */ cmp = (flags & ZIP_FL_NOCASE) ? strcasecmp : strcmp; @@ -79,14 +99,18 @@ _zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags, zip_error_t *e if (cmp(fname, fn) == 0) { _zip_error_clear(error); + _zip_string_free(str); return (zip_int64_t)i; } } zip_error_set(error, ZIP_ER_NOENT, 0); + _zip_string_free(str); return -1; } else { - return _zip_hash_lookup(za->names, (const zip_uint8_t *)fname, flags, error); + zip_int64_t ret = _zip_hash_lookup(za->names, (const zip_uint8_t *)fname, flags, error); + _zip_string_free(str); + return ret; } } diff --git a/Source/Libraries/libzip/zip_new.c b/Libraries/libzip/Source/zip_new.c similarity index 95% rename from Source/Libraries/libzip/zip_new.c rename to Libraries/libzip/Source/zip_new.c index d2a5fa14d..4f69c8a2f 100644 --- a/Source/Libraries/libzip/zip_new.c +++ b/Libraries/libzip/Source/zip_new.c @@ -1,9 +1,9 @@ /* zip_new.c -- create and init struct zip - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_open.c b/Libraries/libzip/Source/zip_open.c similarity index 77% rename from Source/Libraries/libzip/zip_open.c rename to Libraries/libzip/Source/zip_open.c index f957e3982..ee7e9decb 100644 --- a/Source/Libraries/libzip/zip_open.c +++ b/Libraries/libzip/Source/zip_open.c @@ -1,9 +1,9 @@ /* zip_open.c -- open zip archive by name - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -32,6 +32,7 @@ */ +#include #include #include #include @@ -41,10 +42,11 @@ typedef enum { EXISTS_ERROR = -1, EXISTS_NOT = 0, EXISTS_OK } exists_t; static zip_t *_zip_allocate_new(zip_source_t *src, unsigned int flags, zip_error_t *error); static zip_int64_t _zip_checkcons(zip_t *za, zip_cdir_t *cdir, zip_error_t *error); +static void zip_check_torrentzip(zip_t *za, const zip_cdir_t *cdir); static zip_cdir_t *_zip_find_central_dir(zip_t *za, zip_uint64_t len); static exists_t _zip_file_exists(zip_source_t *src, zip_error_t *error); static int _zip_headercomp(const zip_dirent_t *, const zip_dirent_t *); -static unsigned char *_zip_memmem(const unsigned char *, size_t, const unsigned char *, size_t); +static const unsigned char *_zip_memmem(const unsigned char *, size_t, const unsigned char *, size_t); static zip_cdir_t *_zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_error_t *error); static zip_cdir_t *_zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error); static zip_cdir_t *_zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error); @@ -77,9 +79,6 @@ zip_open(const char *fn, int _flags, int *zep) { ZIP_EXTERN zip_t * zip_open_from_source(zip_source_t *src, int _flags, zip_error_t *error) { - static zip_int64_t needed_support_read = -1; - static zip_int64_t needed_support_write = -1; - unsigned int flags; zip_int64_t supported; exists_t exists; @@ -91,15 +90,11 @@ zip_open_from_source(zip_source_t *src, int _flags, zip_error_t *error) { flags = (unsigned int)_flags; supported = zip_source_supports(src); - if (needed_support_read == -1) { - needed_support_read = zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_SEEK, ZIP_SOURCE_TELL, ZIP_SOURCE_STAT, -1); - needed_support_write = zip_source_make_command_bitmap(ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_REMOVE, -1); - } - if ((supported & needed_support_read) != needed_support_read) { + if ((supported & ZIP_SOURCE_SUPPORTS_SEEKABLE) != ZIP_SOURCE_SUPPORTS_SEEKABLE) { zip_error_set(error, ZIP_ER_OPNOTSUPP, 0); return NULL; } - if ((supported & needed_support_write) != needed_support_write) { + if ((supported & ZIP_SOURCE_SUPPORTS_WRITABLE) != ZIP_SOURCE_SUPPORTS_WRITABLE) { flags |= ZIP_RDONLY; } @@ -127,7 +122,7 @@ zip_open_from_source(zip_source_t *src, int _flags, zip_error_t *error) { return NULL; } if (zip_source_open(src) < 0) { - _zip_error_set_from_source(error, src); + zip_error_set_from_source(error, src); return NULL; } @@ -158,7 +153,7 @@ _zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error) { zip_stat_init(&st); if (zip_source_stat(src, &st) < 0) { - _zip_error_set_from_source(error, src); + zip_error_set_from_source(error, src); return NULL; } if ((st.valid & ZIP_STAT_SIZE) == 0) { @@ -188,7 +183,16 @@ _zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error) { za->entry = cdir->entry; za->nentry = cdir->nentry; za->nentry_alloc = cdir->nentry_alloc; - za->comment_orig = cdir->comment; + + zip_check_torrentzip(za, cdir); + + if (ZIP_IS_TORRENTZIP(za)) { + /* Torrentzip uses the archive comment to detect changes by tools that are not torrentzip aware. */ + _zip_string_free(cdir->comment); + } + else { + za->comment_orig = cdir->comment; + } free(cdir); @@ -224,8 +228,14 @@ void _zip_set_open_error(int *zep, const zip_error_t *err, int ze) { if (err) { ze = zip_error_code_zip(err); - if (zip_error_system_type(err) == ZIP_ET_SYS) { - errno = zip_error_code_system(err); + switch (zip_error_system_type(err)) { + case ZIP_ET_SYS: + case ZIP_ET_LIBZIP: + errno = zip_error_code_system(err); + break; + + default: + break; } } @@ -277,7 +287,7 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err if (cd->offset + cd->size > buf_offset + eocd_offset) { /* cdir spans past EOCD record */ - zip_error_set(error, ZIP_ER_INCONS, 0); + zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_OVERLAPS_EOCD); _zip_cdir_free(cd); return NULL; } @@ -289,7 +299,7 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err tail_len = _zip_buffer_left(buffer); if (tail_len < comment_len || ((za->open_flags & ZIP_CHECKCONS) && tail_len != comment_len)) { - zip_error_set(error, ZIP_ER_INCONS, 0); + zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_COMMENT_LENGTH_INVALID); _zip_cdir_free(cd); return NULL; } @@ -308,7 +318,7 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err _zip_buffer_set_offset(buffer, cd->offset - buf_offset); if ((data = _zip_buffer_get(buffer, cd->size)) == NULL) { - zip_error_set(error, ZIP_ER_INCONS, 0); + zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_LENGTH_INVALID); _zip_cdir_free(cd); return NULL; } @@ -322,7 +332,7 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err cd_buffer = NULL; if (zip_source_seek(za->src, (zip_int64_t)cd->offset, SEEK_SET) < 0) { - _zip_error_set_from_source(error, za->src); + zip_error_set_from_source(error, za->src); _zip_cdir_free(cd); return NULL; } @@ -358,8 +368,11 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err } if ((cd->entry[i].orig = _zip_dirent_new()) == NULL || (entry_size = _zip_dirent_read(cd->entry[i].orig, za->src, cd_buffer, false, error)) < 0) { - if (grown && zip_error_code_zip(error) == ZIP_ER_NOZIP) { - zip_error_set(error, ZIP_ER_INCONS, 0); + if (zip_error_code_zip(error) == ZIP_ER_INCONS) { + zip_error_set(error, ZIP_ER_INCONS, ADD_INDEX_TO_DETAIL(zip_error_code_system(error), i)); + } + else if (grown && zip_error_code_zip(error) == ZIP_ER_NOZIP) { + zip_error_set(error, ZIP_ER_INCONS, MAKE_DETAIL_WITH_INDEX(ZIP_ER_DETAIL_CDIR_ENTRY_INVALID, i)); } _zip_cdir_free(cd); _zip_buffer_free(cd_buffer); @@ -370,7 +383,7 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err } if (i != cd->nentry || left > 0) { - zip_error_set(error, ZIP_ER_INCONS, 0); + zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_WRONG_ENTRIES_COUNT); _zip_buffer_free(cd_buffer); _zip_cdir_free(cd); return NULL; @@ -386,7 +399,7 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err zip_int64_t offset = zip_source_tell(za->src); if (offset < 0) { - _zip_error_set_from_source(error, za->src); + zip_error_set_from_source(error, za->src); _zip_cdir_free(cd); return NULL; } @@ -394,7 +407,7 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err } if (!ok) { - zip_error_set(error, ZIP_ER_INCONS, 0); + zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_LENGTH_INVALID); _zip_buffer_free(cd_buffer); _zip_cdir_free(cd); return NULL; @@ -443,17 +456,20 @@ _zip_checkcons(zip_t *za, zip_cdir_t *cd, zip_error_t *error) { } if (zip_source_seek(za->src, (zip_int64_t)cd->entry[i].orig->offset, SEEK_SET) < 0) { - _zip_error_set_from_source(error, za->src); + zip_error_set_from_source(error, za->src); return -1; } if (_zip_dirent_read(&temp, za->src, NULL, true, error) == -1) { + if (zip_error_code_zip(error) == ZIP_ER_INCONS) { + zip_error_set(error, ZIP_ER_INCONS, ADD_INDEX_TO_DETAIL(zip_error_code_system(error), i)); + } _zip_dirent_finalize(&temp); return -1; } if (_zip_headercomp(cd->entry[i].orig, &temp) != 0) { - zip_error_set(error, ZIP_ER_INCONS, 0); + zip_error_set(error, ZIP_ER_INCONS, MAKE_DETAIL_WITH_INDEX(ZIP_ER_DETAIL_ENTRY_HEADER_MISMATCH, i)); _zip_dirent_finalize(&temp); return -1; } @@ -486,9 +502,20 @@ _zip_headercomp(const zip_dirent_t *central, const zip_dirent_t *local) { if ((central->crc != local->crc) || (central->comp_size != local->comp_size) || (central->uncomp_size != local->uncomp_size)) { /* InfoZip stores valid values in local header even when data descriptor is used. - This is in violation of the appnote. */ - if (((local->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0 || local->crc != 0 || local->comp_size != 0 || local->uncomp_size != 0)) + This is in violation of the appnote. + macOS Archive sets the compressed size even when data descriptor is used ( but not the others), + also in violation of the appnote. + */ + /* if data descriptor is not used, the values must match */ + if ((local->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0) { return -1; + } + /* when using a data descriptor, the local header value must be zero or match */ + if ((local->crc != 0 && central->crc != local->crc) || + (local->comp_size != 0 && central->comp_size != local->comp_size) || + (local->uncomp_size != 0 && central->uncomp_size != local->uncomp_size)) { + return -1; + } } return 0; @@ -505,10 +532,15 @@ _zip_allocate_new(zip_source_t *src, unsigned int flags, zip_error_t *error) { za->src = src; za->open_flags = flags; + za->flags = 0; + za->ch_flags = 0; + za->write_crc = NULL; + if (flags & ZIP_RDONLY) { za->flags |= ZIP_AFL_RDONLY; za->ch_flags |= ZIP_AFL_RDONLY; } + return za; } @@ -537,7 +569,7 @@ _zip_file_exists(zip_source_t *src, zip_error_t *error) { static zip_cdir_t * _zip_find_central_dir(zip_t *za, zip_uint64_t len) { zip_cdir_t *cdir, *cdirnew; - zip_uint8_t *match; + const zip_uint8_t *match; zip_int64_t buf_offset; zip_uint64_t buflen; zip_int64_t a; @@ -560,7 +592,7 @@ _zip_find_central_dir(zip_t *za, zip_uint64_t len) { } } if ((buf_offset = zip_source_tell(za->src)) < 0) { - _zip_error_set_from_source(&za->error, za->src); + zip_error_set_from_source(&za->error, za->src); return NULL; } @@ -576,14 +608,9 @@ _zip_find_central_dir(zip_t *za, zip_uint64_t len) { } zip_error_set(&error, ZIP_ER_NOZIP, 0); - // Check for 32bit overflow - zip_uint64_t zipBufferLeft = _zip_buffer_left(buffer); - uint64_t maxMemSize = SIZE_MAX; - if (zipBufferLeft >= maxMemSize) - return NULL; - match = _zip_buffer_get(buffer, 0); - while ((match = _zip_memmem(match, (size_t) (_zip_buffer_left(buffer) - (EOCDLEN - 4)), (const unsigned char *)EOCD_MAGIC, 4)) != NULL) { + /* The size of buffer never greater than CDBUFSIZE. */ + while (_zip_buffer_left(buffer) >= EOCDLEN && (match = _zip_memmem(match, (size_t)_zip_buffer_left(buffer) - (EOCDLEN - 4), (const unsigned char *)EOCD_MAGIC, 4)) != NULL) { _zip_buffer_set_offset(buffer, (zip_uint64_t)(match - _zip_buffer_data(buffer))); if ((cdirnew = _zip_read_cdir(za, buffer, (zip_uint64_t)buf_offset, &error)) != NULL) { if (cdir) { @@ -628,19 +655,28 @@ _zip_find_central_dir(zip_t *za, zip_uint64_t len) { } -static unsigned char * -_zip_memmem(const unsigned char *big, size_t biglen, const unsigned char *little, size_t littlelen) { +static const unsigned char *_zip_memmem(const unsigned char *big, size_t biglen, const unsigned char *little, size_t littlelen) { const unsigned char *p; - if ((biglen < littlelen) || (littlelen == 0)) + if (littlelen == 0) { + return big; + } + + if (biglen < littlelen) { return NULL; - p = big - 1; - while ((p = (const unsigned char *)memchr(p + 1, little[0], (size_t)(big - (p + 1)) + (size_t)(biglen - littlelen) + 1)) != NULL) { - if (memcmp(p + 1, little + 1, littlelen - 1) == 0) - return (unsigned char *)p; } - return NULL; + p = big; + while (true) { + p = (const unsigned char *)memchr(p, little[0], biglen - (littlelen - 1) - (size_t)(p - big)); + if (p == NULL) { + return NULL; + } + if (memcmp(p + 1, little + 1, littlelen - 1) == 0) { + return p; + } + p += 1; + } } @@ -650,7 +686,7 @@ _zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags zip_uint64_t i, nentry, size, offset, eocd_offset; if (_zip_buffer_left(buffer) < EOCDLEN) { - zip_error_set(error, ZIP_ER_INCONS, 0); + zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EOCD_LENGTH_INVALID); return NULL; } @@ -683,12 +719,12 @@ _zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags if (offset + size > buf_offset + eocd_offset) { /* cdir spans past EOCD record */ - zip_error_set(error, ZIP_ER_INCONS, 0); + zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_OVERLAPS_EOCD); return NULL; } if ((flags & ZIP_CHECKCONS) && offset + size != buf_offset + eocd_offset) { - zip_error_set(error, ZIP_ER_INCONS, 0); + zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_LENGTH_INVALID); return NULL; } @@ -729,7 +765,7 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse /* does EOCD fit before EOCD locator? */ if (eocd_offset + EOCD64LEN > eocdloc_offset + buf_offset) { - zip_error_set(error, ZIP_ER_INCONS, 0); + zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EOCD64_OVERLAPS_EOCD); return NULL; } @@ -740,7 +776,7 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse } else { if (zip_source_seek(src, (zip_int64_t)eocd_offset, SEEK_SET) < 0) { - _zip_error_set_from_source(error, src); + zip_error_set_from_source(error, src); return NULL; } if ((buffer = _zip_buffer_new_from_source(src, EOCD64LEN, eocd, error)) == NULL) { @@ -750,7 +786,7 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse } if (memcmp(_zip_buffer_get(buffer, 4), EOCD64_MAGIC, 4) != 0) { - zip_error_set(error, ZIP_ER_INCONS, 0); + zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EOCD64_WRONG_MAGIC); if (free_buffer) { _zip_buffer_free(buffer); } @@ -762,7 +798,7 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse /* is there a hole between EOCD and EOCD locator, or do they overlap? */ if ((flags & ZIP_CHECKCONS) && size + eocd_offset + 12 != buf_offset + eocdloc_offset) { - zip_error_set(error, ZIP_ER_INCONS, 0); + zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EOCD64_OVERLAPS_EOCD); if (free_buffer) { _zip_buffer_free(buffer); } @@ -784,7 +820,7 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse eocd_disk = eocd_disk64; } if ((flags & ZIP_CHECKCONS) && (eocd_disk != eocd_disk64 || num_disks != num_disks64)) { - zip_error_set(error, ZIP_ER_INCONS, 0); + zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EOCD64_MISMATCH); if (free_buffer) { _zip_buffer_free(buffer); } @@ -831,16 +867,16 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse } if (offset + size > buf_offset + eocd_offset) { /* cdir spans past EOCD record */ - zip_error_set(error, ZIP_ER_INCONS, 0); + zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_OVERLAPS_EOCD); return NULL; } if ((flags & ZIP_CHECKCONS) && offset + size != buf_offset + eocd_offset) { - zip_error_set(error, ZIP_ER_INCONS, 0); + zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_OVERLAPS_EOCD); return NULL; } if (nentry > size / CDENTRYSIZE) { - zip_error_set(error, ZIP_ER_INCONS, 0); + zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_INVALID); return NULL; } @@ -853,3 +889,79 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse return cd; } + + +static int decode_hex(char c) { + if (c >= '0' && c <= '9') { + return c - '0'; + } + else if (c >= 'A' && c <= 'F') { + return c - 'A' + 10; + } + else { + return -1; + } +} + +/* _zip_check_torrentzip: + check whether ZA has a valid TORRENTZIP comment, i.e. is torrentzipped */ + +static void zip_check_torrentzip(zip_t *za, const zip_cdir_t *cdir) { + zip_uint32_t crc_should; + char buf[8+1]; + size_t i; + + if (cdir == NULL) { + return; + } + + if (_zip_string_length(cdir->comment) != TORRENTZIP_SIGNATURE_LENGTH + TORRENTZIP_CRC_LENGTH + || strncmp((const char *)cdir->comment->raw, TORRENTZIP_SIGNATURE, TORRENTZIP_SIGNATURE_LENGTH) != 0) + return; + + memcpy(buf, cdir->comment->raw + TORRENTZIP_SIGNATURE_LENGTH, TORRENTZIP_CRC_LENGTH); + buf[TORRENTZIP_CRC_LENGTH] = '\0'; + crc_should = 0; + for (i = 0; i < TORRENTZIP_CRC_LENGTH; i += 2) { + int low, high; + high = decode_hex((buf[i])); + low = decode_hex(buf[i + 1]); + if (high < 0 || low < 0) { + return; + } + crc_should = (crc_should << 8) + (high << 4) + low; + } + + { + zip_stat_t st; + zip_source_t* src_window; + zip_source_t* src_crc; + zip_uint8_t buffer[512]; + zip_int64_t ret; + + zip_stat_init(&st); + st.valid |= ZIP_STAT_SIZE | ZIP_STAT_CRC; + st.size = cdir->size; + st.crc = crc_should; + if ((src_window = _zip_source_window_new(za->src, cdir->offset, cdir->size, &st, 0, NULL, NULL, 0, false, NULL)) == NULL) { + return; + } + if ((src_crc = zip_source_crc_create(src_window, 1, NULL)) == NULL) { + zip_source_free(src_window); + return; + } + if (zip_source_open(src_crc) != 0) { + zip_source_free(src_crc); + return; + } + while ((ret = zip_source_read(src_crc, buffer, sizeof(buffer))) > 0) { + } + zip_source_free(src_crc); + if (ret < 0) { + return; + } + } + + /* TODO: if check consistency, check cdir entries for valid values */ + za->flags |= ZIP_AFL_IS_TORRENTZIP; +} diff --git a/Source/Libraries/libzip/zip_pkware.c b/Libraries/libzip/Source/zip_pkware.c similarity index 98% rename from Source/Libraries/libzip/zip_pkware.c rename to Libraries/libzip/Source/zip_pkware.c index 1b1b461a0..6a8c9fcde 100644 --- a/Source/Libraries/libzip/zip_pkware.c +++ b/Libraries/libzip/Source/zip_pkware.c @@ -3,7 +3,7 @@ Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_progress.c b/Libraries/libzip/Source/zip_progress.c similarity index 99% rename from Source/Libraries/libzip/zip_progress.c rename to Libraries/libzip/Source/zip_progress.c index a881df476..e080514b1 100644 --- a/Source/Libraries/libzip/zip_progress.c +++ b/Libraries/libzip/Source/zip_progress.c @@ -3,7 +3,7 @@ Copyright (C) 2017-2020 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_rename.c b/Libraries/libzip/Source/zip_rename.c similarity index 93% rename from Source/Libraries/libzip/zip_rename.c rename to Libraries/libzip/Source/zip_rename.c index eb1b3956b..c89b06c9e 100644 --- a/Source/Libraries/libzip/zip_rename.c +++ b/Libraries/libzip/Source/zip_rename.c @@ -1,9 +1,9 @@ /* zip_rename.c -- rename file in zip archive - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_replace.c b/Libraries/libzip/Source/zip_replace.c similarity index 93% rename from Source/Libraries/libzip/zip_replace.c rename to Libraries/libzip/Source/zip_replace.c index 2140223ac..96c083c3d 100644 --- a/Source/Libraries/libzip/zip_replace.c +++ b/Libraries/libzip/Source/zip_replace.c @@ -1,9 +1,9 @@ /* zip_replace.c -- replace file via callback function - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_set_archive_comment.c b/Libraries/libzip/Source/zip_set_archive_comment.c similarity index 92% rename from Source/Libraries/libzip/zip_set_archive_comment.c rename to Libraries/libzip/Source/zip_set_archive_comment.c index ce0c5d38a..7d06688e3 100644 --- a/Source/Libraries/libzip/zip_set_archive_comment.c +++ b/Libraries/libzip/Source/zip_set_archive_comment.c @@ -1,9 +1,9 @@ /* zip_set_archive_comment.c -- set archive comment - Copyright (C) 2006-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -45,6 +45,10 @@ zip_set_archive_comment(zip_t *za, const char *comment, zip_uint16_t len) { zip_error_set(&za->error, ZIP_ER_RDONLY, 0); return -1; } + if (ZIP_WANT_TORRENTZIP(za)) { + zip_error_set(&za->error, ZIP_ER_NOT_ALLOWED, 0); + return -1; + } if (len > 0 && comment == NULL) { zip_error_set(&za->error, ZIP_ER_INVAL, 0); diff --git a/Source/Libraries/libzip/zip_set_archive_flag.c b/Libraries/libzip/Source/zip_set_archive_flag.c similarity index 78% rename from Source/Libraries/libzip/zip_set_archive_flag.c rename to Libraries/libzip/Source/zip_set_archive_flag.c index fe9f62ff0..834ef5bac 100644 --- a/Source/Libraries/libzip/zip_set_archive_flag.c +++ b/Libraries/libzip/Source/zip_set_archive_flag.c @@ -1,9 +1,9 @@ /* zip_get_archive_flag.c -- set archive global flag - Copyright (C) 2008-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2008-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -39,15 +39,26 @@ ZIP_EXTERN int zip_set_archive_flag(zip_t *za, zip_flags_t flag, int value) { unsigned int new_flags; - if (value) + if (flag == ZIP_AFL_IS_TORRENTZIP) { + zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + /* TODO: when setting ZIP_AFL_WANT_TORRENTZIP, we should error out if any changes have been made that are not allowed for torrentzip. */ + + if (value) { new_flags = za->ch_flags | flag; - else + } + else { new_flags = za->ch_flags & ~flag; + } - if (new_flags == za->ch_flags) + if (new_flags == za->ch_flags) { return 0; + } - if (ZIP_IS_RDONLY(za)) { + /* Allow removing ZIP_AFL_RDONLY if manually set, not if archive was opened read-only. */ + if (za->flags & ZIP_AFL_RDONLY) { zip_error_set(&za->error, ZIP_ER_RDONLY, 0); return -1; } diff --git a/Source/Libraries/libzip/zip_set_default_password.c b/Libraries/libzip/Source/zip_set_default_password.c similarity index 94% rename from Source/Libraries/libzip/zip_set_default_password.c rename to Libraries/libzip/Source/zip_set_default_password.c index d89394927..4bab513f4 100644 --- a/Source/Libraries/libzip/zip_set_default_password.c +++ b/Libraries/libzip/Source/zip_set_default_password.c @@ -1,9 +1,9 @@ /* zip_set_default_password.c -- set default password for decryption - Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_set_file_comment.c b/Libraries/libzip/Source/zip_set_file_comment.c similarity index 94% rename from Source/Libraries/libzip/zip_set_file_comment.c rename to Libraries/libzip/Source/zip_set_file_comment.c index d19121fa1..5d2b0b8a0 100644 --- a/Source/Libraries/libzip/zip_set_file_comment.c +++ b/Libraries/libzip/Source/zip_set_file_comment.c @@ -1,9 +1,9 @@ /* zip_set_file_comment.c -- set comment for file in archive - Copyright (C) 2006-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_set_file_compression.c b/Libraries/libzip/Source/zip_set_file_compression.c similarity index 92% rename from Source/Libraries/libzip/zip_set_file_compression.c rename to Libraries/libzip/Source/zip_set_file_compression.c index 511c7d515..a193bb77f 100644 --- a/Source/Libraries/libzip/zip_set_file_compression.c +++ b/Libraries/libzip/Source/zip_set_file_compression.c @@ -1,9 +1,9 @@ /* zip_set_file_compression.c -- set compression for file in archive - Copyright (C) 2012-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2012-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -40,7 +40,7 @@ zip_set_file_compression(zip_t *za, zip_uint64_t idx, zip_int32_t method, zip_ui zip_entry_t *e; zip_int32_t old_method; - if (idx >= za->nentry || flags > 9) { + if (idx >= za->nentry) { zip_error_set(&za->error, ZIP_ER_INVAL, 0); return -1; } @@ -49,6 +49,10 @@ zip_set_file_compression(zip_t *za, zip_uint64_t idx, zip_int32_t method, zip_ui zip_error_set(&za->error, ZIP_ER_RDONLY, 0); return -1; } + if (ZIP_WANT_TORRENTZIP(za)) { + zip_error_set(&za->error, ZIP_ER_NOT_ALLOWED, 0); + return -1; + } if (!zip_compression_method_supported(method, true)) { zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0); diff --git a/Source/Libraries/libzip/zip_set_name.c b/Libraries/libzip/Source/zip_set_name.c similarity index 97% rename from Source/Libraries/libzip/zip_set_name.c rename to Libraries/libzip/Source/zip_set_name.c index 52676857e..f1bf703e4 100644 --- a/Source/Libraries/libzip/zip_set_name.c +++ b/Libraries/libzip/Source/zip_set_name.c @@ -1,9 +1,9 @@ /* zip_set_name.c -- rename helper function - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_source_accept_empty.c b/Libraries/libzip/Source/zip_source_accept_empty.c similarity index 90% rename from Source/Libraries/libzip/zip_source_accept_empty.c rename to Libraries/libzip/Source/zip_source_accept_empty.c index 754b80b76..e772aeea9 100644 --- a/Source/Libraries/libzip/zip_source_accept_empty.c +++ b/Libraries/libzip/Source/zip_source_accept_empty.c @@ -1,9 +1,9 @@ /* zip_source_accept_empty.c -- if empty source is a valid archive - Copyright (C) 2019-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2019-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -37,7 +37,7 @@ bool zip_source_accept_empty(zip_source_t *src) { - int ret; + zip_int64_t ret; if ((zip_source_supports(src) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ACCEPT_EMPTY)) == 0) { if (ZIP_SOURCE_IS_LAYERED(src)) { @@ -46,7 +46,7 @@ zip_source_accept_empty(zip_source_t *src) { return true; } - ret = (int)_zip_source_call(src, NULL, 0, ZIP_SOURCE_ACCEPT_EMPTY); + ret = _zip_source_call(src, NULL, 0, ZIP_SOURCE_ACCEPT_EMPTY); return ret != 0; } diff --git a/Source/Libraries/libzip/zip_source_begin_write.c b/Libraries/libzip/Source/zip_source_begin_write.c similarity index 89% rename from Source/Libraries/libzip/zip_source_begin_write.c rename to Libraries/libzip/Source/zip_source_begin_write.c index 3981dc1f9..4a9d5d5d6 100644 --- a/Source/Libraries/libzip/zip_source_begin_write.c +++ b/Libraries/libzip/Source/zip_source_begin_write.c @@ -1,9 +1,9 @@ /* zip_source_begin_write.c -- start a new file for writing - Copyright (C) 2014-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -37,6 +37,11 @@ ZIP_EXTERN int zip_source_begin_write(zip_source_t *src) { + if (ZIP_SOURCE_IS_LAYERED(src)) { + zip_error_set(&src->error, ZIP_ER_OPNOTSUPP, 0); + return -1; + } + if (ZIP_SOURCE_IS_OPEN_WRITING(src)) { zip_error_set(&src->error, ZIP_ER_INVAL, 0); return -1; diff --git a/Source/Libraries/libzip/zip_source_begin_write_cloning.c b/Libraries/libzip/Source/zip_source_begin_write_cloning.c similarity index 89% rename from Source/Libraries/libzip/zip_source_begin_write_cloning.c rename to Libraries/libzip/Source/zip_source_begin_write_cloning.c index bfc63c8a6..df195fcd4 100644 --- a/Source/Libraries/libzip/zip_source_begin_write_cloning.c +++ b/Libraries/libzip/Source/zip_source_begin_write_cloning.c @@ -1,9 +1,9 @@ /* zip_source_begin_write_cloning.c -- clone part of file for writing - Copyright (C) 2017-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2017-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -37,6 +37,11 @@ ZIP_EXTERN int zip_source_begin_write_cloning(zip_source_t *src, zip_uint64_t offset) { + if (ZIP_SOURCE_IS_LAYERED(src)) { + zip_error_set(&src->error, ZIP_ER_OPNOTSUPP, 0); + return -1; + } + if (ZIP_SOURCE_IS_OPEN_WRITING(src)) { zip_error_set(&src->error, ZIP_ER_INVAL, 0); return -1; diff --git a/Source/Libraries/libzip/zip_source_buffer.c b/Libraries/libzip/Source/zip_source_buffer.c similarity index 90% rename from Source/Libraries/libzip/zip_source_buffer.c rename to Libraries/libzip/Source/zip_source_buffer.c index 1553bab4d..566729325 100644 --- a/Source/Libraries/libzip/zip_source_buffer.c +++ b/Libraries/libzip/Source/zip_source_buffer.c @@ -1,9 +1,9 @@ /* zip_source_buffer.c -- create zip data source from buffer - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -50,8 +50,8 @@ struct buffer { zip_uint64_t shared_fragments; /* number of shared fragments */ struct buffer *shared_buffer; /* buffer fragments are shared with */ - zip_uint64_t size; /* size of buffer */ + zip_uint64_t size; /* size of buffer */ zip_uint64_t offset; /* current offset in buffer */ zip_uint64_t current_fragment; /* fragment current offset is in */ }; @@ -159,7 +159,7 @@ zip_source_buffer_fragment_with_attributes_create(const zip_buffer_fragment_t *f ctx->out = NULL; ctx->mtime = time(NULL); if (attributes) { - memcpy(&ctx->attributes, attributes, sizeof(ctx->attributes)); + (void)memcpy_s(&ctx->attributes, sizeof(ctx->attributes), attributes, sizeof(ctx->attributes)); } else { zip_file_attributes_init(&ctx->attributes); @@ -226,7 +226,7 @@ read_data(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { return -1; } - memcpy(data, &ctx->attributes, sizeof(ctx->attributes)); + (void)memcpy_s(data, sizeof(ctx->attributes), &ctx->attributes, sizeof(ctx->attributes)); return sizeof(ctx->attributes); } @@ -287,7 +287,7 @@ read_data(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { } case ZIP_SOURCE_SUPPORTS: - return zip_source_make_command_bitmap(ZIP_SOURCE_GET_FILE_ATTRIBUTES, ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, ZIP_SOURCE_SEEK, ZIP_SOURCE_TELL, ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_BEGIN_WRITE_CLONING, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_REMOVE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_WRITE, -1); + return zip_source_make_command_bitmap(ZIP_SOURCE_GET_FILE_ATTRIBUTES, ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, ZIP_SOURCE_SEEK, ZIP_SOURCE_TELL, ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_BEGIN_WRITE_CLONING, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_REMOVE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_WRITE, ZIP_SOURCE_SUPPORTS_REOPEN, -1); case ZIP_SOURCE_TELL: if (ctx->in->offset > ZIP_INT64_MAX) { @@ -344,6 +344,7 @@ buffer_clone(buffer_t *buffer, zip_uint64_t offset, zip_error_t *error) { fragment_offset = buffer->fragments[fragment].length; } + /* TODO: This should also consider the length of the fully shared fragments */ waste = buffer->fragments[fragment].length - fragment_offset; if (waste > offset) { zip_error_set(error, ZIP_ER_OPNOTSUPP, 0); @@ -356,18 +357,18 @@ buffer_clone(buffer_t *buffer, zip_uint64_t offset, zip_error_t *error) { #ifndef __clang_analyzer__ /* clone->fragments can't be null, since it was created with at least one fragment */ - clone->fragments[clone->nfragments - 1].length = fragment_offset; + clone->fragments[fragment].length = fragment_offset; #endif clone->fragment_offsets[clone->nfragments] = offset; clone->size = offset; - clone->first_owned_fragment = ZIP_MIN(buffer->first_owned_fragment, clone->nfragments - 1); + clone->first_owned_fragment = ZIP_MIN(buffer->first_owned_fragment, clone->nfragments); buffer->shared_buffer = clone; clone->shared_buffer = buffer; - buffer->shared_fragments = clone->nfragments; + buffer->shared_fragments = fragment + 1; clone->shared_fragments = fragment + 1; - + return clone; } @@ -376,6 +377,10 @@ static zip_uint64_t buffer_find_fragment(const buffer_t *buffer, zip_uint64_t offset) { zip_uint64_t low, high, mid; + if (buffer->nfragments == 0) { + return 0; + } + low = 0; high = buffer->nfragments - 1; @@ -429,23 +434,20 @@ buffer_grow_fragments(buffer_t *buffer, zip_uint64_t capacity, zip_error_t *erro return true; } - // Check for 32bit overflow - uint64_t maxMemSize = SIZE_MAX; - uint64_t memFragmentSize = sizeof(buffer->fragments[0])* capacity; - if (memFragmentSize >= maxMemSize) - return false; + zip_uint64_t fragments_size = sizeof(buffer->fragments[0]) * capacity; + zip_uint64_t offsets_size = sizeof(buffer->fragment_offsets[0]) * (capacity + 1); - if ((fragments = realloc(buffer->fragments, (size_t)memFragmentSize)) == NULL) { + if (capacity == ZIP_UINT64_MAX || fragments_size < capacity || fragments_size > SIZE_MAX|| offsets_size < capacity || offsets_size > SIZE_MAX) { zip_error_set(error, ZIP_ER_MEMORY, 0); return false; } - buffer->fragments = fragments; - uint64_t newOffsetSize = sizeof(buffer->fragment_offsets[0]) * (capacity + 1); - if (newOffsetSize >= maxMemSize) + if ((fragments = realloc(buffer->fragments, (size_t)fragments_size)) == NULL) { + zip_error_set(error, ZIP_ER_MEMORY, 0); return false; - - if ((offsets = realloc(buffer->fragment_offsets, (size_t) newOffsetSize)) == NULL) { + } + buffer->fragments = fragments; + if ((offsets = realloc(buffer->fragment_offsets, (size_t)offsets_size)) == NULL) { zip_error_set(error, ZIP_ER_MEMORY, 0); return false; } @@ -504,6 +506,7 @@ buffer_new(const zip_buffer_fragment_t *fragments, zip_uint64_t nfragments, int buffer->fragments[j].data = fragments[i].data; buffer->fragments[j].length = fragments[i].length; buffer->fragment_offsets[i] = offset; + /* TODO: overflow */ offset += fragments[i].length; j++; } @@ -534,12 +537,11 @@ buffer_read(buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length) { n = 0; while (n < length) { zip_uint64_t left = ZIP_MIN(length - n, buffer->fragments[i].length - fragment_offset); +#if ZIP_UINT64_MAX > SIZE_MAX + left = ZIP_MIN(left, SIZE_MAX); +#endif - uint64_t maxMemSize = SIZE_MAX; - if (left >= maxMemSize) - return -1; - - memcpy(data + n, buffer->fragments[i].data + fragment_offset, (size_t)left); + (void)memcpy_s(data + n, (size_t)left, buffer->fragments[i].data + fragment_offset, (size_t)left); if (left == buffer->fragments[i].length - fragment_offset) { i++; @@ -570,7 +572,7 @@ buffer_seek(buffer_t *buffer, void *data, zip_uint64_t len, zip_error_t *error) static zip_int64_t buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_uint64_t length, zip_error_t *error) { - zip_uint64_t n, i, fragment_offset, capacity; + zip_uint64_t copied, i, fragment_offset, capacity; if (buffer->offset + length + WRITE_FRAGMENT_SIZE - 1 < length) { zip_error_set(error, ZIP_ER_INVAL, 0); @@ -612,27 +614,30 @@ buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_uint64_t length, zip i = buffer->current_fragment; fragment_offset = buffer->offset - buffer->fragment_offsets[i]; - n = 0; - while (n < length) { - zip_uint64_t left = ZIP_MIN(length - n, buffer->fragments[i].length - fragment_offset); + copied = 0; + while (copied < length) { + zip_uint64_t n = ZIP_MIN(ZIP_MIN(length - copied, buffer->fragments[i].length - fragment_offset), SIZE_MAX); +#if ZIP_UINT64_MAX > SIZE_MAX + n = ZIP_MIN(n, SIZE_MAX); +#endif - uint64_t maxMemSize = SIZE_MAX; - if (left >= maxMemSize) - return -1; - memcpy(buffer->fragments[i].data + fragment_offset, data + n, (size_t)left); + (void)memcpy_s(buffer->fragments[i].data + fragment_offset, (size_t)n, data + copied, (size_t)n); - if (left == buffer->fragments[i].length - fragment_offset) { + if (n == buffer->fragments[i].length - fragment_offset) { i++; + fragment_offset = 0; } - n += left; - fragment_offset = 0; + else { + fragment_offset += n; + } + copied += n; } - buffer->offset += n; + buffer->offset += copied; buffer->current_fragment = i; if (buffer->offset > buffer->size) { buffer->size = buffer->offset; } - return (zip_int64_t)n; + return (zip_int64_t)copied; } diff --git a/Source/Libraries/libzip/zip_source_call.c b/Libraries/libzip/Source/zip_source_call.c similarity index 95% rename from Source/Libraries/libzip/zip_source_call.c rename to Libraries/libzip/Source/zip_source_call.c index 66b13d6e4..8c98fc2ef 100644 --- a/Source/Libraries/libzip/zip_source_call.c +++ b/Libraries/libzip/Source/zip_source_call.c @@ -1,9 +1,9 @@ /* zip_source_call.c -- invoke callback command on zip_source - Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_source_close.c b/Libraries/libzip/Source/zip_source_close.c similarity index 94% rename from Source/Libraries/libzip/zip_source_close.c rename to Libraries/libzip/Source/zip_source_close.c index 264e4b0d3..f4f3ff2b3 100644 --- a/Source/Libraries/libzip/zip_source_close.c +++ b/Libraries/libzip/Source/zip_source_close.c @@ -1,9 +1,9 @@ /* zip_source_close.c -- close zip_source (stop reading) - Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_source_commit_write.c b/Libraries/libzip/Source/zip_source_commit_write.c similarity index 90% rename from Source/Libraries/libzip/zip_source_commit_write.c rename to Libraries/libzip/Source/zip_source_commit_write.c index ec8cd8bc3..d7f567b80 100644 --- a/Source/Libraries/libzip/zip_source_commit_write.c +++ b/Libraries/libzip/Source/zip_source_commit_write.c @@ -1,9 +1,9 @@ /* zip_source_commit_write.c -- commit changes to file - Copyright (C) 2014-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -37,6 +37,11 @@ ZIP_EXTERN int zip_source_commit_write(zip_source_t *src) { + if (ZIP_SOURCE_IS_LAYERED(src)) { + zip_error_set(&src->error, ZIP_ER_OPNOTSUPP, 0); + return -1; + } + if (!ZIP_SOURCE_IS_OPEN_WRITING(src)) { zip_error_set(&src->error, ZIP_ER_INVAL, 0); return -1; diff --git a/Source/Libraries/libzip/zip_source_compress.c b/Libraries/libzip/Source/zip_source_compress.c similarity index 92% rename from Source/Libraries/libzip/zip_source_compress.c rename to Libraries/libzip/Source/zip_source_compress.c index 78f86b6b6..3cf709ffa 100644 --- a/Source/Libraries/libzip/zip_source_compress.c +++ b/Libraries/libzip/Source/zip_source_compress.c @@ -1,9 +1,9 @@ /* zip_source_compress.c -- (de)compression routines - Copyright (C) 2017-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2017-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -83,10 +83,10 @@ static struct implementation implementations[] = { static size_t implementations_size = sizeof(implementations) / sizeof(implementations[0]); -static zip_source_t *compression_source_new(zip_t *za, zip_source_t *src, zip_int32_t method, bool compress, int compression_flags); +static zip_source_t *compression_source_new(zip_t *za, zip_source_t *src, zip_int32_t method, bool compress, zip_uint32_t compression_flags); static zip_int64_t compress_callback(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t); static void context_free(struct context *ctx); -static struct context *context_new(zip_int32_t method, bool compress, int compression_flags, zip_compression_algorithm_t *algorithm); +static struct context *context_new(zip_int32_t method, bool compress, zip_uint32_t compression_flags, zip_compression_algorithm_t *algorithm); static zip_int64_t compress_read(zip_source_t *, struct context *, void *, zip_uint64_t); zip_compression_algorithm_t * @@ -117,7 +117,7 @@ zip_compression_method_supported(zip_int32_t method, int compress) { } zip_source_t * -zip_source_compress(zip_t *za, zip_source_t *src, zip_int32_t method, int compression_flags) { +zip_source_compress(zip_t *za, zip_source_t *src, zip_int32_t method, zip_uint32_t compression_flags) { return compression_source_new(za, src, method, true, compression_flags); } @@ -128,7 +128,7 @@ zip_source_decompress(zip_t *za, zip_source_t *src, zip_int32_t method) { static zip_source_t * -compression_source_new(zip_t *za, zip_source_t *src, zip_int32_t method, bool compress, int compression_flags) { +compression_source_new(zip_t *za, zip_source_t *src, zip_int32_t method, bool compress, zip_uint32_t compression_flags) { struct context *ctx; zip_source_t *s2; zip_compression_algorithm_t *algorithm = NULL; @@ -158,7 +158,7 @@ compression_source_new(zip_t *za, zip_source_t *src, zip_int32_t method, bool co static struct context * -context_new(zip_int32_t method, bool compress, int compression_flags, zip_compression_algorithm_t *algorithm) { +context_new(zip_int32_t method, bool compress, zip_uint32_t compression_flags, zip_compression_algorithm_t *algorithm) { struct context *ctx; if ((ctx = (struct context *)malloc(sizeof(*ctx))) == NULL) { @@ -240,13 +240,7 @@ compress_read(zip_source_t *src, struct context *ctx, void *data, zip_uint64_t l if (ctx->can_store && (zip_uint64_t)ctx->first_read <= out_offset) { ctx->is_stored = true; ctx->size = (zip_uint64_t)ctx->first_read; - - // Check 32bit overflow - uint64_t maxMemSize = SIZE_MAX; - if (ctx->size >= maxMemSize) - return -1; - - memcpy(data, ctx->buffer, (size_t) ctx->size); + (void)memcpy_s(data, ctx->size, ctx->buffer, ctx->size); return (zip_int64_t)ctx->size; } end = true; @@ -263,7 +257,7 @@ compress_read(zip_source_t *src, struct context *ctx, void *data, zip_uint64_t l } if ((n = zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) { - _zip_error_set_from_source(&ctx->error, src); + zip_error_set_from_source(&ctx->error, src); end = true; break; } @@ -325,7 +319,7 @@ compress_callback(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip ctx->first_read = -1; if (zip_source_stat(src, &st) < 0 || zip_source_get_file_attributes(src, &attributes) < 0) { - _zip_error_set_from_source(&ctx->error, src); + zip_error_set_from_source(&ctx->error, src); return -1; } @@ -363,6 +357,7 @@ compress_callback(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip else { st->comp_method = ZIP_CM_STORE; st->valid |= ZIP_STAT_COMP_METHOD; + st->valid &= ~ZIP_STAT_COMP_SIZE; if (ctx->end_of_stream) { st->size = ctx->size; st->valid |= ZIP_STAT_SIZE; @@ -395,10 +390,9 @@ compress_callback(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip } case ZIP_SOURCE_SUPPORTS: - return ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_GET_FILE_ATTRIBUTES, -1); + return ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_GET_FILE_ATTRIBUTES, ZIP_SOURCE_SUPPORTS_REOPEN, -1); default: - zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0); - return -1; + return zip_source_pass_to_lower_layer(src, data, len, cmd); } } diff --git a/Source/Libraries/libzip/zip_source_crc.c b/Libraries/libzip/Source/zip_source_crc.c similarity index 80% rename from Source/Libraries/libzip/zip_source_crc.c rename to Libraries/libzip/Source/zip_source_crc.c index cae73635a..435a084b7 100644 --- a/Source/Libraries/libzip/zip_source_crc.c +++ b/Libraries/libzip/Source/zip_source_crc.c @@ -1,9 +1,9 @@ /* zip_source_crc.c -- pass-through source that calculates CRC32 and size - Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -52,16 +52,16 @@ static zip_int64_t crc_read(zip_source_t *, void *, void *, zip_uint64_t, zip_so zip_source_t * -zip_source_crc(zip_t *za, zip_source_t *src, int validate) { +zip_source_crc_create(zip_source_t *src, int validate, zip_error_t *error) { struct crc_context *ctx; if (src == NULL) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); + zip_error_set(error, ZIP_ER_INVAL, 0); return NULL; } if ((ctx = (struct crc_context *)malloc(sizeof(*ctx))) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + zip_error_set(error, ZIP_ER_MEMORY, 0); return NULL; } @@ -72,7 +72,7 @@ zip_source_crc(zip_t *za, zip_source_t *src, int validate) { ctx->crc = (zip_uint32_t)crc32(0, NULL, 0); ctx->size = 0; - return zip_source_layered(za, src, crc_read, ctx); + return zip_source_layered_create(src, crc_read, ctx, error); } @@ -90,7 +90,7 @@ crc_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source case ZIP_SOURCE_READ: if ((n = zip_source_read(src, data, len)) < 0) { - _zip_error_set_from_source(&ctx->error, src); + zip_error_set_from_source(&ctx->error, src); return -1; } @@ -103,7 +103,7 @@ crc_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source struct zip_stat st; if (zip_source_stat(src, &st) < 0) { - _zip_error_set_from_source(&ctx->error, src); + zip_error_set_from_source(&ctx->error, src); return -1; } @@ -112,7 +112,8 @@ crc_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source return -1; } if ((st.valid & ZIP_STAT_SIZE) && st.size != ctx->size) { - zip_error_set(&ctx->error, ZIP_ER_INCONS, 0); + /* We don't have the index here, but the caller should know which file they are reading from. */ + zip_error_set(&ctx->error, ZIP_ER_INCONS, MAKE_DETAIL_WITH_INDEX(ZIP_ER_DETAIL_INVALID_FILE_LENGTH, MAX_DETAIL_INDEX)); return -1; } } @@ -140,6 +141,10 @@ crc_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source st = (zip_stat_t *)data; if (ctx->crc_complete) { + if ((st->valid & ZIP_STAT_SIZE) && st->size != ctx->size) { + zip_error_set(&ctx->error, ZIP_ER_DATA_LENGTH, 0); + return -1; + } /* TODO: Set comp_size, comp_method, encryption_method? After all, this only works for uncompressed data. */ st->size = ctx->size; @@ -163,11 +168,13 @@ crc_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source zip_int64_t mask = zip_source_supports(src); if (mask < 0) { - _zip_error_set_from_source(&ctx->error, src); + zip_error_set_from_source(&ctx->error, src); return -1; } - return mask & ~zip_source_make_command_bitmap(ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_REMOVE, ZIP_SOURCE_GET_FILE_ATTRIBUTES, -1); + mask &= ~zip_source_make_command_bitmap(ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_REMOVE, ZIP_SOURCE_GET_FILE_ATTRIBUTES, -1); + mask |= zip_source_make_command_bitmap(ZIP_SOURCE_FREE, -1); + return mask; } case ZIP_SOURCE_SEEK: { @@ -178,7 +185,7 @@ crc_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source return -1; } if (zip_source_seek(src, args->offset, args->whence) < 0 || (new_position = zip_source_tell(src)) < 0) { - _zip_error_set_from_source(&ctx->error, src); + zip_error_set_from_source(&ctx->error, src); return -1; } @@ -191,7 +198,6 @@ crc_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source return (zip_int64_t)ctx->position; default: - zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0); - return -1; + return zip_source_pass_to_lower_layer(src, data, len, cmd); } } diff --git a/Source/Libraries/libzip/zip_source_error.c b/Libraries/libzip/Source/zip_source_error.c similarity index 93% rename from Source/Libraries/libzip/zip_source_error.c rename to Libraries/libzip/Source/zip_source_error.c index 00998e839..dc7fa20cb 100644 --- a/Source/Libraries/libzip/zip_source_error.c +++ b/Libraries/libzip/Source/zip_source_error.c @@ -1,9 +1,9 @@ /* zip_source_error.c -- get last error from zip_source - Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_source_file_common.c b/Libraries/libzip/Source/zip_source_file_common.c similarity index 91% rename from Source/Libraries/libzip/zip_source_file_common.c rename to Libraries/libzip/Source/zip_source_file_common.c index 32414361b..6c58320f1 100644 --- a/Source/Libraries/libzip/zip_source_file_common.c +++ b/Libraries/libzip/Source/zip_source_file_common.c @@ -1,9 +1,9 @@ /* zip_source_file_common.c -- create data source from file - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -54,6 +54,7 @@ zip_source_file_common_new(const char *fname, void *file, zip_uint64_t start, zi zip_source_file_context_t *ctx; zip_source_t *zs; zip_source_file_stat_t sb; + zip_uint64_t length; if (ops == NULL) { zip_error_set(error, ZIP_ER_INVAL, 0); @@ -82,10 +83,17 @@ zip_source_file_common_new(const char *fname, void *file, zip_uint64_t start, zi } if (len < 0) { - len = 0; + if (len == -1) { + len = ZIP_LENGTH_TO_END; + } + // TODO: return ZIP_ER_INVAL if len != ZIP_LENGTH_UNCHECKED? + length = 0; + } + else { + length = (zip_uint64_t)len; } - if (start > ZIP_INT64_MAX || start + (zip_uint64_t)len < start) { + if (start > ZIP_INT64_MAX || start + length < start) { zip_error_set(error, ZIP_ER_INVAL, 0); return NULL; } @@ -107,9 +115,9 @@ zip_source_file_common_new(const char *fname, void *file, zip_uint64_t start, zi } ctx->f = file; ctx->start = start; - ctx->len = (zip_uint64_t)len; + ctx->len = length; if (st) { - memcpy(&ctx->st, st, sizeof(ctx->st)); + (void)memcpy_s(&ctx->st, sizeof(ctx->st), st, sizeof(*st)); ctx->st.name = NULL; ctx->st.valid &= ~ZIP_STAT_NAME; } @@ -130,7 +138,7 @@ zip_source_file_common_new(const char *fname, void *file, zip_uint64_t start, zi zip_error_init(&ctx->error); zip_file_attributes_init(&ctx->attributes); - ctx->supports = ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1); + ctx->supports = ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, ZIP_SOURCE_SUPPORTS_REOPEN, -1); zip_source_file_stat_init(&sb); if (!ops->stat(ctx, &sb)) { @@ -169,9 +177,11 @@ zip_source_file_common_new(const char *fname, void *file, zip_uint64_t start, zi } if (ctx->len == 0) { - ctx->len = sb.size - ctx->start; - ctx->st.size = ctx->len; - ctx->st.valid |= ZIP_STAT_SIZE; + if (len != ZIP_LENGTH_UNCHECKED) { + ctx->len = sb.size - ctx->start; + ctx->st.size = ctx->len; + ctx->st.valid |= ZIP_STAT_SIZE; + } /* when using a partial file, don't allow writing */ if (ctx->fname && start == 0 && ops->write != NULL) { @@ -262,7 +272,7 @@ read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); return -1; } - memcpy(data, &ctx->attributes, sizeof(ctx->attributes)); + (void)memcpy_s(data, sizeof(ctx->attributes), &ctx->attributes, sizeof(ctx->attributes)); return sizeof(ctx->attributes); case ZIP_SOURCE_OPEN: @@ -272,7 +282,7 @@ read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { } } - if (ctx->start > 0) { // TODO: rewind on re-open + if (ctx->start > 0) { /* TODO: rewind on re-open */ if (ctx->ops->seek(ctx, ctx->f, (zip_int64_t)ctx->start, SEEK_SET) == false) { /* TODO: skip by reading */ return -1; @@ -355,7 +365,7 @@ read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { return -1; } - memcpy(data, &ctx->st, sizeof(ctx->st)); + (void)memcpy_s(data, sizeof(ctx->st), &ctx->st, sizeof(ctx->st)); return sizeof(ctx->st); } diff --git a/Source/Libraries/libzip/zip_source_file_stdio.c b/Libraries/libzip/Source/zip_source_file_stdio.c similarity index 87% rename from Source/Libraries/libzip/zip_source_file_stdio.c rename to Libraries/libzip/Source/zip_source_file_stdio.c index 15817716c..6dcc56399 100644 --- a/Source/Libraries/libzip/zip_source_file_stdio.c +++ b/Libraries/libzip/Source/zip_source_file_stdio.c @@ -3,7 +3,7 @@ Copyright (C) 2020 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -78,7 +78,7 @@ zip_source_filep(zip_t *za, FILE *file, zip_uint64_t start, zip_int64_t len) { ZIP_EXTERN zip_source_t * zip_source_filep_create(FILE *file, zip_uint64_t start, zip_int64_t length, zip_error_t *error) { - if (file == NULL || length < -1) { + if (file == NULL || length < ZIP_LENGTH_UNCHECKED) { zip_error_set(error, ZIP_ER_INVAL, 0); return NULL; } @@ -176,33 +176,3 @@ _zip_stdio_op_tell(zip_source_file_context_t *ctx, void *f) { return offset; } - - -/* - * fopen replacement that sets the close-on-exec flag - * some implementations support an fopen 'e' flag for that, - * but e.g. macOS doesn't. - */ -FILE * -_zip_fopen_close_on_exec(const char *name, bool writeable) { - int fd; - int flags; - FILE *fp; - - flags = O_CLOEXEC; - if (writeable) { - flags |= O_RDWR; - } - else { - flags |= O_RDONLY; - } - - /* mode argument needed on Windows */ - if ((fd = open(name, flags, 0666)) < 0) { - return NULL; - } - if ((fp = fdopen(fd, writeable ? "r+b" : "rb")) == NULL) { - return NULL; - } - return fp; -} diff --git a/Source/Libraries/libzip/zip_source_free.c b/Libraries/libzip/Source/zip_source_free.c similarity index 95% rename from Source/Libraries/libzip/zip_source_free.c rename to Libraries/libzip/Source/zip_source_free.c index 26504931e..1a800405c 100644 --- a/Source/Libraries/libzip/zip_source_free.c +++ b/Libraries/libzip/Source/zip_source_free.c @@ -1,9 +1,9 @@ /* zip_source_free.c -- free zip data source - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_source_function.c b/Libraries/libzip/Source/zip_source_function.c similarity index 93% rename from Source/Libraries/libzip/zip_source_function.c rename to Libraries/libzip/Source/zip_source_function.c index 5602f1d19..1fe6396e1 100644 --- a/Source/Libraries/libzip/zip_source_function.c +++ b/Libraries/libzip/Source/zip_source_function.c @@ -1,9 +1,9 @@ /* zip_source_function.c -- create zip data source from callback function - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -61,6 +61,7 @@ zip_source_function_create(zip_source_callback zcb, void *ud, zip_error_t *error if (zs->supports < 0) { zs->supports = ZIP_SOURCE_SUPPORTS_READABLE; } + zs->supports |= zip_source_make_command_bitmap(ZIP_SOURCE_SUPPORTS, -1); return zs; } diff --git a/Source/Libraries/libzip/zip_source_get_file_attributes.c b/Libraries/libzip/Source/zip_source_get_file_attributes.c similarity index 96% rename from Source/Libraries/libzip/zip_source_get_file_attributes.c rename to Libraries/libzip/Source/zip_source_get_file_attributes.c index 734767a0e..4771dc16b 100644 --- a/Source/Libraries/libzip/zip_source_get_file_attributes.c +++ b/Libraries/libzip/Source/zip_source_get_file_attributes.c @@ -3,7 +3,7 @@ Copyright (C) 2020 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -60,8 +60,10 @@ zip_source_get_file_attributes(zip_source_t *src, zip_file_attributes_t *attribu if (ZIP_SOURCE_IS_LAYERED(src)) { zip_file_attributes_t lower_attributes; + zip_file_attributes_init(&lower_attributes); + if (zip_source_get_file_attributes(src->src, &lower_attributes) < 0) { - _zip_error_set_from_source(&src->error, src->src); + zip_error_set_from_source(&src->error, src->src); return -1; } diff --git a/Source/Libraries/libzip/zip_source_is_deleted.c b/Libraries/libzip/Source/zip_source_is_deleted.c similarity index 93% rename from Source/Libraries/libzip/zip_source_is_deleted.c rename to Libraries/libzip/Source/zip_source_is_deleted.c index 27c931fd4..838aa9096 100644 --- a/Source/Libraries/libzip/zip_source_is_deleted.c +++ b/Libraries/libzip/Source/zip_source_is_deleted.c @@ -1,9 +1,9 @@ /* zip_source_is_deleted.c -- was archive was removed? - Copyright (C) 2014-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_source_layered.c b/Libraries/libzip/Source/zip_source_layered.c similarity index 70% rename from Source/Libraries/libzip/zip_source_layered.c rename to Libraries/libzip/Source/zip_source_layered.c index a02986929..62b78e68e 100644 --- a/Source/Libraries/libzip/zip_source_layered.c +++ b/Libraries/libzip/Source/zip_source_layered.c @@ -1,9 +1,9 @@ /* zip_source_layered.c -- create layered source - Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -49,19 +49,27 @@ zip_source_layered(zip_t *za, zip_source_t *src, zip_source_layered_callback cb, zip_source_t * zip_source_layered_create(zip_source_t *src, zip_source_layered_callback cb, void *ud, zip_error_t *error) { zip_source_t *zs; + zip_int64_t lower_supports, supports; - if ((zs = _zip_source_new(error)) == NULL) + lower_supports = zip_source_supports(src); + supports = cb(src, ud, &lower_supports, sizeof(lower_supports), ZIP_SOURCE_SUPPORTS); + if (supports < 0) { + zip_error_set(error,ZIP_ER_INVAL, 0); /* Initialize in case cb doesn't return valid error. */ + cb(src, ud, error, sizeof(*error), ZIP_SOURCE_ERROR); return NULL; + } + + if ((zs = _zip_source_new(error)) == NULL) { + return NULL; + } - zip_source_keep(src); zs->src = src; zs->cb.l = cb; zs->ud = ud; + zs->supports = supports; - zs->supports = cb(src, ud, NULL, 0, ZIP_SOURCE_SUPPORTS); - if (zs->supports < 0) { - zs->supports = ZIP_SOURCE_SUPPORTS_READABLE; - } + /* Layered sources can't support writing, since we currently have no use case. If we want to revisit this, we have to define how the two sources interact. */ + zs->supports &= ~(ZIP_SOURCE_SUPPORTS_WRITABLE & ~ZIP_SOURCE_SUPPORTS_SEEKABLE); return zs; } diff --git a/Source/Libraries/libzip/zip_source_open.c b/Libraries/libzip/Source/zip_source_open.c similarity index 93% rename from Source/Libraries/libzip/zip_source_open.c rename to Libraries/libzip/Source/zip_source_open.c index 442f1894f..b34fa2c6c 100644 --- a/Source/Libraries/libzip/zip_source_open.c +++ b/Libraries/libzip/Source/zip_source_open.c @@ -1,9 +1,9 @@ /* zip_source_open.c -- open zip_source (prepare for reading) - Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -53,7 +53,7 @@ zip_source_open(zip_source_t *src) { else { if (ZIP_SOURCE_IS_LAYERED(src)) { if (zip_source_open(src->src) < 0) { - _zip_error_set_from_source(&src->error, src->src); + zip_error_set_from_source(&src->error, src->src); return -1; } } diff --git a/Source/Libraries/libzip/Unix/zip_mkstempm.c b/Libraries/libzip/Source/zip_source_pass_to_lower_layer.c similarity index 53% rename from Source/Libraries/libzip/Unix/zip_mkstempm.c rename to Libraries/libzip/Source/zip_source_pass_to_lower_layer.c index 41516d2ff..4a98222ec 100644 --- a/Source/Libraries/libzip/Unix/zip_mkstempm.c +++ b/Libraries/libzip/Source/zip_source_pass_to_lower_layer.c @@ -1,9 +1,9 @@ /* - zip_mkstempm.c -- mkstemp replacement that accepts a mode argument - Copyright (C) 2019-2020 Dieter Baron and Thomas Klausner + zip_source_pass_to_lower_layer.c -- pass command to lower layer + Copyright (C) 2022 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -31,63 +31,48 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#include -#include - #include "zipint.h" -/* - * create temporary file with same permissions as previous one; - * or default permissions if there is no previous file - */ -int -_zip_mkstempm(char *path, int mode) { - int fd; - char *start, *end, *xs; - - int xcnt = 0; +zip_int64_t zip_source_pass_to_lower_layer(zip_source_t *src, void *data, zip_uint64_t length, zip_source_cmd_t command) { + switch (command) { + case ZIP_SOURCE_OPEN: + case ZIP_SOURCE_CLOSE: + case ZIP_SOURCE_FREE: + case ZIP_SOURCE_GET_FILE_ATTRIBUTES: + case ZIP_SOURCE_SUPPORTS_REOPEN: + return 0; - end = path + strlen(path); - start = end - 1; - while (start >= path && *start == 'X') { - xcnt++; - start--; - } - - if (xcnt == 0) { - errno = EINVAL; - return -1; - } + case ZIP_SOURCE_STAT: + return sizeof(zip_stat_t); - start++; + case ZIP_SOURCE_ACCEPT_EMPTY: + case ZIP_SOURCE_ERROR: + case ZIP_SOURCE_READ: + case ZIP_SOURCE_SEEK: + case ZIP_SOURCE_TELL: + return _zip_source_call(src, data, length, command); - for (;;) { - zip_uint32_t value = zip_random_uint32(); - xs = start; - - while (xs < end) { - char digit = value % 36; - if (digit < 10) { - *(xs++) = digit + '0'; - } - else { - *(xs++) = digit - 10 + 'a'; - } - value /= 36; - } + case ZIP_SOURCE_BEGIN_WRITE: + case ZIP_SOURCE_BEGIN_WRITE_CLONING: + case ZIP_SOURCE_COMMIT_WRITE: + case ZIP_SOURCE_REMOVE: + case ZIP_SOURCE_ROLLBACK_WRITE: + case ZIP_SOURCE_SEEK_WRITE: + case ZIP_SOURCE_TELL_WRITE: + case ZIP_SOURCE_WRITE: + zip_error_set(&src->error, ZIP_ER_OPNOTSUPP, 0); + return -1; - if ((fd = open(path, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC, mode == -1 ? 0666 : (mode_t)mode)) >= 0) { - if (mode != -1) { - /* open() honors umask(), which we don't want in this case */ - (void)chmod(path, (mode_t)mode); - } - return fd; - } - if (errno != EEXIST) { + case ZIP_SOURCE_SUPPORTS: + if (length < sizeof(zip_int64_t)) { + zip_error_set(&src->error, ZIP_ER_INTERNAL, 0); return -1; } + return *(zip_int64_t *)data; + + default: + zip_error_set(&src->error, ZIP_ER_OPNOTSUPP, 0); + return -1; } -} +} \ No newline at end of file diff --git a/Source/Libraries/libzip/zip_source_pkware_decode.c b/Libraries/libzip/Source/zip_source_pkware_decode.c similarity index 95% rename from Source/Libraries/libzip/zip_source_pkware_decode.c rename to Libraries/libzip/Source/zip_source_pkware_decode.c index a1c9e3a9b..b4c482b31 100644 --- a/Source/Libraries/libzip/zip_source_pkware_decode.c +++ b/Libraries/libzip/Source/zip_source_pkware_decode.c @@ -3,7 +3,7 @@ Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -85,7 +85,7 @@ decrypt_header(zip_source_t *src, struct trad_pkware *ctx) { bool ok = false; if ((n = zip_source_read(src, header, ZIP_CRYPTO_PKWARE_HEADERLEN)) < 0) { - _zip_error_set_from_source(&ctx->error, src); + zip_error_set_from_source(&ctx->error, src); return -1; } @@ -147,7 +147,7 @@ pkware_decrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_so case ZIP_SOURCE_READ: if ((n = zip_source_read(src, data, len)) < 0) { - _zip_error_set_from_source(&ctx->error, src); + zip_error_set_from_source(&ctx->error, src); return -1; } @@ -172,7 +172,7 @@ pkware_decrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_so } case ZIP_SOURCE_SUPPORTS: - return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, -1); + return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, ZIP_SOURCE_SUPPORTS_REOPEN, -1); case ZIP_SOURCE_ERROR: return zip_error_to_data(&ctx->error, data, len); @@ -182,8 +182,7 @@ pkware_decrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_so return 0; default: - zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); - return -1; + return zip_source_pass_to_lower_layer(src, data, len, cmd); } } diff --git a/Source/Libraries/libzip/zip_source_pkware_encode.c b/Libraries/libzip/Source/zip_source_pkware_encode.c similarity index 86% rename from Source/Libraries/libzip/zip_source_pkware_encode.c rename to Libraries/libzip/Source/zip_source_pkware_encode.c index 941e64f93..d89b9f4e8 100644 --- a/Source/Libraries/libzip/zip_source_pkware_encode.c +++ b/Libraries/libzip/Source/zip_source_pkware_encode.c @@ -3,7 +3,7 @@ Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -42,6 +42,8 @@ struct trad_pkware { zip_pkware_keys_t keys; zip_buffer_t *buffer; bool eof; + bool mtime_set; + time_t mtime; zip_error_t error; }; @@ -50,7 +52,7 @@ static int encrypt_header(zip_source_t *, struct trad_pkware *); static zip_int64_t pkware_encrypt(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t); static void trad_pkware_free(struct trad_pkware *); static struct trad_pkware *trad_pkware_new(const char *password, zip_error_t *error); - +static void set_mtime(struct trad_pkware* ctx, zip_stat_t* st); zip_source_t * zip_source_pkware_encode(zip_t *za, zip_source_t *src, zip_uint16_t em, int flags, const char *password) { @@ -81,16 +83,19 @@ zip_source_pkware_encode(zip_t *za, zip_source_t *src, zip_uint16_t em, int flag static int encrypt_header(zip_source_t *src, struct trad_pkware *ctx) { - struct zip_stat st; unsigned short dostime, dosdate; zip_uint8_t *header; - if (zip_source_stat(src, &st) != 0) { - _zip_error_set_from_source(&ctx->error, src); - return -1; + if (!ctx->mtime_set) { + struct zip_stat st; + if (zip_source_stat(src, &st) != 0) { + zip_error_set_from_source(&ctx->error, src); + return -1; + } + set_mtime(ctx, &st); } - _zip_u2d_time(st.mtime, &dostime, &dosdate); + _zip_u2d_time(ctx->mtime, &dostime, &dosdate); if ((ctx->buffer = _zip_buffer_new(NULL, ZIP_CRYPTO_PKWARE_HEADERLEN)) == NULL) { zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0); @@ -101,8 +106,7 @@ encrypt_header(zip_source_t *src, struct trad_pkware *ctx) { /* generate header from random bytes and mtime see appnote.iz, XIII. Decryption, Step 2, last paragraph */ - // if (!zip_secure_random(header, ZIP_CRYPTO_PKWARE_HEADERLEN - 1)) { - if (0==0) { + if (!zip_secure_random(header, ZIP_CRYPTO_PKWARE_HEADERLEN - 1)) { zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0); _zip_buffer_free(ctx->buffer); ctx->buffer = NULL; @@ -157,7 +161,7 @@ pkware_encrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t length, zip } if ((n = zip_source_read(src, data, length)) < 0) { - _zip_error_set_from_source(&ctx->error, src); + zip_error_set_from_source(&ctx->error, src); return -1; } @@ -183,6 +187,9 @@ pkware_encrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t length, zip if (st->valid & ZIP_STAT_COMP_SIZE) { st->comp_size += ZIP_CRYPTO_PKWARE_HEADERLEN; } + set_mtime(ctx, st); + st->mtime = ctx->mtime; + st->valid |= ZIP_STAT_MTIME; return 0; } @@ -210,8 +217,7 @@ pkware_encrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t length, zip return 0; default: - zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); - return -1; + return zip_source_pass_to_lower_layer(src, data, length, cmd); } } @@ -231,6 +237,8 @@ trad_pkware_new(const char *password, zip_error_t *error) { return NULL; } ctx->buffer = NULL; + ctx->mtime_set = false; + ctx->mtime = 0; zip_error_init(&ctx->error); return ctx; @@ -248,3 +256,16 @@ trad_pkware_free(struct trad_pkware *ctx) { zip_error_fini(&ctx->error); free(ctx); } + + +static void set_mtime(struct trad_pkware* ctx, zip_stat_t* st) { + if (!ctx->mtime_set) { + if (st->valid & ZIP_STAT_MTIME) { + ctx->mtime = st->mtime; + } + else { + time(&ctx->mtime); + } + ctx->mtime_set = true; + } +} diff --git a/Source/Libraries/libzip/zip_source_read.c b/Libraries/libzip/Source/zip_source_read.c similarity index 96% rename from Source/Libraries/libzip/zip_source_read.c rename to Libraries/libzip/Source/zip_source_read.c index f146ab065..0938fcb08 100644 --- a/Source/Libraries/libzip/zip_source_read.c +++ b/Libraries/libzip/Source/zip_source_read.c @@ -1,9 +1,9 @@ /* zip_source_read.c -- read data from zip_source - Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_source_remove.c b/Libraries/libzip/Source/zip_source_remove.c similarity index 89% rename from Source/Libraries/libzip/zip_source_remove.c rename to Libraries/libzip/Source/zip_source_remove.c index a6ccd7eda..c1d73ab92 100644 --- a/Source/Libraries/libzip/zip_source_remove.c +++ b/Libraries/libzip/Source/zip_source_remove.c @@ -1,9 +1,9 @@ /* zip_source_remove.c -- remove empty archive - Copyright (C) 2014-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -37,6 +37,11 @@ int zip_source_remove(zip_source_t *src) { + if (ZIP_SOURCE_IS_LAYERED(src)) { + zip_error_set(&src->error, ZIP_ER_OPNOTSUPP, 0); + return -1; + } + if (src->write_state == ZIP_SOURCE_WRITE_REMOVED) { return 0; } diff --git a/Source/Libraries/libzip/zip_source_rollback_write.c b/Libraries/libzip/Source/zip_source_rollback_write.c similarity index 91% rename from Source/Libraries/libzip/zip_source_rollback_write.c rename to Libraries/libzip/Source/zip_source_rollback_write.c index d21b1ffe2..ea1a15107 100644 --- a/Source/Libraries/libzip/zip_source_rollback_write.c +++ b/Libraries/libzip/Source/zip_source_rollback_write.c @@ -1,9 +1,9 @@ /* zip_source_rollback_write.c -- discard changes - Copyright (C) 2014-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -37,6 +37,10 @@ ZIP_EXTERN void zip_source_rollback_write(zip_source_t *src) { + if (ZIP_SOURCE_IS_LAYERED(src)) { + return; + } + if (src->write_state != ZIP_SOURCE_WRITE_OPEN && src->write_state != ZIP_SOURCE_WRITE_FAILED) { return; } diff --git a/Source/Libraries/libzip/zip_source_seek.c b/Libraries/libzip/Source/zip_source_seek.c similarity index 96% rename from Source/Libraries/libzip/zip_source_seek.c rename to Libraries/libzip/Source/zip_source_seek.c index 29d1e968e..e3baad5ab 100644 --- a/Source/Libraries/libzip/zip_source_seek.c +++ b/Libraries/libzip/Source/zip_source_seek.c @@ -1,9 +1,9 @@ /* zip_source_seek.c -- seek to offset - Copyright (C) 2014-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_source_seek_write.c b/Libraries/libzip/Source/zip_source_seek_write.c similarity index 89% rename from Source/Libraries/libzip/zip_source_seek_write.c rename to Libraries/libzip/Source/zip_source_seek_write.c index 5fa2a8129..34ae2f5af 100644 --- a/Source/Libraries/libzip/zip_source_seek_write.c +++ b/Libraries/libzip/Source/zip_source_seek_write.c @@ -1,9 +1,9 @@ /* zip_source_seek_write.c -- seek to offset for writing - Copyright (C) 2014-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -39,6 +39,11 @@ ZIP_EXTERN int zip_source_seek_write(zip_source_t *src, zip_int64_t offset, int whence) { zip_source_args_seek_t args; + if (ZIP_SOURCE_IS_LAYERED(src)) { + zip_error_set(&src->error, ZIP_ER_OPNOTSUPP, 0); + return -1; + } + if (!ZIP_SOURCE_IS_OPEN_WRITING(src) || (whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END)) { zip_error_set(&src->error, ZIP_ER_INVAL, 0); return -1; diff --git a/Source/Libraries/libzip/zip_source_stat.c b/Libraries/libzip/Source/zip_source_stat.c similarity index 87% rename from Source/Libraries/libzip/zip_source_stat.c rename to Libraries/libzip/Source/zip_source_stat.c index 46eb92db5..05dcb84d7 100644 --- a/Source/Libraries/libzip/zip_source_stat.c +++ b/Libraries/libzip/Source/zip_source_stat.c @@ -1,9 +1,9 @@ /* zip_source_stat.c -- get meta information from zip_source - Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -45,11 +45,15 @@ zip_source_stat(zip_source_t *src, zip_stat_t *st) { return -1; } + if (src->write_state == ZIP_SOURCE_WRITE_REMOVED) { + zip_error_set(&src->error, ZIP_ER_READ, ENOENT); + } + zip_stat_init(st); if (ZIP_SOURCE_IS_LAYERED(src)) { if (zip_source_stat(src->src, st) < 0) { - _zip_error_set_from_source(&src->error, src->src); + zip_error_set_from_source(&src->error, src->src); return -1; } } diff --git a/Source/Libraries/libzip/zip_source_supports.c b/Libraries/libzip/Source/zip_source_supports.c similarity index 83% rename from Source/Libraries/libzip/zip_source_supports.c rename to Libraries/libzip/Source/zip_source_supports.c index b4575a74b..8fea2ae91 100644 --- a/Source/Libraries/libzip/zip_source_supports.c +++ b/Libraries/libzip/Source/zip_source_supports.c @@ -1,9 +1,9 @@ /* zip_source_supports.c -- check for supported functions - Copyright (C) 2014-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -42,6 +42,10 @@ zip_source_supports(zip_source_t *src) { return src->supports; } +bool +zip_source_supports_reopen(zip_source_t *src) { + return (zip_source_supports(src) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SUPPORTS_REOPEN)) != 0; +} ZIP_EXTERN zip_int64_t zip_source_make_command_bitmap(zip_source_cmd_t cmd0, ...) { @@ -63,3 +67,8 @@ zip_source_make_command_bitmap(zip_source_cmd_t cmd0, ...) { return bitmap; } + + +ZIP_EXTERN int zip_source_is_seekable(zip_source_t *src) { + return ZIP_SOURCE_CHECK_SUPPORTED(zip_source_supports(src->src), ZIP_SOURCE_SEEK); +} diff --git a/Source/Libraries/libzip/zip_source_tell.c b/Libraries/libzip/Source/zip_source_tell.c similarity index 95% rename from Source/Libraries/libzip/zip_source_tell.c rename to Libraries/libzip/Source/zip_source_tell.c index b17412be7..49057ce56 100644 --- a/Source/Libraries/libzip/zip_source_tell.c +++ b/Libraries/libzip/Source/zip_source_tell.c @@ -1,9 +1,9 @@ /* zip_source_tell.c -- report current offset - Copyright (C) 2014-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_source_tell_write.c b/Libraries/libzip/Source/zip_source_tell_write.c similarity index 88% rename from Source/Libraries/libzip/zip_source_tell_write.c rename to Libraries/libzip/Source/zip_source_tell_write.c index c09a79fcb..a5b0e5311 100644 --- a/Source/Libraries/libzip/zip_source_tell_write.c +++ b/Libraries/libzip/Source/zip_source_tell_write.c @@ -1,9 +1,9 @@ /* zip_source_tell_write.c -- report current offset for writing - Copyright (C) 2014-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -37,6 +37,11 @@ ZIP_EXTERN zip_int64_t zip_source_tell_write(zip_source_t *src) { + if (ZIP_SOURCE_IS_LAYERED(src)) { + zip_error_set(&src->error, ZIP_ER_OPNOTSUPP, 0); + return -1; + } + if (!ZIP_SOURCE_IS_OPEN_WRITING(src)) { zip_error_set(&src->error, ZIP_ER_INVAL, 0); return -1; diff --git a/Source/Libraries/libzip/zip_source_window.c b/Libraries/libzip/Source/zip_source_window.c similarity index 66% rename from Source/Libraries/libzip/zip_source_window.c rename to Libraries/libzip/Source/zip_source_window.c index b63ba1df4..524e27c83 100644 --- a/Source/Libraries/libzip/zip_source_window.c +++ b/Libraries/libzip/Source/zip_source_window.c @@ -1,9 +1,9 @@ /* zip_source_window.c -- return part of lower source - Copyright (C) 2012-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2012-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -40,6 +40,7 @@ struct window { zip_uint64_t start; /* where in file we start reading */ zip_uint64_t end; /* where in file we stop reading */ + bool end_valid; /* whether end is set, otherwise read until EOF */ /* if not NULL, read file data for this file */ zip_t *source_archive; @@ -48,6 +49,7 @@ struct window { zip_uint64_t offset; /* offset in src for next read */ zip_stat_t stat; + zip_uint64_t stat_invalid; zip_file_attributes_t attributes; zip_error_t error; zip_int64_t supports; @@ -57,20 +59,28 @@ struct window { static zip_int64_t window_read(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t); -zip_source_t * -zip_source_window(zip_t *za, zip_source_t *src, zip_uint64_t start, zip_uint64_t len) { - return _zip_source_window_new(src, start, len, NULL, 0, NULL, 0, &za->error); +ZIP_EXTERN zip_source_t * +zip_source_window_create(zip_source_t *src, zip_uint64_t start, zip_int64_t len, zip_error_t *error) { + return _zip_source_window_new(src, start, len, NULL, 0, NULL, NULL, 0, false, error); } zip_source_t * -_zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_uint64_t length, zip_stat_t *st, zip_file_attributes_t *attributes, zip_t *source_archive, zip_uint64_t source_index, zip_error_t *error) { +_zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_int64_t length, zip_stat_t *st, zip_uint64_t st_invalid, zip_file_attributes_t *attributes, zip_t *source_archive, zip_uint64_t source_index, bool take_ownership, zip_error_t *error) { + zip_source_t* window_source; struct window *ctx; - if (src == NULL || start + length < start || (source_archive == NULL && source_index != 0)) { + if (src == NULL || length < -1 || (source_archive == NULL && source_index != 0)) { zip_error_set(error, ZIP_ER_INVAL, 0); return NULL; } + + if (length >= 0) { + if (start + (zip_uint64_t)length < start) { + zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + } if ((ctx = (struct window *)malloc(sizeof(*ctx))) == NULL) { zip_error_set(error, ZIP_ER_MEMORY, 0); @@ -78,10 +88,17 @@ _zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_uint64_t lengt } ctx->start = start; - ctx->end = start + length; + if (length == -1) { + ctx->end_valid = false; + } + else { + ctx->end = start + (zip_uint64_t)length; + ctx->end_valid = true; + } zip_stat_init(&ctx->stat); + ctx->stat_invalid = st_invalid; if (attributes != NULL) { - memcpy(&ctx->attributes, attributes, sizeof(ctx->attributes)); + (void)memcpy_s(&ctx->attributes, sizeof(ctx->attributes), attributes, sizeof(ctx->attributes)); } else { zip_file_attributes_init(&ctx->attributes); @@ -89,7 +106,7 @@ _zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_uint64_t lengt ctx->source_archive = source_archive; ctx->source_index = source_index; zip_error_init(&ctx->error); - ctx->supports = (zip_source_supports(src) & ZIP_SOURCE_SUPPORTS_SEEKABLE) | (zip_source_make_command_bitmap(ZIP_SOURCE_GET_FILE_ATTRIBUTES, ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1)); + ctx->supports = (zip_source_supports(src) & (ZIP_SOURCE_SUPPORTS_SEEKABLE | ZIP_SOURCE_SUPPORTS_REOPEN)) | (zip_source_make_command_bitmap(ZIP_SOURCE_GET_FILE_ATTRIBUTES, ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, ZIP_SOURCE_FREE, -1)); ctx->needs_seek = (ctx->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK)) ? true : false; if (st) { @@ -98,8 +115,12 @@ _zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_uint64_t lengt return NULL; } } - - return zip_source_layered_create(src, window_read, ctx, error); + + window_source = zip_source_layered_create(src, window_read, ctx, error); + if (window_source != NULL && !take_ownership) { + zip_source_keep(src); + } + return window_source; } @@ -149,7 +170,7 @@ window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_sou } if (ctx->end + offset < ctx->end) { /* zip archive data claims end of data past zip64 limits */ - zip_error_set(&ctx->error, ZIP_ER_INCONS, 0); + zip_error_set(&ctx->error, ZIP_ER_INCONS, MAKE_DETAIL_WITH_INDEX(ZIP_ER_DETAIL_CDIR_ENTRY_INVALID, ctx->source_index)); return -1; } ctx->start += offset; @@ -168,7 +189,7 @@ window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_sou for (n = 0; n < ctx->start; n += (zip_uint64_t)ret) { i = (ctx->start - n > BUFSIZE ? BUFSIZE : ctx->start - n); if ((ret = zip_source_read(src, b, i)) < 0) { - _zip_error_set_from_source(&ctx->error, src); + zip_error_set_from_source(&ctx->error, src); byte_array_fini(b); return -1; } @@ -186,15 +207,17 @@ window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_sou return 0; case ZIP_SOURCE_READ: - if (len > ctx->end - ctx->offset) + if (ctx->end_valid && len > ctx->end - ctx->offset) { len = ctx->end - ctx->offset; + } - if (len == 0) + if (len == 0) { return 0; + } if (ctx->needs_seek) { if (zip_source_seek(src, (zip_int64_t)ctx->offset, SEEK_SET) < 0) { - _zip_error_set_from_source(&ctx->error, src); + zip_error_set_from_source(&ctx->error, src); return -1; } } @@ -207,7 +230,7 @@ window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_sou ctx->offset += (zip_uint64_t)ret; if (ret == 0) { - if (ctx->offset < ctx->end) { + if (ctx->end_valid && ctx->offset < ctx->end) { zip_error_set(&ctx->error, ZIP_ER_EOF, 0); return -1; } @@ -215,12 +238,40 @@ window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_sou return ret; case ZIP_SOURCE_SEEK: { - zip_int64_t new_offset = zip_source_seek_compute_offset(ctx->offset - ctx->start, ctx->end - ctx->start, data, len, &ctx->error); + zip_int64_t new_offset; + + if (!ctx->end_valid) { + zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error); + + if (args == NULL) { + return -1; + } + if (args->whence == SEEK_END) { + if (zip_source_seek(src, args->offset, args->whence) < 0) { + zip_error_set_from_source(&ctx->error, src); + return -1; + } + new_offset = zip_source_tell(src); + if (new_offset < 0) { + zip_error_set_from_source(&ctx->error, src); + return -1; + } + if ((zip_uint64_t)new_offset < ctx->start) { + zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); + (void)zip_source_seek(src, (zip_int64_t)ctx->offset, SEEK_SET); + return -1; + } + ctx->offset = (zip_uint64_t)new_offset; + return 0; + } + } + new_offset = zip_source_seek_compute_offset(ctx->offset - ctx->start, ctx->end - ctx->start, data, len, &ctx->error); + if (new_offset < 0) { return -1; } - + ctx->offset = (zip_uint64_t)new_offset + ctx->start; return 0; } @@ -233,6 +284,19 @@ window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_sou if (_zip_stat_merge(st, &ctx->stat, &ctx->error) < 0) { return -1; } + + if (!(ctx->stat.valid & ZIP_STAT_SIZE)) { + if (ctx->end_valid) { + st->valid |= ZIP_STAT_SIZE; + st->size = ctx->end - ctx->start; + } + else if (st->valid & ZIP_STAT_SIZE) { + st->size -= ctx->start; + } + } + + st->valid &= ~ctx->stat_invalid; + return 0; } @@ -242,7 +306,7 @@ window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_sou return -1; } - memcpy(data, &ctx->attributes, sizeof(ctx->attributes)); + (void)memcpy_s(data, sizeof(ctx->attributes), &ctx->attributes, sizeof(ctx->attributes)); return sizeof(ctx->attributes); case ZIP_SOURCE_SUPPORTS: @@ -252,8 +316,7 @@ window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_sou return (zip_int64_t)(ctx->offset - ctx->start); default: - zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0); - return -1; + return zip_source_pass_to_lower_layer(src, data, len, cmd); } } diff --git a/Source/Libraries/libzip/zip_source_write.c b/Libraries/libzip/Source/zip_source_write.c similarity index 94% rename from Source/Libraries/libzip/zip_source_write.c rename to Libraries/libzip/Source/zip_source_write.c index 33bf9c944..24dde9b24 100644 --- a/Source/Libraries/libzip/zip_source_write.c +++ b/Libraries/libzip/Source/zip_source_write.c @@ -1,9 +1,9 @@ /* zip_source_write.c -- start a new file for writing - Copyright (C) 2014-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_source_zip.c b/Libraries/libzip/Source/zip_source_zip.c similarity index 68% rename from Source/Libraries/libzip/zip_source_zip.c rename to Libraries/libzip/Source/zip_source_zip.c index cb62540d5..faabf0d29 100644 --- a/Source/Libraries/libzip/zip_source_zip.c +++ b/Libraries/libzip/Source/zip_source_zip.c @@ -1,9 +1,9 @@ /* zip_source_zip.c -- create data source from zip file - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -34,23 +34,30 @@ #include +#define _ZIP_COMPILING_DEPRECATED #include "zipint.h" - -ZIP_EXTERN zip_source_t * -zip_source_zip(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t flags, zip_uint64_t start, zip_int64_t len) { +ZIP_EXTERN zip_source_t *zip_source_zip_create(zip_t *srcza, zip_uint64_t srcidx, zip_flags_t flags, zip_uint64_t start, zip_int64_t len, zip_error_t *error) { if (len < -1) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); + zip_error_set(error, ZIP_ER_INVAL, 0); return NULL; } - - if (len == -1) - len = 0; - - if (start == 0 && len == 0) + + if (len == 0) { + len = -1; + } + + if (start == 0 && len == -1) { flags |= ZIP_FL_COMPRESSED; - else + } + else { flags &= ~ZIP_FL_COMPRESSED; + } + + return zip_source_zip_file_create(srcza, srcidx, flags, start, len, NULL, error); +} + - return _zip_source_zip_new(za, srcza, srcidx, flags, start, (zip_uint64_t)len, NULL); +ZIP_EXTERN zip_source_t *zip_source_zip(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t flags, zip_uint64_t start, zip_int64_t len) { + return zip_source_zip_create(srcza, srcidx, flags, start, len, &za->error); } diff --git a/Libraries/libzip/Source/zip_source_zip_new.c b/Libraries/libzip/Source/zip_source_zip_new.c new file mode 100644 index 000000000..ecccdd68f --- /dev/null +++ b/Libraries/libzip/Source/zip_source_zip_new.c @@ -0,0 +1,312 @@ +/* + zip_source_zip_new.c -- prepare data structures for zip_fopen/zip_source_zip + Copyright (C) 2012-2021 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include + +#include "zipint.h" + +static void _zip_file_attributes_from_dirent(zip_file_attributes_t *attributes, zip_dirent_t *de); + +ZIP_EXTERN zip_source_t *zip_source_zip_file(zip_t* za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t flags, zip_uint64_t start, zip_int64_t len, const char *password) { + return zip_source_zip_file_create(srcza, srcidx, flags, start, len, password, &za->error); +} + + +ZIP_EXTERN zip_source_t *zip_source_zip_file_create(zip_t *srcza, zip_uint64_t srcidx, zip_flags_t flags, zip_uint64_t start, zip_int64_t len, const char *password, zip_error_t *error) { + /* TODO: We need to make sure that the returned source is invalidated when srcza is closed. */ + zip_source_t *src, *s2; + zip_stat_t st; + zip_file_attributes_t attributes; + zip_dirent_t *de; + bool partial_data, needs_crc, encrypted, needs_decrypt, compressed, needs_decompress, changed_data, have_size, have_comp_size; + zip_flags_t stat_flags; + zip_int64_t data_len; + bool take_ownership = false; + bool empty_data = false; + + if (srcza == NULL || srcidx >= srcza->nentry || len < -1) { + zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + + if (flags & ZIP_FL_ENCRYPTED) { + flags |= ZIP_FL_COMPRESSED; + } + + changed_data = false; + if ((flags & ZIP_FL_UNCHANGED) == 0) { + zip_entry_t *entry = srcza->entry + srcidx; + if (ZIP_ENTRY_DATA_CHANGED(entry)) { + if ((flags & ZIP_FL_COMPRESSED) || !zip_source_supports_reopen(entry->source)) { + zip_error_set(error, ZIP_ER_CHANGED, 0); + return NULL; + } + + changed_data = true; + } + else if (entry->deleted) { + zip_error_set(error, ZIP_ER_CHANGED, 0); + return NULL; + } + } + + stat_flags = flags; + if (!changed_data) { + stat_flags |= ZIP_FL_UNCHANGED; + } + + if (zip_stat_index(srcza, srcidx, stat_flags, &st) < 0) { + zip_error_set(error, ZIP_ER_INTERNAL, 0); + return NULL; + } + + if ((start > 0 || len >= 0) && (flags & ZIP_FL_COMPRESSED)) { + zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + + have_size = (st.valid & ZIP_STAT_SIZE) != 0; + /* overflow or past end of file */ + if (len >= 0 && ((start > 0 && start + len < start) || (have_size && start + len > st.size))) { + zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + + if (len == -1) { + if (have_size) { + if (st.size - start > ZIP_INT64_MAX) { + zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + data_len = (zip_int64_t)(st.size - start); + } + else { + data_len = -1; + } + } + else { + data_len = len; + } + + if (have_size) { + partial_data = (zip_uint64_t)(data_len) < st.size; + } + else { + partial_data = true; + } + encrypted = (st.valid & ZIP_STAT_ENCRYPTION_METHOD) && (st.encryption_method != ZIP_EM_NONE); + needs_decrypt = ((flags & ZIP_FL_ENCRYPTED) == 0) && encrypted; + compressed = (st.valid & ZIP_STAT_COMP_METHOD) && (st.comp_method != ZIP_CM_STORE); + needs_decompress = ((flags & ZIP_FL_COMPRESSED) == 0) && compressed; + /* when reading the whole file, check for CRC errors */ + needs_crc = ((flags & ZIP_FL_COMPRESSED) == 0 || !compressed) && !partial_data && (st.valid & ZIP_STAT_CRC) != 0; + + if (needs_decrypt) { + if (password == NULL) { + password = srcza->default_password; + } + if (password == NULL) { + zip_error_set(error, ZIP_ER_NOPASSWD, 0); + return NULL; + } + } + + if ((de = _zip_get_dirent(srcza, srcidx, flags, error)) == NULL) { + return NULL; + } + _zip_file_attributes_from_dirent(&attributes, de); + + have_comp_size = (st.valid & ZIP_STAT_COMP_SIZE) != 0; + if (needs_decrypt || needs_decompress) { + empty_data = (have_comp_size && st.comp_size == 0); + } + else { + empty_data = (have_size && st.size == 0); + } + if (empty_data) { + src = zip_source_buffer_with_attributes_create(NULL, 0, 0, &attributes, error); + } + else { + src = NULL; + } + + + /* If we created source buffer above, we want the window source to take ownership of it. */ + take_ownership = src != NULL; + /* if we created a buffer source above, then treat it as if + reading the changed data - that way we don't need add another + special case to the code below that wraps it in the window + source */ + changed_data = changed_data || (src != NULL); + + if (partial_data && !needs_decrypt && !needs_decompress) { + struct zip_stat st2; + zip_t *source_archive; + zip_uint64_t source_index; + + if (changed_data) { + if (src == NULL) { + src = srcza->entry[srcidx].source; + } + source_archive = NULL; + source_index = 0; + } + else { + src = srcza->src; + source_archive = srcza; + source_index = srcidx; + } + + st2.comp_method = ZIP_CM_STORE; + st2.valid = ZIP_STAT_COMP_METHOD; + if (data_len >= 0) { + st2.size = (zip_uint64_t)data_len; + st2.comp_size = (zip_uint64_t)data_len; + st2.valid |= ZIP_STAT_SIZE | ZIP_STAT_COMP_SIZE; + } + if (st.valid & ZIP_STAT_MTIME) { + st2.mtime = st.mtime; + st2.valid |= ZIP_STAT_MTIME; + } + + if ((src = _zip_source_window_new(src, start, data_len, &st2, ZIP_STAT_NAME, &attributes, source_archive, source_index, take_ownership, error)) == NULL) { + return NULL; + } + } + /* here we restrict src to file data, so no point in doing it for + source that already represents only the file data */ + else if (!changed_data) { + /* this branch is executed only for archive sources; we know + that stat data come from the archive too, so it's safe to + assume that st has a comp_size specified */ + if (st.comp_size > ZIP_INT64_MAX) { + zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + /* despite the fact that we want the whole data file, we still + wrap the source into a window source to add st and + attributes and to have a source that positions the read + offset properly before each read for multiple zip_file_t + referring to the same underlying source */ + if ((src = _zip_source_window_new(srcza->src, 0, (zip_int64_t)st.comp_size, &st, ZIP_STAT_NAME, &attributes, srcza, srcidx, take_ownership, error)) == NULL) { + return NULL; + } + } + else { + /* this branch gets executed when reading the whole changed + data file or when "reading" from a zero-sized source buffer + that we created above */ + if (src == NULL) { + src = srcza->entry[srcidx].source; + } + /* despite the fact that we want the whole data file, we still + wrap the source into a window source to add st and + attributes and to have a source that positions the read + offset properly before each read for multiple zip_file_t + referring to the same underlying source */ + if ((src = _zip_source_window_new(src, 0, data_len, &st, ZIP_STAT_NAME, &attributes, NULL, 0, take_ownership, error)) == NULL) { + return NULL; + } + } + + /* In all cases, src is a window source and therefore is owned by this function. */ + + if (_zip_source_set_source_archive(src, srcza) < 0) { + zip_source_free(src); + return NULL; + } + + /* creating a layered source calls zip_keep() on the lower layer, so we free it */ + + if (needs_decrypt) { + zip_encryption_implementation enc_impl; + + if ((enc_impl = _zip_get_encryption_implementation(st.encryption_method, ZIP_CODEC_DECODE)) == NULL) { + zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0); + return NULL; + } + + s2 = enc_impl(srcza, src, st.encryption_method, 0, password); + if (s2 == NULL) { + zip_source_free(src); + return NULL; + } + + src = s2; + } + if (needs_decompress) { + s2 = zip_source_decompress(srcza, src, st.comp_method); + if (s2 == NULL) { + zip_source_free(src); + return NULL; + } + src = s2; + } + if (needs_crc) { + s2 = zip_source_crc_create(src, 1, error); + if (s2 == NULL) { + zip_source_free(src); + return NULL; + } + src = s2; + } + + if (partial_data && (needs_decrypt || needs_decompress)) { + zip_stat_t st2; + zip_stat_init(&st2); + if (data_len >= 0) { + st2.valid = ZIP_STAT_SIZE; + st2.size = (zip_uint64_t)data_len; + } + s2 = _zip_source_window_new(src, start, data_len, &st2, ZIP_STAT_NAME, NULL, NULL, 0, true, error); + if (s2 == NULL) { + zip_source_free(src); + return NULL; + } + src = s2; + } + + return src; +} + +static void +_zip_file_attributes_from_dirent(zip_file_attributes_t *attributes, zip_dirent_t *de) { + zip_file_attributes_init(attributes); + attributes->valid = ZIP_FILE_ATTRIBUTES_ASCII | ZIP_FILE_ATTRIBUTES_HOST_SYSTEM | ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES | ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS; + attributes->ascii = de->int_attrib & 1; + attributes->host_system = de->version_madeby >> 8; + attributes->external_file_attributes = de->ext_attrib; + attributes->general_purpose_bit_flags = de->bitflags; + attributes->general_purpose_bit_mask = ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS_ALLOWED_MASK; +} diff --git a/Source/Libraries/libzip/zip_stat.c b/Libraries/libzip/Source/zip_stat.c similarity index 94% rename from Source/Libraries/libzip/zip_stat.c rename to Libraries/libzip/Source/zip_stat.c index c328dcfb4..51d8026dd 100644 --- a/Source/Libraries/libzip/zip_stat.c +++ b/Libraries/libzip/Source/zip_stat.c @@ -1,9 +1,9 @@ /* zip_stat.c -- get information about file by name - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_stat_index.c b/Libraries/libzip/Source/zip_stat_index.c similarity index 66% rename from Source/Libraries/libzip/zip_stat_index.c rename to Libraries/libzip/Source/zip_stat_index.c index 62dc0455e..da33c09eb 100644 --- a/Source/Libraries/libzip/zip_stat_index.c +++ b/Libraries/libzip/Source/zip_stat_index.c @@ -3,7 +3,7 @@ Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -39,22 +39,43 @@ ZIP_EXTERN int zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags, zip_stat_t *st) { const char *name; zip_dirent_t *de; + zip_entry_t *entry; - if ((de = _zip_get_dirent(za, index, flags, NULL)) == NULL) + if ((de = _zip_get_dirent(za, index, flags, NULL)) == NULL) { return -1; + } - if ((name = zip_get_name(za, index, flags)) == NULL) + if ((name = zip_get_name(za, index, flags)) == NULL) { return -1; + } + entry = za->entry + index; if ((flags & ZIP_FL_UNCHANGED) == 0 && ZIP_ENTRY_DATA_CHANGED(za->entry + index)) { - zip_entry_t *entry = za->entry + index; if (zip_source_stat(entry->source, st) < 0) { zip_error_set(&za->error, ZIP_ER_CHANGED, 0); return -1; } + if (ZIP_CM_IS_DEFAULT(de->comp_method)) { + if (!(st->valid & ZIP_STAT_COMP_METHOD) || st->comp_method == ZIP_CM_STORE) { + st->valid &= ~(ZIP_STAT_COMP_SIZE|ZIP_STAT_COMP_METHOD); + } + } + else { + if ((st->valid & ZIP_STAT_COMP_METHOD) && st->comp_method != de->comp_method) { + st->valid &= ~ZIP_STAT_COMP_SIZE; + } + st->valid |= ZIP_STAT_COMP_METHOD; + st->comp_method = de->comp_method; + } + + if (((st->valid & (ZIP_STAT_COMP_METHOD|ZIP_STAT_SIZE)) == (ZIP_STAT_COMP_METHOD|ZIP_STAT_SIZE)) && st->comp_method == ZIP_CM_STORE) { + st->valid |= ZIP_STAT_COMP_SIZE; + st->comp_size = st->size; + } + if (entry->changes != NULL && entry->changes->changed & ZIP_DIRENT_LAST_MOD) { st->mtime = de->last_mod; st->valid |= ZIP_STAT_MTIME; @@ -70,6 +91,16 @@ zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags, zip_stat_t *st) st->comp_method = (zip_uint16_t)de->comp_method; st->encryption_method = de->encryption_method; st->valid = (de->crc_valid ? ZIP_STAT_CRC : 0) | ZIP_STAT_SIZE | ZIP_STAT_MTIME | ZIP_STAT_COMP_SIZE | ZIP_STAT_COMP_METHOD | ZIP_STAT_ENCRYPTION_METHOD; + if (entry->changes != NULL && entry->changes->changed & ZIP_DIRENT_COMP_METHOD) { + st->valid &= ~ZIP_STAT_COMP_SIZE; + } + } + + if ((za->ch_flags & ZIP_AFL_WANT_TORRENTZIP) && (flags & ZIP_FL_UNCHANGED) == 0) { + st->comp_method = ZIP_CM_DEFLATE; + st->mtime = _zip_d2u_time(0xbc00, 0x2198); + st->valid |= ZIP_STAT_MTIME | ZIP_STAT_COMP_METHOD; + st->valid &= ~ZIP_STAT_COMP_SIZE; } st->index = index; diff --git a/Source/Libraries/libzip/zip_stat_init.c b/Libraries/libzip/Source/zip_stat_init.c similarity index 96% rename from Source/Libraries/libzip/zip_stat_init.c rename to Libraries/libzip/Source/zip_stat_init.c index 0cf51efad..9c6088a79 100644 --- a/Source/Libraries/libzip/zip_stat_init.c +++ b/Libraries/libzip/Source/zip_stat_init.c @@ -1,9 +1,9 @@ /* zip_stat_init.c -- initialize struct zip_stat. - Copyright (C) 2006-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_strerror.c b/Libraries/libzip/Source/zip_strerror.c similarity index 93% rename from Source/Libraries/libzip/zip_strerror.c rename to Libraries/libzip/Source/zip_strerror.c index 6adec16cd..7d8279318 100644 --- a/Source/Libraries/libzip/zip_strerror.c +++ b/Libraries/libzip/Source/zip_strerror.c @@ -1,9 +1,9 @@ /* zip_sterror.c -- get string representation of zip error - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_string.c b/Libraries/libzip/Source/zip_string.c similarity index 96% rename from Source/Libraries/libzip/zip_string.c rename to Libraries/libzip/Source/zip_string.c index 2c6f42826..1c964491c 100644 --- a/Source/Libraries/libzip/zip_string.c +++ b/Libraries/libzip/Source/zip_string.c @@ -1,9 +1,9 @@ /* zip_string.c -- string handling (with encoding) - Copyright (C) 2012-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2012-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -150,7 +150,7 @@ _zip_string_new(const zip_uint8_t *raw, zip_uint16_t length, zip_flags_t flags, return NULL; } - memcpy(s->raw, raw, length); + (void)memcpy_s(s->raw, length + 1, raw, length); s->raw[length] = '\0'; s->length = length; s->encoding = ZIP_ENCODING_UNKNOWN; diff --git a/Source/Libraries/libzip/zip_unchange.c b/Libraries/libzip/Source/zip_unchange.c similarity index 77% rename from Source/Libraries/libzip/zip_unchange.c rename to Libraries/libzip/Source/zip_unchange.c index 17e250099..d69a3dfe1 100644 --- a/Source/Libraries/libzip/zip_unchange.c +++ b/Libraries/libzip/Source/zip_unchange.c @@ -1,9 +1,9 @@ /* zip_unchange.c -- undo changes to file in zip archive - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -46,14 +46,18 @@ zip_unchange(zip_t *za, zip_uint64_t idx) { int _zip_unchange(zip_t *za, zip_uint64_t idx, int allow_duplicates) { zip_int64_t i; - const char *orig_name, *changed_name; + bool renamed; if (idx >= za->nentry) { zip_error_set(&za->error, ZIP_ER_INVAL, 0); return -1; } - if (!allow_duplicates && za->entry[idx].changes && (za->entry[idx].changes->changed & ZIP_DIRENT_FILENAME)) { + renamed = za->entry[idx].changes && (za->entry[idx].changes->changed & ZIP_DIRENT_FILENAME); + if (!allow_duplicates && (renamed || za->entry[idx].deleted)) { + const char *orig_name = NULL; + const char *changed_name = NULL; + if (za->entry[idx].orig != NULL) { if ((orig_name = _zip_get_name(za, idx, ZIP_FL_UNCHANGED, &za->error)) == NULL) { return -1; @@ -65,12 +69,11 @@ _zip_unchange(zip_t *za, zip_uint64_t idx, int allow_duplicates) { return -1; } } - else { - orig_name = NULL; - } - if ((changed_name = _zip_get_name(za, idx, 0, &za->error)) == NULL) { - return -1; + if (renamed) { + if ((changed_name = _zip_get_name(za, idx, 0, &za->error)) == NULL) { + return -1; + } } if (orig_name) { @@ -78,9 +81,11 @@ _zip_unchange(zip_t *za, zip_uint64_t idx, int allow_duplicates) { return -1; } } - if (_zip_hash_delete(za->names, (const zip_uint8_t *)changed_name, &za->error) == false) { - _zip_hash_delete(za->names, (const zip_uint8_t *)orig_name, NULL); - return -1; + if (changed_name) { + if (_zip_hash_delete(za->names, (const zip_uint8_t *)changed_name, &za->error) == false) { + _zip_hash_delete(za->names, (const zip_uint8_t *)orig_name, NULL); + return -1; + } } } diff --git a/Source/Libraries/libzip/zip_unchange_all.c b/Libraries/libzip/Source/zip_unchange_all.c similarity index 94% rename from Source/Libraries/libzip/zip_unchange_all.c rename to Libraries/libzip/Source/zip_unchange_all.c index b8bfd70e9..34f3702e0 100644 --- a/Source/Libraries/libzip/zip_unchange_all.c +++ b/Libraries/libzip/Source/zip_unchange_all.c @@ -1,9 +1,9 @@ /* zip_unchange.c -- undo changes to all files in zip archive - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_unchange_archive.c b/Libraries/libzip/Source/zip_unchange_archive.c similarity index 94% rename from Source/Libraries/libzip/zip_unchange_archive.c rename to Libraries/libzip/Source/zip_unchange_archive.c index ebf2bd58a..56a8e31f6 100644 --- a/Source/Libraries/libzip/zip_unchange_archive.c +++ b/Libraries/libzip/Source/zip_unchange_archive.c @@ -1,9 +1,9 @@ /* zip_unchange_archive.c -- undo global changes to ZIP archive - Copyright (C) 2006-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_unchange_data.c b/Libraries/libzip/Source/zip_unchange_data.c similarity index 94% rename from Source/Libraries/libzip/zip_unchange_data.c rename to Libraries/libzip/Source/zip_unchange_data.c index 2a393add8..6bdecd187 100644 --- a/Source/Libraries/libzip/zip_unchange_data.c +++ b/Libraries/libzip/Source/zip_unchange_data.c @@ -1,9 +1,9 @@ /* zip_unchange_data.c -- undo helper function - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Source/Libraries/libzip/zip_utf-8.c b/Libraries/libzip/Source/zip_utf-8.c similarity index 98% rename from Source/Libraries/libzip/zip_utf-8.c rename to Libraries/libzip/Source/zip_utf-8.c index 51a47221e..678912f6b 100644 --- a/Source/Libraries/libzip/zip_utf-8.c +++ b/Libraries/libzip/Source/zip_utf-8.c @@ -1,9 +1,9 @@ /* zip_utf-8.c -- UTF-8 support functions for libzip - Copyright (C) 2011-2020 Dieter Baron and Thomas Klausner + Copyright (C) 2011-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at + The authors can be contacted at Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Libraries/libzip/libzip_v1.10.1.txt b/Libraries/libzip/libzip_v1.10.1.txt new file mode 100644 index 000000000..c77ccdd92 --- /dev/null +++ b/Libraries/libzip/libzip_v1.10.1.txt @@ -0,0 +1 @@ +"v1.10.1" diff --git a/README.md b/README.md index 68e055ab8..7400f3adb 100644 --- a/README.md +++ b/README.md @@ -41,9 +41,9 @@ This page also contains a section about building lib3mf from source or obtaining ## Licenses and third party code lib3mf is released under the [BSD license](LICENSE). The library contains code of the following [third parties](SDK/Credits.txt): -1. libzip 1.7.3.1, https://libzip.org/license/ -2. zlib 1.2.11, http://www.zlib.net/zlib_license.html -3. cpp-base64 1.01.00, https://github.com/ReneNyffenegger/cpp-base64/blob/master/LICENSE +1. libzip 1.10.1, https://libzip.org/license/ +2. zlib 1.3.0, http://www.zlib.net/zlib_license.html +3. cpp-base64 2.rc.08, https://github.com/ReneNyffenegger/cpp-base64/blob/master/LICENSE 4. fast-float v6.0.0, https://github.com/fastfloat/fast_float/tree/v6.0.0?tab=License-3-ov-file In addition, the automated tests of lib3mf make use of LibReSSL 3.0.2, [License](Tests/libressl/COPYING). diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 523ec9eb3..2d94b2c24 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -1,10 +1,10 @@ if (USE_INCLUDED_LIBZIP) - file(GLOB LIBZIP_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "Source/Libraries/libzip/*.c") + file(GLOB LIBZIP_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "Libraries/libzip/Source/*.c") if (UNIX) - file(GLOB LIBZIP_FILES_PLATFORM RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "Source/Libraries/libzip/Unix/*.c") + file(GLOB LIBZIP_FILES_PLATFORM RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "Libraries/libzip/Source/unix/*.c") else() - file(GLOB LIBZIP_FILES_PLATFORM RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "Source/Libraries/libzip/Win/*.c") + file(GLOB LIBZIP_FILES_PLATFORM RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "Libraries/libzip/Source/win/*.c") endif() endif() diff --git a/Source/Libraries/libzip/zip_err_str.c b/Source/Libraries/libzip/zip_err_str.c deleted file mode 100644 index c46258b4a..000000000 --- a/Source/Libraries/libzip/zip_err_str.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - This file was generated automatically by CMake - from zip.h; make changes there. -*/ - -#include "zipint.h" - -const char * const _zip_err_str[] = { - "No error", - "Multi-disk zip archives not supported", - "Renaming temporary file failed", - "Closing zip archive failed", - "Seek error", - "Read error", - "Write error", - "CRC error", - "Containing zip archive was closed", - "No such file", - "File already exists", - "Can't open file", - "Failure to create temporary file", - "Zlib error", - "Malloc failure", - "Entry has been changed", - "Compression method not supported", - "Premature end of file", - "Invalid argument", - "Not a zip archive", - "Internal error", - "Zip archive inconsistent", - "Can't remove file", - "Entry has been deleted", - "Encryption method not supported", - "Read-only archive", - "No password provided", - "Wrong password provided", - "Operation not supported", - "Resource still in use", - "Tell error", - "Compressed data invalid", - "Operation cancelled", -}; - -const int _zip_nerr_str = sizeof(_zip_err_str)/sizeof(_zip_err_str[0]); - -#define N ZIP_ET_NONE -#define S ZIP_ET_SYS -#define Z ZIP_ET_ZLIB - -const int _zip_err_type[] = { - N, - N, - S, - S, - S, - S, - S, - N, - N, - N, - N, - S, - S, - Z, - N, - N, - N, - N, - N, - N, - N, - N, - S, - N, - N, - N, - N, - N, - N, - N, - S, - N, - N, -}; diff --git a/Source/Libraries/libzip/zip_source_zip_new.c b/Source/Libraries/libzip/zip_source_zip_new.c deleted file mode 100644 index ffb2bdf4b..000000000 --- a/Source/Libraries/libzip/zip_source_zip_new.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - zip_source_zip_new.c -- prepare data structures for zip_fopen/zip_source_zip - Copyright (C) 2012-2020 Dieter Baron and Thomas Klausner - - This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include - -#include "zipint.h" - -static void _zip_file_attributes_from_dirent(zip_file_attributes_t *attributes, zip_dirent_t *de); - -zip_source_t * -_zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t flags, zip_uint64_t start, zip_uint64_t len, const char *password) { - zip_source_t *src, *s2; - zip_stat_t st; - zip_file_attributes_t attributes; - zip_dirent_t *de; - bool partial_data, needs_crc, needs_decrypt, needs_decompress; - - if (za == NULL) { - return NULL; - } - - if (srcza == NULL || srcidx >= srcza->nentry) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return NULL; - } - - if ((flags & ZIP_FL_UNCHANGED) == 0 && (ZIP_ENTRY_DATA_CHANGED(srcza->entry + srcidx) || srcza->entry[srcidx].deleted)) { - zip_error_set(&za->error, ZIP_ER_CHANGED, 0); - return NULL; - } - - if (zip_stat_index(srcza, srcidx, flags | ZIP_FL_UNCHANGED, &st) < 0) { - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - return NULL; - } - - if (flags & ZIP_FL_ENCRYPTED) { - flags |= ZIP_FL_COMPRESSED; - } - - if ((start > 0 || len > 0) && (flags & ZIP_FL_COMPRESSED)) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return NULL; - } - - /* overflow or past end of file */ - if ((start > 0 || len > 0) && (start + len < start || start + len > st.size)) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return NULL; - } - - if (len == 0) { - len = st.size - start; - } - - partial_data = len < st.size; - needs_decrypt = ((flags & ZIP_FL_ENCRYPTED) == 0) && (st.encryption_method != ZIP_EM_NONE); - needs_decompress = ((flags & ZIP_FL_COMPRESSED) == 0) && (st.comp_method != ZIP_CM_STORE); - /* when reading the whole file, check for CRC errors */ - needs_crc = ((flags & ZIP_FL_COMPRESSED) == 0 || st.comp_method == ZIP_CM_STORE) && !partial_data; - - if (needs_decrypt) { - if (password == NULL) { - password = za->default_password; - } - if (password == NULL) { - zip_error_set(&za->error, ZIP_ER_NOPASSWD, 0); - return NULL; - } - } - - if ((de = _zip_get_dirent(srcza, srcidx, flags, &za->error)) == NULL) { - return NULL; - } - _zip_file_attributes_from_dirent(&attributes, de); - - if (st.comp_size == 0) { - return zip_source_buffer_with_attributes(za, NULL, 0, 0, &attributes); - } - - if (partial_data && !needs_decrypt && !needs_decompress) { - struct zip_stat st2; - - st2.size = len; - st2.comp_size = len; - st2.comp_method = ZIP_CM_STORE; - st2.mtime = st.mtime; - st2.valid = ZIP_STAT_SIZE | ZIP_STAT_COMP_SIZE | ZIP_STAT_COMP_METHOD | ZIP_STAT_MTIME; - - if ((src = _zip_source_window_new(srcza->src, start, len, &st2, &attributes, srcza, srcidx, &za->error)) == NULL) { - return NULL; - } - } - else { - if ((src = _zip_source_window_new(srcza->src, 0, st.comp_size, &st, &attributes, srcza, srcidx, &za->error)) == NULL) { - return NULL; - } - } - - if (_zip_source_set_source_archive(src, srcza) < 0) { - zip_source_free(src); - return NULL; - } - - /* creating a layered source calls zip_keep() on the lower layer, so we free it */ - - if (needs_decrypt) { - zip_encryption_implementation enc_impl; - - if ((enc_impl = _zip_get_encryption_implementation(st.encryption_method, ZIP_CODEC_DECODE)) == NULL) { - zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0); - return NULL; - } - - s2 = enc_impl(za, src, st.encryption_method, 0, password); - zip_source_free(src); - if (s2 == NULL) { - return NULL; - } - src = s2; - } - if (needs_decompress) { - s2 = zip_source_decompress(za, src, st.comp_method); - zip_source_free(src); - if (s2 == NULL) { - return NULL; - } - src = s2; - } - if (needs_crc) { - s2 = zip_source_crc(za, src, 1); - zip_source_free(src); - if (s2 == NULL) { - return NULL; - } - src = s2; - } - - if (partial_data && (needs_decrypt || needs_decompress)) { - s2 = zip_source_window(za, src, start, len); - zip_source_free(src); - if (s2 == NULL) { - return NULL; - } - src = s2; - } - - return src; -} - -static void -_zip_file_attributes_from_dirent(zip_file_attributes_t *attributes, zip_dirent_t *de) { - zip_file_attributes_init(attributes); - attributes->valid = ZIP_FILE_ATTRIBUTES_ASCII | ZIP_FILE_ATTRIBUTES_HOST_SYSTEM | ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES | ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS; - attributes->ascii = de->int_attrib & 1; - attributes->host_system = de->version_madeby >> 8; - attributes->external_file_attributes = de->ext_attrib; - attributes->general_purpose_bit_flags = de->bitflags; - attributes->general_purpose_bit_mask = ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS_ALLOWED_MASK; -} diff --git a/Tests/codecoverage/run_codecoverage.sh b/Tests/codecoverage/run_codecoverage.sh index 817820740..a8a64459f 100755 --- a/Tests/codecoverage/run_codecoverage.sh +++ b/Tests/codecoverage/run_codecoverage.sh @@ -7,7 +7,7 @@ lcov --add-tracefile Test_CPP_Bindings_base.info --add-tracefile Test_CPP_Bindin TARGETDIR=`dirname \`pwd\`` -lcov --remove Test_CPP_Bindings.info --ignore-errors inconsistent -o Test_CPP_Bindings_filtered.info "$TARGETDIR/Tests/*" "$TARGETDIR/Source/Libraries/*" "$TARGETDIR/Include/Libraries/*" "$TARGETDIR/Libraries/*" "$TARGETDIR/submodules/*" "/Applications/*" \ +lcov --remove Test_CPP_Bindings.info --ignore-errors inconsistent -o Test_CPP_Bindings_filtered.info "$TARGETDIR/Tests/*" "$TARGETDIR/Source/Libraries/*" "$TARGETDIR/Include/Libraries/*" "$TARGETDIR/Libraries/*" "$TARGETDIR/build/*" "$TARGETDIR/submodules/*" "/Applications/*" \ "$TARGETDIR/Autogenerated/Bindings/C/*" \ "$TARGETDIR/Autogenerated/Bindings/CDynamic/*" \ "$TARGETDIR/Autogenerated/Bindings/CSharp/*" \ diff --git a/submodules/README.md b/submodules/README.md index bc9f1218f..56511dda5 100644 --- a/submodules/README.md +++ b/submodules/README.md @@ -17,3 +17,7 @@ bash update_libs.sh - If no library name is provided, all libraries will be updated. - If a library name is provided, only that library will be updated. +## Note + +- Libzip - In copying header and source files script, a cmake script is called to generate zip_err_str.c and while configuring CMake of Lib3MF, Libzip needs to be configured as well to generate platfrom specific header files config.h and zipconf.h. + diff --git a/submodules/libzip b/submodules/libzip new file mode 160000 index 000000000..210b09d9d --- /dev/null +++ b/submodules/libzip @@ -0,0 +1 @@ +Subproject commit 210b09d9d2d0f4c0bbc64f92ad45c1ac53598fec diff --git a/submodules/update_libs.bat b/submodules/update_libs.bat index e40236b46..f5e0a86c5 100644 --- a/submodules/update_libs.bat +++ b/submodules/update_libs.bat @@ -81,3 +81,39 @@ for %%A in ("cpp-base64" "") do ( echo "!tag!" >"!lib_path_dest!!lib_name!_!tag!.txt" ) ) + + +for %%A in ("libzip" "") do ( + if "%update_lib%"==%%A ( + REM updating the libzip library + set lib_name=libzip + set lib_path_src=!base_path!!lib_name!\ + cd !lib_name! + set "tag=" + for /f %%i in ('git describe --contains HEAD') do set "tag=%%i" + + cd !base_path! + REM delete the destination library folder when updating + RD /S /Q "..\Libraries\!lib_name!" + set lib_path_dest=..\Libraries\!lib_name!\ + mkdir !lib_path_dest! + + mkdir "!lib_path_dest!Include" + mkdir "!lib_path_dest!Source" + REM when copying files for libzip exclude external lib files aes, crypto, xz, zstd, bzip2 + robocopy *.h !lib_path_src!lib\ "!lib_path_dest!Include" /XF *crypto* + robocopy *.c !lib_path_src!lib\ "!lib_path_dest!Source" /XF *crypto* *aes* *bzip2* *xz* *zstd* *win32* *unix* *stdio_named* *uwp* + + REM copy windows specific files to win and unix specific files to unix folders + mkdir "!lib_path_dest!Source\win" + mkdir "!lib_path_dest!Source\unix" + robocopy *win32*.c !lib_path_src!lib\ "!lib_path_dest!Source\win" + robocopy *unix*.c *stdio_named*.c !lib_path_src!lib\ "!lib_path_dest!Source\unix" + + REM generate autogenerated file using cmake script run + cd !lib_path_dest!Source\ + cmake -DPROJECT_SOURCE_DIR=!lib_path_src! -P !lib_path_src!cmake\GenerateZipErrorStrings.cmake + cd !base_path! + echo "!tag!" >"!lib_path_dest!!lib_name!_!tag!.txt" + ) +) diff --git a/submodules/update_libs.sh b/submodules/update_libs.sh index 5b5d90749..bff169ebf 100644 --- a/submodules/update_libs.sh +++ b/submodules/update_libs.sh @@ -76,5 +76,53 @@ if [[ "$1" == "cpp-base64" || "$update_all_libs" == true ]]; then cp ${lib_path_src}base*.h "${lib_path_dest}Include" cp ${lib_path_src}base*.cpp "${lib_path_dest}Source" + echo "\"$tag\"" > "$lib_path_dest${lib_name}_$tag.txt" +fi + +# Updating the libzip library +if [[ "$1" == "libzip" || "$update_all_libs" == true ]]; then + lib_name="libzip" + lib_path_src="$base_path$lib_name/" + + cd "$lib_name" + tag=$(git describe --contains HEAD) + cd "$base_path" + + # Delete the destination library folder when updating + lib_path_dest="../Libraries/$lib_name/" + rm -rf "$lib_path_dest" + mkdir -p "$lib_path_dest" + + mkdir "$lib_path_dest/Include" + mkdir "$lib_path_dest/Source" + find "${lib_path_src}lib" -name "*.h" \ + ! -name "*crypto*" \ + -exec cp {} "${lib_path_dest}Include" \; + + find "${lib_path_src}lib" -name "*.c" \ + ! -name "*crypto*" \ + ! -name "*aes*" \ + ! -name "*bzip2*" \ + ! -name "*xz*" \ + ! -name "*zstd*" \ + ! -name "*win32*" \ + ! -name "*unix*" \ + ! -name "*stdio_named*" \ + ! -name "*uwp*" \ + -exec cp {} "${lib_path_dest}Source" \; + + # copy windows specific files to win and unix specific files to unix folders + mkdir ${lib_path_dest}Source/win + mkdir ${lib_path_dest}Source/unix + + find "${lib_path_src}lib" -name "*win32*.c" \ + -exec cp {} "${lib_path_dest}Source/win" \; + + find "${lib_path_src}lib" \( -name "*unix*.c" -o -name "*stdio_named*.c" \) \ + -exec cp {} "${lib_path_dest}Source/unix" \; + + cd "${lib_path_dest}Source" + cmake -DPROJECT_SOURCE_DIR=${lib_path_src} -P ${lib_path_src}cmake/GenerateZipErrorStrings.cmake + cd "$base_path" echo "\"$tag\"" > "$lib_path_dest${lib_name}_$tag.txt" fi \ No newline at end of file