From b9ffb962e3b684cd6d2ffac674f3210134fd8cd7 Mon Sep 17 00:00:00 2001 From: Martin Lau Date: Tue, 22 Dec 2020 15:33:33 +0800 Subject: [PATCH] commit code: Update libzip to 1.7.3; add support iOS --- Package.swift | 111 +-- README-CN.md | 2 +- README.md | 2 +- Sources/libzip/include-patches/zip.h.patch | 172 ----- .../libzip/include-patches/zipconf.h.patch | 74 -- Sources/libzip/include/zip.h | 303 ++++---- Sources/libzip/include/zipconf.h | 40 +- Sources/libzip/private_include/config.h | 107 --- .../libzip/private_include/darwin/config.h | 62 ++ Sources/libzip/private_include/linux/config.h | 62 ++ Sources/libzip/src/compat.h | 9 - Sources/libzip/src/zip.h | 456 ------------ Sources/libzip/src/zip_algorithm_bzip2.c | 10 +- Sources/libzip/src/zip_algorithm_deflate.c | 14 +- Sources/libzip/src/zip_algorithm_xz.c | 75 +- Sources/libzip/src/zip_close.c | 87 ++- Sources/libzip/src/zip_crypto_gnutls.h | 1 + Sources/libzip/src/zip_crypto_mbedtls.c | 1 + Sources/libzip/src/zip_crypto_openssl.c | 2 +- Sources/libzip/src/zip_crypto_win.c | 5 +- Sources/libzip/src/zip_dirent.c | 101 ++- Sources/libzip/src/zip_err_str.c | 4 +- Sources/libzip/src/zip_error_strerror.c | 1 + Sources/libzip/src/zip_error_to_str.c | 2 +- Sources/libzip/src/zip_file_get_offset.c | 3 - Sources/libzip/src/zip_filerange_crc.c | 84 --- Sources/libzip/src/zip_fopen_index.c | 3 - Sources/libzip/src/zip_fseek.c | 1 - Sources/libzip/src/zip_ftell.c | 1 - .../src/zip_get_encryption_implementation.c | 13 +- Sources/libzip/src/zip_mkstempm.c | 19 +- Sources/libzip/src/zip_open.c | 8 +- Sources/libzip/src/zip_pkware.c | 112 +++ Sources/libzip/src/zip_progress.c | 8 +- Sources/libzip/src/zip_random_unix.c | 13 +- Sources/libzip/src/zip_random_uwp.c | 6 +- Sources/libzip/src/zip_random_win32.c | 7 +- Sources/libzip/src/zip_rename.c | 2 - Sources/libzip/src/zip_set_file_comment.c | 2 - Sources/libzip/src/zip_source_buffer.c | 55 +- Sources/libzip/src/zip_source_compress.c | 38 +- Sources/libzip/src/zip_source_crc.c | 4 +- Sources/libzip/src/zip_source_file.c | 61 -- Sources/libzip/src/zip_source_file.h | 90 +++ Sources/libzip/src/zip_source_file_common.c | 378 ++++++++++ Sources/libzip/src/zip_source_file_stdio.c | 208 ++++++ ...ession_flags.c => zip_source_file_stdio.h} | 40 +- .../libzip/src/zip_source_file_stdio_named.c | 313 +++++++++ Sources/libzip/src/zip_source_file_win32.c | 230 ++++++ Sources/libzip/src/zip_source_file_win32.h | 74 ++ .../libzip/src/zip_source_file_win32_ansi.c | 81 +++ .../libzip/src/zip_source_file_win32_named.c | 266 +++++++ .../libzip/src/zip_source_file_win32_utf16.c | 108 +++ ...n32utf8.c => zip_source_file_win32_utf8.c} | 32 +- Sources/libzip/src/zip_source_filep.c | 664 ------------------ .../src/zip_source_get_file_attributes.c | 104 +++ ...ce_pkware.c => zip_source_pkware_decode.c} | 136 ++-- Sources/libzip/src/zip_source_pkware_encode.c | 249 +++++++ Sources/libzip/src/zip_source_win32a.c | 130 ---- Sources/libzip/src/zip_source_win32handle.c | 602 ---------------- Sources/libzip/src/zip_source_win32w.c | 154 ---- Sources/libzip/src/zip_source_window.c | 25 +- .../libzip/src/zip_source_winzip_aes_encode.c | 14 +- Sources/libzip/src/zip_source_zip.c | 1 - Sources/libzip/src/zip_source_zip_new.c | 38 +- Sources/libzip/src/zip_stat_index.c | 2 +- Sources/libzip/src/zip_string.c | 4 +- Sources/libzip/src/zip_unchange_all.c | 2 - Sources/libzip/src/zip_winzip_aes.c | 1 - Sources/libzip/src/zipint.h | 52 +- Sources/libzip/src/zipwin32.h | 85 --- 71 files changed, 3084 insertions(+), 3142 deletions(-) delete mode 100644 Sources/libzip/include-patches/zip.h.patch delete mode 100644 Sources/libzip/include-patches/zipconf.h.patch delete mode 100644 Sources/libzip/private_include/config.h create mode 100644 Sources/libzip/private_include/darwin/config.h create mode 100644 Sources/libzip/private_include/linux/config.h delete mode 100644 Sources/libzip/src/zip.h delete mode 100644 Sources/libzip/src/zip_filerange_crc.c create mode 100644 Sources/libzip/src/zip_pkware.c delete mode 100644 Sources/libzip/src/zip_source_file.c create mode 100644 Sources/libzip/src/zip_source_file.h create mode 100644 Sources/libzip/src/zip_source_file_common.c create mode 100644 Sources/libzip/src/zip_source_file_stdio.c rename Sources/libzip/src/{zip_source_get_compression_flags.c => zip_source_file_stdio.h} (67%) create mode 100644 Sources/libzip/src/zip_source_file_stdio_named.c create mode 100644 Sources/libzip/src/zip_source_file_win32.c create mode 100644 Sources/libzip/src/zip_source_file_win32.h create mode 100644 Sources/libzip/src/zip_source_file_win32_ansi.c create mode 100644 Sources/libzip/src/zip_source_file_win32_named.c create mode 100644 Sources/libzip/src/zip_source_file_win32_utf16.c rename Sources/libzip/src/{zip_source_win32utf8.c => zip_source_file_win32_utf8.c} (84%) delete mode 100644 Sources/libzip/src/zip_source_filep.c create mode 100644 Sources/libzip/src/zip_source_get_file_attributes.c rename Sources/libzip/src/{zip_source_pkware.c => zip_source_pkware_decode.c} (63%) create mode 100644 Sources/libzip/src/zip_source_pkware_encode.c delete mode 100644 Sources/libzip/src/zip_source_win32a.c delete mode 100644 Sources/libzip/src/zip_source_win32handle.c delete mode 100644 Sources/libzip/src/zip_source_win32w.c delete mode 100644 Sources/libzip/src/zipwin32.h diff --git a/Package.swift b/Package.swift index 83f21e8..4654d68 100644 --- a/Package.swift +++ b/Package.swift @@ -5,26 +5,10 @@ import PackageDescription // MARK: - Common -private func ruleSets(_ items: [[Element]]) -> [Element] { - return items.flatMap { $0 } -} - -private func always(use items: [Element]) -> [Element] { - return items -} - -private func when(_ condition: Bool, use items: [Element]) -> [Element] { - if condition { - return items - } else { - return [] - } -} - private enum OSPlatform: Equatable { case darwin // macOS, iOS, tvOS, watchOS case linux // ubuntu(16/18/20) / Amazon Linux 2 - case windows // windows 10² + case windows // windows 10 #if os(macOS) static let current = OSPlatform.darwin @@ -35,12 +19,25 @@ private enum OSPlatform: Equatable { #endif } +private func ruleSets(_ items: [[Element]]) -> [Element] { + return items.flatMap { $0 } +} + +private func releDeclaration(_ items: [Element], when platforms: [OSPlatform]) -> [Element] { + if !platforms.contains(OSPlatform.current) { + return [] + } + return items +} + + // MARK: - Package Config let package = Package( name: "LibzipSwift", platforms: [ .macOS(.v10_13), + .iOS(.v13) ], products: [ .library(name: "LibzipSwift", targets: ["LibzipSwift"]), @@ -58,51 +55,63 @@ let package = Package( dependencies: [], path: "Sources/libzip", exclude: ruleSets([ - // always excluded items - always(use: [ - // Exclude XZ compression - "src/zip_algorithm_xz.c", - - // Exclude non-CommonCrypto encryption + [ + // HAVE_MBEDTLS HAVE_GNUTLS "src/zip_crypto_mbedtls.c", "src/zip_crypto_gnutls.c", + ], + releDeclaration([ + // HAVE_WINDOWS_CRYPTO "src/zip_crypto_win.c", - // Exclude Windows random - "src/zip_random_win32.c", + // WIN32 "src/zip_random_uwp.c", - - // Exclude Windows utilities - "src/zip_source_win32handle.c", - "src/zip_source_win32utf8.c", - "src/zip_source_win32a.c", - "src/zip_source_win32w.c", - ]), - when(OSPlatform.current == .darwin, use: [ - "src/zip_crypto_openssl.c", - ]), - when(OSPlatform.current == .linux, use: [ + "src/zip_source_file_win32.c", + "src/zip_source_file_win32_named.c", + "src/zip_source_file_win32_utf16.c", + "src/zip_source_file_win32_utf8.c", + "src/zip_source_file_win32_ansi.c", + "src/zip_random_win32.c" + ], when: [.linux, .darwin]), + + releDeclaration([ + // HAVE_COMMONCRYPTO "src/zip_crypto_commoncrypto.c", - ]), + ], when: [.linux]), + + releDeclaration([ + // HAVE_OPENSSL + "src/zip_crypto_openssl.c", + + // HAVE_LIBLZMA + // LZMA compression requires LZMA SDK + "src/zip_algorithm_xz.c", + ], when: [.darwin]), ]), sources: [ "src", + "" ], publicHeadersPath: "include", - cSettings: [ - .define("HAVE_CONFIG_H"), - .headerSearchPath("private_include"), - ], - linkerSettings: ruleSets([ - always(use: [ - .linkedLibrary("z"), - .linkedLibrary("bz2"), - ]), - when(OSPlatform.current == .linux, use: [ - .linkedLibrary("ssl"), - .linkedLibrary("crypto") - ]), - ]) + cSettings: ruleSets([ + [ + .define("HAVE_CONFIG_H"), + ], + releDeclaration([ + .headerSearchPath("private_include/darwin"), + ], when: [.darwin]), + releDeclaration([ + .headerSearchPath("private_include/linux"), + ], when: [.linux]), + ]), + linkerSettings: [ + .linkedLibrary("z"), + .linkedLibrary("bz2"), + + .linkedLibrary("lzma", .when(platforms: [.linux])), + .linkedLibrary("ssl", .when(platforms: [.linux])), + .linkedLibrary("crypto", .when(platforms: [.linux])), + ] ), .target( name: "LibzipSwift", diff --git a/README-CN.md b/README-CN.md index c3b127f..e0d61e4 100644 --- a/README-CN.md +++ b/README-CN.md @@ -74,7 +74,7 @@ print("\(Handle errors here)") ### TODO - [x] ~~完整的压缩函式~~ -- [ ] 对iOS 支持的完善 +- [x] 对iOS 支持的完善 - [ ] 对 unix 上的zip 归档保留更多属性 - [ ] 完善单元测试 - [ ] more diff --git a/README.md b/README.md index 9aa1ed8..babfbc1 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ When you want to undo the changes, you can add discardChanged: false to the clos - [x] ~~Complete compression function~~ -- [ ] Improved iOS support +- [x] Improved iOS support - [ ] Preserve more attributes for zip archives on unix diff --git a/Sources/libzip/include-patches/zip.h.patch b/Sources/libzip/include-patches/zip.h.patch deleted file mode 100644 index a36a071..0000000 --- a/Sources/libzip/include-patches/zip.h.patch +++ /dev/null @@ -1,172 +0,0 @@ ---- zip_old.h 2020-03-10 15:06:15.000000000 +0800 -+++ zip.h 2020-02-03 22:18:57.000000000 +0800 -@@ -2,34 +2,37 @@ - #define _HAD_ZIP_H - - /* -- zip.h -- exported declarations. -- Copyright (C) 1999-2019 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. -- */ -+ zip.h -- exported declarations. -+ 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. -+*/ - - - #ifdef __cplusplus -@@ -131,6 +134,7 @@ - #define ZIP_ER_INUSE 29 /* N Resource still in use */ - #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 */ - - /* type of system error value */ - -@@ -159,6 +163,7 @@ - /* 15-17 - Reserved by PKWARE */ - #define ZIP_CM_TERSE 18 /* compressed using IBM TERSE (new) */ - #define ZIP_CM_LZ77 19 /* IBM LZ77 z Architecture (PFS) */ -+#define ZIP_CM_LZMA2 33 - #define ZIP_CM_XZ 95 /* XZ compressed data */ - #define ZIP_CM_JPEG 96 /* Compressed Jpeg data */ - #define ZIP_CM_WAVPACK 97 /* WavPack compressed data */ -@@ -226,7 +231,8 @@ - ZIP_SOURCE_SUPPORTS, /* check whether source supports command */ - ZIP_SOURCE_REMOVE, /* remove file */ - ZIP_SOURCE_GET_COMPRESSION_FLAGS, /* get compression flags, internal only */ -- ZIP_SOURCE_BEGIN_WRITE_CLONING /* like ZIP_SOURCE_BEGIN_WRITE, but keep part of original file */ -+ 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 */ - }; - typedef enum zip_source_cmd zip_source_cmd_t; - -@@ -234,26 +240,26 @@ - - // clang-format off - --#define ZIP_SOURCE_SUPPORTS_READABLE (ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_OPEN) \ --| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_READ) \ --| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_CLOSE) \ --| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_STAT) \ --| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ERROR) \ --| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_FREE)) -- --#define ZIP_SOURCE_SUPPORTS_SEEKABLE (ZIP_SOURCE_SUPPORTS_READABLE \ --| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK) \ --| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_TELL) \ --| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SUPPORTS)) -+#define ZIP_SOURCE_SUPPORTS_READABLE (ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_OPEN) \ -+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_READ) \ -+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_CLOSE) \ -+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_STAT) \ -+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ERROR) \ -+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_FREE)) -+ -+#define ZIP_SOURCE_SUPPORTS_SEEKABLE (ZIP_SOURCE_SUPPORTS_READABLE \ -+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK) \ -+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_TELL) \ -+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SUPPORTS)) - - #define ZIP_SOURCE_SUPPORTS_WRITABLE (ZIP_SOURCE_SUPPORTS_SEEKABLE \ --| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE) \ --| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_COMMIT_WRITE) \ --| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ROLLBACK_WRITE) \ --| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_WRITE) \ --| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK_WRITE) \ --| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_TELL_WRITE) \ --| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_REMOVE)) -+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE) \ -+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_COMMIT_WRITE) \ -+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ROLLBACK_WRITE) \ -+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_WRITE) \ -+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK_WRITE) \ -+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_TELL_WRITE) \ -+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_REMOVE)) - - // clang-format on - -@@ -318,6 +324,7 @@ - - typedef zip_int64_t (*zip_source_callback)(void * _Nullable, void * _Nullable, zip_uint64_t, zip_source_cmd_t); - 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 - typedef void (*zip_progress_callback_t)(double); -@@ -370,6 +377,7 @@ - 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); -+ZIP_EXTERN int zip_file_set_dostime(zip_t * _Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_flags_t); - ZIP_EXTERN int zip_file_set_encryption(zip_t * _Nonnull, zip_uint64_t, zip_uint16_t, const char * _Nullable); - ZIP_EXTERN int zip_file_set_external_attributes(zip_t * _Nonnull, zip_uint64_t, zip_flags_t, zip_uint8_t, zip_uint32_t); - ZIP_EXTERN int zip_file_set_mtime(zip_t * _Nonnull, zip_uint64_t, time_t, zip_flags_t); -@@ -390,6 +398,7 @@ - ZIP_EXTERN zip_t * _Nullable zip_open(const char * _Nonnull, int, int * _Nullable); - ZIP_EXTERN zip_t * _Nullable zip_open_from_source(zip_source_t * _Nonnull, int, zip_error_t * _Nullable); - ZIP_EXTERN int zip_register_progress_callback_with_state(zip_t * _Nonnull, double, zip_progress_callback _Nullable, void (* _Nullable)(void * _Nullable), void * _Nullable); -+ZIP_EXTERN int zip_register_cancel_callback_with_state(zip_t * _Nonnull, zip_cancel_callback _Nullable, void (* _Nullable)(void * _Nullable), void * _Nullable); - ZIP_EXTERN int zip_set_archive_comment(zip_t * _Nonnull, const char * _Nullable, zip_uint16_t); - ZIP_EXTERN int zip_set_archive_flag(zip_t * _Nonnull, zip_flags_t, int); - ZIP_EXTERN int zip_set_default_password(zip_t * _Nonnull, const char * _Nullable); -@@ -399,7 +408,7 @@ - ZIP_EXTERN zip_source_t * _Nullable zip_source_buffer(zip_t * _Nonnull, const void * _Nullable, zip_uint64_t, int); - ZIP_EXTERN zip_source_t * _Nullable zip_source_buffer_create(const void * _Nullable, zip_uint64_t, int, zip_error_t * _Nullable); - ZIP_EXTERN zip_source_t * _Nullable zip_source_buffer_fragment(zip_t * _Nonnull, const zip_buffer_fragment_t * _Nonnull, zip_uint64_t, int); --ZIP_EXTERN zip_source_t * _Nullable zip_source_buffer_fragment_create(const zip_buffer_fragment_t * _Nonnull, zip_uint64_t, int, zip_error_t * _Nullable); -+ZIP_EXTERN zip_source_t * _Nullable zip_source_buffer_fragment_create(const zip_buffer_fragment_t * _Nullable, zip_uint64_t, int, zip_error_t * _Nullable); - ZIP_EXTERN int zip_source_close(zip_source_t * _Nonnull); - ZIP_EXTERN int zip_source_commit_write(zip_source_t * _Nonnull); - ZIP_EXTERN zip_error_t * _Nonnull zip_source_error(zip_source_t * _Nonnull); diff --git a/Sources/libzip/include-patches/zipconf.h.patch b/Sources/libzip/include-patches/zipconf.h.patch deleted file mode 100644 index 0db37e9..0000000 --- a/Sources/libzip/include-patches/zipconf.h.patch +++ /dev/null @@ -1,74 +0,0 @@ ---- zipconf_old.h 2020-03-10 15:00:35.000000000 +0800 -+++ zipconf.h 2020-03-10 15:00:30.000000000 +0800 -@@ -4,44 +4,45 @@ - /* - zipconf.h -- platform specific include file - -- This file was generated automatically by ./make_zipconf.sh -- based on ../config.h. -+ This file was generated automatically by CMake -+ based on ../cmake-zipconf.h.in. - */ - --#define LIBZIP_VERSION "0.11" --#define LIBZIP_VERSION_MAJOR 0 --#define LIBZIP_VERSION_MINOR 11 --#define LIBZIP_VERSION_MICRO 0 -+#define LIBZIP_VERSION "1.6.1" -+#define LIBZIP_VERSION_MAJOR 1 -+#define LIBZIP_VERSION_MINOR 6 -+#define LIBZIP_VERSION_MICRO 1 - --#include -+/* #undef ZIP_STATIC */ - --typedef int8_t zip_int8_t; --#define ZIP_INT8_MIN INT8_MIN --#define ZIP_INT8_MAX INT8_MAX - --typedef uint8_t zip_uint8_t; --#define ZIP_UINT8_MAX UINT8_MAX - --typedef int16_t zip_int16_t; --#define ZIP_INT16_MIN INT16_MIN --#define ZIP_INT16_MAX INT16_MAX -+#define __STDC_FORMAT_MACROS 1 -+#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; --#define ZIP_UINT16_MAX UINT16_MAX -- - typedef int32_t zip_int32_t; --#define ZIP_INT32_MIN INT32_MIN --#define ZIP_INT32_MAX INT32_MAX -- - typedef uint32_t zip_uint32_t; --#define ZIP_UINT32_MAX UINT32_MAX -- - typedef int64_t zip_int64_t; --#define ZIP_INT64_MIN INT64_MIN --#define ZIP_INT64_MAX INT64_MAX -- - typedef uint64_t zip_uint64_t; --#define ZIP_UINT64_MAX UINT64_MAX - -+#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/Sources/libzip/include/zip.h b/Sources/libzip/include/zip.h index b0d1493..a90776d 100644 --- a/Sources/libzip/include/zip.h +++ b/Sources/libzip/include/zip.h @@ -161,8 +161,8 @@ extern "C" { /* 13 - Reserved by PKWARE */ #define ZIP_CM_LZMA 14 /* LZMA (EFS) */ /* 15-17 - Reserved by PKWARE */ -#define ZIP_CM_TERSE 18 /* compressed using IBM TERSE (new) */ -#define ZIP_CM_LZ77 19 /* IBM LZ77 z Architecture (PFS) */ +#define ZIP_CM_TERSE 18 /* compressed using IBM TERSE (new) */ +#define ZIP_CM_LZ77 19 /* IBM LZ77 z Architecture (PFS) */ #define ZIP_CM_LZMA2 33 #define ZIP_CM_XZ 95 /* XZ compressed data */ #define ZIP_CM_JPEG 96 /* Compressed Jpeg data */ @@ -214,31 +214,32 @@ extern "C" { enum zip_source_cmd { - ZIP_SOURCE_OPEN, /* prepare for reading */ - ZIP_SOURCE_READ, /* read data */ - ZIP_SOURCE_CLOSE, /* reading is done */ - ZIP_SOURCE_STAT, /* get meta information */ - ZIP_SOURCE_ERROR, /* get error information */ - ZIP_SOURCE_FREE, /* cleanup and free resources */ - ZIP_SOURCE_SEEK, /* set position for reading */ - ZIP_SOURCE_TELL, /* get read position */ - ZIP_SOURCE_BEGIN_WRITE, /* prepare for writing */ - ZIP_SOURCE_COMMIT_WRITE, /* writing is done */ - ZIP_SOURCE_ROLLBACK_WRITE, /* discard written changes */ - ZIP_SOURCE_WRITE, /* write data */ - ZIP_SOURCE_SEEK_WRITE, /* set position for writing */ - ZIP_SOURCE_TELL_WRITE, /* get write position */ - ZIP_SOURCE_SUPPORTS, /* check whether source supports command */ - ZIP_SOURCE_REMOVE, /* remove file */ - ZIP_SOURCE_GET_COMPRESSION_FLAGS, /* get compression flags, internal only */ - 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_OPEN, /* prepare for reading */ + ZIP_SOURCE_READ, /* read data */ + ZIP_SOURCE_CLOSE, /* reading is done */ + ZIP_SOURCE_STAT, /* get meta information */ + ZIP_SOURCE_ERROR, /* get error information */ + ZIP_SOURCE_FREE, /* cleanup and free resources */ + ZIP_SOURCE_SEEK, /* set position for reading */ + ZIP_SOURCE_TELL, /* get read position */ + ZIP_SOURCE_BEGIN_WRITE, /* prepare for writing */ + ZIP_SOURCE_COMMIT_WRITE, /* writing is done */ + ZIP_SOURCE_ROLLBACK_WRITE, /* discard written changes */ + ZIP_SOURCE_WRITE, /* write data */ + ZIP_SOURCE_SEEK_WRITE, /* set position for writing */ + ZIP_SOURCE_TELL_WRITE, /* get write position */ + ZIP_SOURCE_SUPPORTS, /* check whether source supports command */ + ZIP_SOURCE_REMOVE, /* remove file */ + 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 */ }; typedef enum zip_source_cmd zip_source_cmd_t; #define ZIP_SOURCE_MAKE_COMMAND_BITMASK(cmd) (((zip_int64_t)1) << (cmd)) -// clang-format off +/* clang-format off */ #define ZIP_SOURCE_SUPPORTS_READABLE (ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_OPEN) \ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_READ) \ @@ -261,7 +262,7 @@ typedef enum zip_source_cmd zip_source_cmd_t; | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_TELL_WRITE) \ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_REMOVE)) -// clang-format on +/* clang-format on */ /* for use by sources */ struct zip_source_args_seek { @@ -276,9 +277,9 @@ typedef struct zip_source_args_seek zip_source_args_seek_t; /* error information */ /* use zip_error_*() to access */ struct zip_error { - int zip_err; /* libzip error code (ZIP_ER_*) */ - int sys_err; /* copy of errno (E*) or zlib error code */ - char * _Nullable str; /* string representation or NULL */ + int zip_err; /* libzip error code (ZIP_ER_*) */ + int sys_err; /* copy of errno (E*) or zlib error code */ + char *_Nullable str; /* string representation or NULL */ }; #define ZIP_STAT_NAME 0x0001u @@ -293,7 +294,7 @@ struct zip_error { struct zip_stat { zip_uint64_t valid; /* which fields have valid values */ - const char * _Nullable name; /* name of the file */ + const char *_Nullable name; /* name of the file */ zip_uint64_t index; /* index within archive */ zip_uint64_t size; /* size of file (uncompressed) */ zip_uint64_t comp_size; /* size of file (compressed) */ @@ -305,10 +306,27 @@ struct zip_stat { }; struct zip_buffer_fragment { - zip_uint8_t * _Nonnull data; + zip_uint8_t *_Nonnull data; zip_uint64_t length; }; +struct zip_file_attributes { + zip_uint64_t valid; /* which fields have valid values */ + zip_uint8_t version; /* version of this struct, currently 1 */ + zip_uint8_t host_system; /* host system on which file was created */ + zip_uint8_t ascii; /* flag whether file is ASCII text */ + zip_uint8_t version_needed; /* minimum version needed to extract file */ + zip_uint32_t external_file_attributes; /* external file attributes (host-system specific) */ + zip_uint16_t general_purpose_bit_flags; /* general purpose big flags, only some bits are honored */ + zip_uint16_t general_purpose_bit_mask; /* which bits in general_purpose_bit_flags are valid */ +}; + +#define ZIP_FILE_ATTRIBUTES_HOST_SYSTEM 0x0001u +#define ZIP_FILE_ATTRIBUTES_ASCII 0x0002u +#define ZIP_FILE_ATTRIBUTES_VERSION_NEEDED 0x0004u +#define ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES 0x0008u +#define ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS 0x0010u + struct zip; struct zip_file; struct zip_source; @@ -316,121 +334,124 @@ struct zip_source; typedef struct zip zip_t; typedef struct zip_error zip_error_t; typedef struct zip_file zip_file_t; +typedef struct zip_file_attributes zip_file_attributes_t; typedef struct zip_source zip_source_t; typedef struct zip_stat zip_stat_t; 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 void (*zip_progress_callback)(zip_t * _Nonnull, double, void * _Nullable); -typedef int (*zip_cancel_callback)(zip_t * _Nonnull, void * _Nullable); +typedef zip_int64_t (*zip_source_callback)(void *_Nullable, void *_Nullable, zip_uint64_t, zip_source_cmd_t); +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 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_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 */ #endif -ZIP_EXTERN int zip_close(zip_t * _Nonnull); -ZIP_EXTERN int zip_delete(zip_t * _Nonnull, zip_uint64_t); -ZIP_EXTERN zip_int64_t zip_dir_add(zip_t * _Nonnull, const char * _Nonnull, zip_flags_t); -ZIP_EXTERN void zip_discard(zip_t * _Nonnull); - -ZIP_EXTERN zip_error_t * _Nonnull zip_get_error(zip_t * _Nonnull); -ZIP_EXTERN void zip_error_clear(zip_t * _Nonnull); -ZIP_EXTERN int zip_error_code_zip(const zip_error_t * _Nonnull); -ZIP_EXTERN int zip_error_code_system(const zip_error_t * _Nonnull); -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 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); - -ZIP_EXTERN int zip_fclose(zip_file_t * _Nonnull); -ZIP_EXTERN zip_t * _Nullable zip_fdopen(int, int, int * _Nullable); -ZIP_EXTERN zip_int64_t zip_file_add(zip_t * _Nonnull, const char * _Nonnull, zip_source_t * _Nonnull, zip_flags_t); -ZIP_EXTERN void zip_file_error_clear(zip_file_t * _Nonnull); -ZIP_EXTERN int zip_file_extra_field_delete(zip_t * _Nonnull, zip_uint64_t, zip_uint16_t, zip_flags_t); -ZIP_EXTERN int zip_file_extra_field_delete_by_id(zip_t * _Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_flags_t); -ZIP_EXTERN int zip_file_extra_field_set(zip_t * _Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, const zip_uint8_t * _Nullable, zip_uint16_t, zip_flags_t); -ZIP_EXTERN zip_int16_t zip_file_extra_fields_count(zip_t * _Nonnull, zip_uint64_t, zip_flags_t); -ZIP_EXTERN zip_int16_t zip_file_extra_fields_count_by_id(zip_t * _Nonnull, zip_uint64_t, zip_uint16_t, zip_flags_t); -ZIP_EXTERN const zip_uint8_t * _Nullable zip_file_extra_field_get(zip_t * _Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t * _Nullable, zip_uint16_t * _Nullable, zip_flags_t); -ZIP_EXTERN const zip_uint8_t * _Nullable zip_file_extra_field_get_by_id(zip_t * _Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_uint16_t * _Nullable, zip_flags_t); -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_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); -ZIP_EXTERN int zip_file_set_dostime(zip_t * _Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_flags_t); -ZIP_EXTERN int zip_file_set_encryption(zip_t * _Nonnull, zip_uint64_t, zip_uint16_t, const char * _Nullable); -ZIP_EXTERN int zip_file_set_external_attributes(zip_t * _Nonnull, zip_uint64_t, zip_flags_t, zip_uint8_t, zip_uint32_t); -ZIP_EXTERN int zip_file_set_mtime(zip_t * _Nonnull, zip_uint64_t, time_t, zip_flags_t); -ZIP_EXTERN const char * _Nonnull zip_file_strerror(zip_file_t * _Nonnull); -ZIP_EXTERN zip_file_t * _Nullable zip_fopen(zip_t * _Nonnull, const char * _Nonnull, zip_flags_t); -ZIP_EXTERN zip_file_t * _Nullable zip_fopen_encrypted(zip_t * _Nonnull, const char * _Nonnull, zip_flags_t, const char * _Nullable); -ZIP_EXTERN zip_file_t * _Nullable zip_fopen_index(zip_t * _Nonnull, zip_uint64_t, zip_flags_t); -ZIP_EXTERN zip_file_t * _Nullable zip_fopen_index_encrypted(zip_t * _Nonnull, zip_uint64_t, zip_flags_t, const char * _Nullable); -ZIP_EXTERN zip_int64_t zip_fread(zip_file_t * _Nonnull, void * _Nonnull, zip_uint64_t); -ZIP_EXTERN zip_int8_t zip_fseek(zip_file_t * _Nonnull, zip_int64_t, int); -ZIP_EXTERN zip_int64_t zip_ftell(zip_file_t * _Nonnull); -ZIP_EXTERN const char * _Nullable zip_get_archive_comment(zip_t * _Nonnull, int * _Nullable, zip_flags_t); -ZIP_EXTERN int zip_get_archive_flag(zip_t * _Nonnull, zip_flags_t, zip_flags_t); -ZIP_EXTERN const char * _Nullable zip_get_name(zip_t * _Nonnull, zip_uint64_t, zip_flags_t); -ZIP_EXTERN zip_int64_t zip_get_num_entries(zip_t * _Nonnull, zip_flags_t); -ZIP_EXTERN const char * _Nonnull zip_libzip_version(void); -ZIP_EXTERN zip_int64_t zip_name_locate(zip_t * _Nonnull, const char * _Nonnull, zip_flags_t); -ZIP_EXTERN zip_t * _Nullable zip_open(const char * _Nonnull, int, int * _Nullable); -ZIP_EXTERN zip_t * _Nullable zip_open_from_source(zip_source_t * _Nonnull, int, zip_error_t * _Nullable); -ZIP_EXTERN int zip_register_progress_callback_with_state(zip_t * _Nonnull, double, zip_progress_callback _Nullable, void (* _Nullable)(void * _Nullable), void * _Nullable); -ZIP_EXTERN int zip_register_cancel_callback_with_state(zip_t * _Nonnull, zip_cancel_callback _Nullable, void (* _Nullable)(void * _Nullable), void * _Nullable); -ZIP_EXTERN int zip_set_archive_comment(zip_t * _Nonnull, const char * _Nullable, zip_uint16_t); -ZIP_EXTERN int zip_set_archive_flag(zip_t * _Nonnull, zip_flags_t, int); -ZIP_EXTERN int zip_set_default_password(zip_t * _Nonnull, const char * _Nullable); -ZIP_EXTERN int zip_set_file_compression(zip_t * _Nonnull, zip_uint64_t, zip_int32_t, zip_uint32_t); -ZIP_EXTERN int zip_source_begin_write(zip_source_t * _Nonnull); -ZIP_EXTERN int zip_source_begin_write_cloning(zip_source_t * _Nonnull, zip_uint64_t); -ZIP_EXTERN zip_source_t * _Nullable zip_source_buffer(zip_t * _Nonnull, const void * _Nullable, zip_uint64_t, int); -ZIP_EXTERN zip_source_t * _Nullable zip_source_buffer_create(const void * _Nullable, zip_uint64_t, int, zip_error_t * _Nullable); -ZIP_EXTERN zip_source_t * _Nullable zip_source_buffer_fragment(zip_t * _Nonnull, const zip_buffer_fragment_t * _Nonnull, zip_uint64_t, int); -ZIP_EXTERN zip_source_t * _Nullable zip_source_buffer_fragment_create(const zip_buffer_fragment_t * _Nullable, zip_uint64_t, int, zip_error_t * _Nullable); -ZIP_EXTERN int zip_source_close(zip_source_t * _Nonnull); -ZIP_EXTERN int zip_source_commit_write(zip_source_t * _Nonnull); -ZIP_EXTERN zip_error_t * _Nonnull zip_source_error(zip_source_t * _Nonnull); -ZIP_EXTERN zip_source_t * _Nullable zip_source_file(zip_t * _Nonnull, const char * _Nonnull, zip_uint64_t, zip_int64_t); -ZIP_EXTERN zip_source_t * _Nullable zip_source_file_create(const char * _Nonnull, zip_uint64_t, zip_int64_t, zip_error_t * _Nullable); -ZIP_EXTERN zip_source_t * _Nullable zip_source_filep(zip_t * _Nonnull, FILE * _Nonnull, zip_uint64_t, zip_int64_t); -ZIP_EXTERN zip_source_t * _Nullable zip_source_filep_create(FILE * _Nonnull, zip_uint64_t, zip_int64_t, zip_error_t * _Nullable); -ZIP_EXTERN void zip_source_free(zip_source_t * _Nullable); -ZIP_EXTERN zip_source_t * _Nullable zip_source_function(zip_t * _Nonnull, zip_source_callback _Nonnull , void * _Nullable); -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_is_deleted(zip_source_t * _Nonnull); -ZIP_EXTERN void zip_source_keep(zip_source_t * _Nonnull); +ZIP_EXTERN int zip_close(zip_t *_Nonnull); +ZIP_EXTERN int zip_delete(zip_t *_Nonnull, zip_uint64_t); +ZIP_EXTERN zip_int64_t zip_dir_add(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t); +ZIP_EXTERN void zip_discard(zip_t *_Nonnull); + +ZIP_EXTERN zip_error_t *_Nonnull zip_get_error(zip_t *_Nonnull); +ZIP_EXTERN void zip_error_clear(zip_t *_Nonnull); +ZIP_EXTERN int zip_error_code_zip(const zip_error_t *_Nonnull); +ZIP_EXTERN int zip_error_code_system(const zip_error_t *_Nonnull); +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 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); + +ZIP_EXTERN int zip_fclose(zip_file_t *_Nonnull); +ZIP_EXTERN zip_t *_Nullable zip_fdopen(int, int, int *_Nullable); +ZIP_EXTERN zip_int64_t zip_file_add(zip_t *_Nonnull, const char *_Nonnull, zip_source_t *_Nonnull, zip_flags_t); +ZIP_EXTERN void zip_file_attributes_init(zip_file_attributes_t *_Nonnull); +ZIP_EXTERN void zip_file_error_clear(zip_file_t *_Nonnull); +ZIP_EXTERN int zip_file_extra_field_delete(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_flags_t); +ZIP_EXTERN int zip_file_extra_field_delete_by_id(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_flags_t); +ZIP_EXTERN int zip_file_extra_field_set(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, const zip_uint8_t *_Nullable, zip_uint16_t, zip_flags_t); +ZIP_EXTERN zip_int16_t zip_file_extra_fields_count(zip_t *_Nonnull, zip_uint64_t, zip_flags_t); +ZIP_EXTERN zip_int16_t zip_file_extra_fields_count_by_id(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_flags_t); +ZIP_EXTERN const zip_uint8_t *_Nullable zip_file_extra_field_get(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t *_Nullable, zip_uint16_t *_Nullable, zip_flags_t); +ZIP_EXTERN const zip_uint8_t *_Nullable zip_file_extra_field_get_by_id(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_uint16_t *_Nullable, zip_flags_t); +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_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); +ZIP_EXTERN int zip_file_set_dostime(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_flags_t); +ZIP_EXTERN int zip_file_set_encryption(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, const char *_Nullable); +ZIP_EXTERN int zip_file_set_external_attributes(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint8_t, zip_uint32_t); +ZIP_EXTERN int zip_file_set_mtime(zip_t *_Nonnull, zip_uint64_t, time_t, zip_flags_t); +ZIP_EXTERN const char *_Nonnull zip_file_strerror(zip_file_t *_Nonnull); +ZIP_EXTERN zip_file_t *_Nullable zip_fopen(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t); +ZIP_EXTERN zip_file_t *_Nullable zip_fopen_encrypted(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t, const char *_Nullable); +ZIP_EXTERN zip_file_t *_Nullable zip_fopen_index(zip_t *_Nonnull, zip_uint64_t, zip_flags_t); +ZIP_EXTERN zip_file_t *_Nullable zip_fopen_index_encrypted(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, const char *_Nullable); +ZIP_EXTERN zip_int64_t zip_fread(zip_file_t *_Nonnull, void *_Nonnull, zip_uint64_t); +ZIP_EXTERN zip_int8_t zip_fseek(zip_file_t *_Nonnull, zip_int64_t, int); +ZIP_EXTERN zip_int64_t zip_ftell(zip_file_t *_Nonnull); +ZIP_EXTERN const char *_Nullable zip_get_archive_comment(zip_t *_Nonnull, int *_Nullable, zip_flags_t); +ZIP_EXTERN int zip_get_archive_flag(zip_t *_Nonnull, zip_flags_t, zip_flags_t); +ZIP_EXTERN const char *_Nullable zip_get_name(zip_t *_Nonnull, zip_uint64_t, zip_flags_t); +ZIP_EXTERN zip_int64_t zip_get_num_entries(zip_t *_Nonnull, zip_flags_t); +ZIP_EXTERN const char *_Nonnull zip_libzip_version(void); +ZIP_EXTERN zip_int64_t zip_name_locate(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t); +ZIP_EXTERN zip_t *_Nullable zip_open(const char *_Nonnull, int, int *_Nullable); +ZIP_EXTERN zip_t *_Nullable zip_open_from_source(zip_source_t *_Nonnull, int, zip_error_t *_Nullable); +ZIP_EXTERN int zip_register_progress_callback_with_state(zip_t *_Nonnull, double, zip_progress_callback _Nullable, void (*_Nullable)(void *_Nullable), void *_Nullable); +ZIP_EXTERN int zip_register_cancel_callback_with_state(zip_t *_Nonnull, zip_cancel_callback _Nullable, void (*_Nullable)(void *_Nullable), void *_Nullable); +ZIP_EXTERN int zip_set_archive_comment(zip_t *_Nonnull, const char *_Nullable, zip_uint16_t); +ZIP_EXTERN int zip_set_archive_flag(zip_t *_Nonnull, zip_flags_t, int); +ZIP_EXTERN int zip_set_default_password(zip_t *_Nonnull, const char *_Nullable); +ZIP_EXTERN int zip_set_file_compression(zip_t *_Nonnull, zip_uint64_t, zip_int32_t, zip_uint32_t); +ZIP_EXTERN int zip_source_begin_write(zip_source_t *_Nonnull); +ZIP_EXTERN int zip_source_begin_write_cloning(zip_source_t *_Nonnull, zip_uint64_t); +ZIP_EXTERN zip_source_t *_Nullable zip_source_buffer(zip_t *_Nonnull, const void *_Nullable, zip_uint64_t, int); +ZIP_EXTERN zip_source_t *_Nullable zip_source_buffer_create(const void *_Nullable, zip_uint64_t, int, zip_error_t *_Nullable); +ZIP_EXTERN zip_source_t *_Nullable zip_source_buffer_fragment(zip_t *_Nonnull, const zip_buffer_fragment_t *_Nonnull, zip_uint64_t, int); +ZIP_EXTERN zip_source_t *_Nullable zip_source_buffer_fragment_create(const zip_buffer_fragment_t *_Nullable, zip_uint64_t, int, zip_error_t *_Nullable); +ZIP_EXTERN int zip_source_close(zip_source_t *_Nonnull); +ZIP_EXTERN int zip_source_commit_write(zip_source_t *_Nonnull); +ZIP_EXTERN zip_error_t *_Nonnull zip_source_error(zip_source_t *_Nonnull); +ZIP_EXTERN zip_source_t *_Nullable zip_source_file(zip_t *_Nonnull, const char *_Nonnull, zip_uint64_t, zip_int64_t); +ZIP_EXTERN zip_source_t *_Nullable zip_source_file_create(const char *_Nonnull, zip_uint64_t, zip_int64_t, zip_error_t *_Nullable); +ZIP_EXTERN zip_source_t *_Nullable zip_source_filep(zip_t *_Nonnull, FILE *_Nonnull, zip_uint64_t, zip_int64_t); +ZIP_EXTERN zip_source_t *_Nullable zip_source_filep_create(FILE *_Nonnull, zip_uint64_t, zip_int64_t, zip_error_t *_Nullable); +ZIP_EXTERN void zip_source_free(zip_source_t *_Nullable); +ZIP_EXTERN zip_source_t *_Nullable zip_source_function(zip_t *_Nonnull, zip_source_callback _Nonnull, void *_Nullable); +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 void zip_source_keep(zip_source_t *_Nonnull); 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_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); -ZIP_EXTERN zip_int64_t zip_source_seek_compute_offset(zip_uint64_t, zip_uint64_t, void * _Nonnull, zip_uint64_t, zip_error_t * _Nullable); -ZIP_EXTERN int zip_source_seek_write(zip_source_t * _Nonnull, zip_int64_t, int); -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); +ZIP_EXTERN int zip_source_open(zip_source_t *_Nonnull); +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); +ZIP_EXTERN zip_int64_t zip_source_seek_compute_offset(zip_uint64_t, zip_uint64_t, void *_Nonnull, zip_uint64_t, zip_error_t *_Nullable); +ZIP_EXTERN int zip_source_seek_write(zip_source_t *_Nonnull, zip_int64_t, int); +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 *); @@ -439,15 +460,17 @@ ZIP_EXTERN zip_source_t *zip_source_win32handle_create(void *, zip_uint64_t, zip 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 *); #endif -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 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); -ZIP_EXTERN const char * _Nonnull zip_strerror(zip_t * _Nonnull); -ZIP_EXTERN int zip_unchange(zip_t * _Nonnull, zip_uint64_t); -ZIP_EXTERN int zip_unchange_all(zip_t * _Nonnull); -ZIP_EXTERN int zip_unchange_archive(zip_t * _Nonnull); +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 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); +ZIP_EXTERN const char *_Nonnull zip_strerror(zip_t *_Nonnull); +ZIP_EXTERN int zip_unchange(zip_t *_Nonnull, zip_uint64_t); +ZIP_EXTERN int zip_unchange_all(zip_t *_Nonnull); +ZIP_EXTERN int zip_unchange_archive(zip_t *_Nonnull); +ZIP_EXTERN int zip_compression_method_supported(zip_int32_t method, int compress); +ZIP_EXTERN int zip_encryption_method_supported(zip_uint16_t method, int encode); #ifdef __cplusplus } diff --git a/Sources/libzip/include/zipconf.h b/Sources/libzip/include/zipconf.h index 7aed508..eb13aee 100644 --- a/Sources/libzip/include/zipconf.h +++ b/Sources/libzip/include/zipconf.h @@ -8,18 +8,26 @@ based on ../cmake-zipconf.h.in. */ -#define LIBZIP_VERSION "1.6.1" +#define LIBZIP_VERSION "1.7.3" #define LIBZIP_VERSION_MAJOR 1 -#define LIBZIP_VERSION_MINOR 6 -#define LIBZIP_VERSION_MICRO 1 +#define LIBZIP_VERSION_MINOR 7 +#define LIBZIP_VERSION_MICRO 3 /* #undef ZIP_STATIC */ +#if __linux__ +#define _Nullable +#define _Nonnull +#endif - +#if !defined(__STDC_FORMAT_MACROS) #define __STDC_FORMAT_MACROS 1 +#endif #include + +#if __linux__ #include +#endif typedef int8_t zip_int8_t; typedef uint8_t zip_uint8_t; @@ -30,20 +38,20 @@ 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_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_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_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 +#define ZIP_INT64_MIN (-ZIP_INT64_MAX - 1LL) +#define ZIP_INT64_MAX 0x7fffffffffffffffLL +#define ZIP_UINT64_MAX 0xffffffffffffffffULL #endif /* zipconf.h */ diff --git a/Sources/libzip/private_include/config.h b/Sources/libzip/private_include/config.h deleted file mode 100644 index 96331e6..0000000 --- a/Sources/libzip/private_include/config.h +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef HAD_CONFIG_H -#define HAD_CONFIG_H -#ifndef _HAD_ZIPCONF_H -#include "zipconf.h" -#endif - -/* BEGIN DEFINES */ -#if __APPLE__ - -#define HAVE_ARC4RANDOM -#define HAVE_CLONEFILE -#define HAVE_COMMONCRYPTO -#define HAVE_CRYPTO -#define HAVE_FILENO -#define HAVE_FSEEKO -#define HAVE_FTELLO -#define HAVE_GETPROGNAME -#define HAVE_LIBBZ2 -#define HAVE_LOCALTIME_R -#define HAVE_NULLABLE -#define HAVE_OPEN -#define HAVE_SETMODE -#define HAVE_SNPRINTF -#define HAVE_SSIZE_T_LIBZIP -#define HAVE_STRCASECMP -#define HAVE_STRDUP -#define HAVE_STRTOLL -#define HAVE_STRTOULL -#define HAVE_STDBOOL_H -#define HAVE_STRINGS_H -#define HAVE_UNISTD_H -#define INT8_T_LIBZIP 1 -#define UINT8_T_LIBZIP 1 -#define INT16_T_LIBZIP 2 -#define UINT16_T_LIBZIP 2 -#define INT32_T_LIBZIP 4 -#define UINT32_T_LIBZIP 4 -#define INT64_T_LIBZIP 8 -#define UINT64_T_LIBZIP 8 -#define SHORT_LIBZIP 2 -#define INT_LIBZIP 4 -#define LONG_LIBZIP 8 -#define LONG_LONG_LIBZIP 8 -#define SIZEOF_OFF_T 8 -#define SIZE_T_LIBZIP 8 -#define SSIZE_T_LIBZIP 8 -#define HAVE_FTS_H -#define HAVE_SHARED - -#else - -#define HAVE_CRYPTO -#define HAVE_FICLONERANGE -#define HAVE_FILENO -#define HAVE_FSEEKO -#define HAVE_FTELLO -#define HAVE_LOCALTIME_R -#define HAVE_NULLABLE -#define HAVE_OPEN -#define HAVE_OPENSSL -#define HAVE_SNPRINTF -#define HAVE_SSIZE_T_LIBZIP -#define HAVE_STRCASECMP -#define HAVE_STRDUP -#define HAVE_STRTOLL -#define HAVE_STRTOULL -#define HAVE_STDBOOL_H -#define HAVE_STRINGS_H -#define HAVE_UNISTD_H -#define INT8_T_LIBZIP 1 -#define UINT8_T_LIBZIP 1 -#define INT16_T_LIBZIP 2 -#define UINT16_T_LIBZIP 2 -#define INT32_T_LIBZIP 4 -#define UINT32_T_LIBZIP 4 -#define INT64_T_LIBZIP 8 -#define UINT64_T_LIBZIP 8 -#define SHORT_LIBZIP 2 -#define INT_LIBZIP 4 -#define LONG_LIBZIP 8 -#define LONG_LONG_LIBZIP 8 -#define SIZEOF_OFF_T 8 -#define SIZE_T_LIBZIP 8 -#define SSIZE_T_LIBZIP 8 -#define HAVE_FTS_H -#define HAVE_SHARED - -#endif -/* END DEFINES */ - - -#define PACKAGE "libzip" -#define VERSION "1.6.1a" - -#ifndef HAVE_SSIZE_T_LIBZIP -# if SIZE_T_LIBZIP == INT_LIBZIP -typedef int ssize_t; -# elif SIZE_T_LIBZIP == LONG_LIBZIP -typedef long ssize_t; -# elif SIZE_T_LIBZIP == LONG_LONG_LIBZIP -typedef long long ssize_t; -# else -#error no suitable type for ssize_t found -# endif -#endif - -#endif /* HAD_CONFIG_H */ diff --git a/Sources/libzip/private_include/darwin/config.h b/Sources/libzip/private_include/darwin/config.h new file mode 100644 index 0000000..5dd47be --- /dev/null +++ b/Sources/libzip/private_include/darwin/config.h @@ -0,0 +1,62 @@ +#ifndef HAD_CONFIG_H +#define HAD_CONFIG_H +#ifndef _HAD_ZIPCONF_H +#include "zipconf.h" +#endif +/* BEGIN DEFINES */ +/* #undef HAVE___PROGNAME */ +/* #undef HAVE__CLOSE */ +/* #undef HAVE__DUP */ +/* #undef HAVE__FDOPEN */ +/* #undef HAVE__FILENO */ +/* #undef HAVE__SETMODE */ +/* #undef HAVE__SNPRINTF */ +/* #undef HAVE__STRDUP */ +/* #undef HAVE__STRICMP */ +/* #undef HAVE__STRTOI64 */ +/* #undef HAVE__STRTOUI64 */ +/* #undef HAVE__UMASK */ +/* #undef HAVE__UNLINK */ +#define HAVE_ARC4RANDOM +#define HAVE_CLONEFILE +#define HAVE_COMMONCRYPTO +#define HAVE_CRYPTO +/* #undef HAVE_FICLONERANGE */ +#define HAVE_FILENO +#define HAVE_FSEEKO +#define HAVE_FTELLO +#define HAVE_GETPROGNAME +/* #undef HAVE_GNUTLS */ +#define HAVE_LIBBZ2 +//#define HAVE_LIBLZMA +#define HAVE_LOCALTIME_R +/* #undef HAVE_MBEDTLS */ +/* #undef HAVE_MKSTEMP */ +#define HAVE_NULLABLE +/* #undef HAVE_OPENSSL */ +#define HAVE_SETMODE +#define HAVE_SNPRINTF +#define HAVE_STRCASECMP +#define HAVE_STRDUP +/* #undef HAVE_STRICMP */ +#define HAVE_STRTOLL +#define HAVE_STRTOULL +/* #undef HAVE_STRUCT_TM_TM_ZONE */ +#define HAVE_STDBOOL_H +#define HAVE_STRINGS_H +#define HAVE_UNISTD_H +/* #undef HAVE_WINDOWS_CRYPTO */ +#define SIZEOF_OFF_T 8 +#define SIZEOF_SIZE_T 8 +/* #undef HAVE_DIRENT_H */ +#define 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" + +#endif /* HAD_CONFIG_H */ diff --git a/Sources/libzip/private_include/linux/config.h b/Sources/libzip/private_include/linux/config.h new file mode 100644 index 0000000..6d0bb6e --- /dev/null +++ b/Sources/libzip/private_include/linux/config.h @@ -0,0 +1,62 @@ +#ifndef HAD_CONFIG_H +#define HAD_CONFIG_H +#ifndef _HAD_ZIPCONF_H +#include "zipconf.h" +#endif +/* BEGIN DEFINES */ +/* #undef HAVE___PROGNAME */ +/* #undef HAVE__CLOSE */ +/* #undef HAVE__DUP */ +/* #undef HAVE__FDOPEN */ +/* #undef HAVE__FILENO */ +/* #undef HAVE__SETMODE */ +/* #undef HAVE__SNPRINTF */ +/* #undef HAVE__STRDUP */ +/* #undef HAVE__STRICMP */ +/* #undef HAVE__STRTOI64 */ +/* #undef HAVE__STRTOUI64 */ +/* #undef HAVE__UMASK */ +/* #undef HAVE__UNLINK */ +/* #undef HAVE_ARC4RANDOM */ +/* #undef HAVE_CLONEFILE */ +/* #undef HAVE_COMMONCRYPTO */ +#define HAVE_CRYPTO +#define HAVE_FICLONERANGE +#define HAVE_FILENO +#define HAVE_FSEEKO +#define HAVE_FTELLO +/* #undef HAVE_GETPROGNAME */ +/* #undef HAVE_GNUTLS */ +#define HAVE_LIBBZ2 +#define HAVE_LIBLZMA +#define HAVE_LOCALTIME_R +/* #undef HAVE_MBEDTLS */ +/* #undef HAVE_MKSTEMP */ +/* #undef HAVE_NULLABLE */ +#define HAVE_OPENSSL +/* #undef HAVE_SETMODE */ +#define HAVE_SNPRINTF +#define HAVE_STRCASECMP +#define HAVE_STRDUP +/* #undef HAVE_STRICMP */ +#define HAVE_STRTOLL +#define HAVE_STRTOULL +/* #undef HAVE_STRUCT_TM_TM_ZONE */ +#define HAVE_STDBOOL_H +#define HAVE_STRINGS_H +#define HAVE_UNISTD_H +/* #undef HAVE_WINDOWS_CRYPTO */ +#define SIZEOF_OFF_T 8 +#define SIZEOF_SIZE_T 8 +/* #undef HAVE_DIRENT_H */ +#define 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 "" + +#endif /* HAD_CONFIG_H */ diff --git a/Sources/libzip/src/compat.h b/Sources/libzip/src/compat.h index 2f05bf0..a5cf728 100644 --- a/Sources/libzip/src/compat.h +++ b/Sources/libzip/src/compat.h @@ -36,9 +36,7 @@ #include "zipconf.h" -#ifdef HAVE_CONFIG_H #include "config.h" -#endif /* to have *_MAX definitions for all types when compiling with g++ */ #define __STDC_LIMIT_MACROS @@ -83,9 +81,6 @@ typedef char bool; #endif #ifdef _WIN32 -#if defined(HAVE__CHMOD) -#define chmod _chmod -#endif #if defined(HAVE__CLOSE) #define close _close #endif @@ -99,10 +94,6 @@ typedef char bool; #if !defined(HAVE_FILENO) && defined(HAVE__FILENO) #define fileno _fileno #endif -/* Windows' open() doesn't understand Unix permissions */ -#if defined(HAVE__OPEN) -#define open(a, b, c) _open((a), (b)) -#endif #if defined(HAVE__SNPRINTF) #define snprintf _snprintf #endif diff --git a/Sources/libzip/src/zip.h b/Sources/libzip/src/zip.h deleted file mode 100644 index 018c948..0000000 --- a/Sources/libzip/src/zip.h +++ /dev/null @@ -1,456 +0,0 @@ -#ifndef _HAD_ZIP_H -#define _HAD_ZIP_H - -/* - zip.h -- exported declarations. - 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. -*/ - - -#ifdef __cplusplus -extern "C" { -#if 0 -} /* fix autoindent */ -#endif -#endif - -#include - -#ifndef ZIP_EXTERN -#ifndef ZIP_STATIC -#ifdef _WIN32 -#define ZIP_EXTERN __declspec(dllimport) -#elif defined(__GNUC__) && __GNUC__ >= 4 -#define ZIP_EXTERN __attribute__((visibility("default"))) -#else -#define ZIP_EXTERN -#endif -#else -#define ZIP_EXTERN -#endif -#endif - -#include -#include -#include - -/* flags for zip_open */ - -#define ZIP_CREATE 1 -#define ZIP_EXCL 2 -#define ZIP_CHECKCONS 4 -#define ZIP_TRUNCATE 8 -#define ZIP_RDONLY 16 - - -/* flags for zip_name_locate, zip_fopen, zip_stat, ... */ - -#define ZIP_FL_NOCASE 1u /* ignore case on name lookup */ -#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 */ -#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 */ -#define ZIP_FL_ENC_STRICT 128u /* follow specification strictly */ -#define ZIP_FL_LOCAL 256u /* in local header */ -#define ZIP_FL_CENTRAL 512u /* in central directory */ -/* 1024u reserved for internal use */ -#define ZIP_FL_ENC_UTF_8 2048u /* string is UTF-8 encoded */ -#define ZIP_FL_ENC_CP437 4096u /* string is CP437 encoded */ -#define ZIP_FL_OVERWRITE 8192u /* zip_file_add: if file with name exists, overwrite (replace) it */ - -/* archive global flags flags */ - -#define ZIP_AFL_RDONLY 2u /* read only -- cannot be cleared */ - - -/* create a new extra field */ - -#define ZIP_EXTRA_FIELD_ALL ZIP_UINT16_MAX -#define ZIP_EXTRA_FIELD_NEW ZIP_UINT16_MAX - - -/* libzip error codes */ - -#define ZIP_ER_OK 0 /* N No error */ -#define ZIP_ER_MULTIDISK 1 /* N Multi-disk zip archives not supported */ -#define ZIP_ER_RENAME 2 /* S Renaming temporary file failed */ -#define ZIP_ER_CLOSE 3 /* S Closing zip archive failed */ -#define ZIP_ER_SEEK 4 /* S Seek error */ -#define ZIP_ER_READ 5 /* S Read error */ -#define ZIP_ER_WRITE 6 /* S Write error */ -#define ZIP_ER_CRC 7 /* N CRC error */ -#define ZIP_ER_ZIPCLOSED 8 /* N Containing zip archive was closed */ -#define ZIP_ER_NOENT 9 /* N No such file */ -#define ZIP_ER_EXISTS 10 /* N File already exists */ -#define ZIP_ER_OPEN 11 /* S Can't open file */ -#define ZIP_ER_TMPOPEN 12 /* S Failure to create temporary file */ -#define ZIP_ER_ZLIB 13 /* Z Zlib error */ -#define ZIP_ER_MEMORY 14 /* N Malloc failure */ -#define ZIP_ER_CHANGED 15 /* N Entry has been changed */ -#define ZIP_ER_COMPNOTSUPP 16 /* N Compression method not supported */ -#define ZIP_ER_EOF 17 /* N Premature end of file */ -#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_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 */ -#define ZIP_ER_RDONLY 25 /* N Read-only archive */ -#define ZIP_ER_NOPASSWD 26 /* N No password provided */ -#define ZIP_ER_WRONGPASSWD 27 /* N Wrong password provided */ -#define ZIP_ER_OPNOTSUPP 28 /* N Operation not supported */ -#define ZIP_ER_INUSE 29 /* N Resource still in use */ -#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 */ - -/* 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 */ - -/* compression methods */ - -#define ZIP_CM_DEFAULT -1 /* better of deflate or store */ -#define ZIP_CM_STORE 0 /* stored (uncompressed) */ -#define ZIP_CM_SHRINK 1 /* shrunk */ -#define ZIP_CM_REDUCE_1 2 /* reduced with factor 1 */ -#define ZIP_CM_REDUCE_2 3 /* reduced with factor 2 */ -#define ZIP_CM_REDUCE_3 4 /* reduced with factor 3 */ -#define ZIP_CM_REDUCE_4 5 /* reduced with factor 4 */ -#define ZIP_CM_IMPLODE 6 /* imploded */ -/* 7 - Reserved for Tokenizing compression algorithm */ -#define ZIP_CM_DEFLATE 8 /* deflated */ -#define ZIP_CM_DEFLATE64 9 /* deflate64 */ -#define ZIP_CM_PKWARE_IMPLODE 10 /* PKWARE imploding */ -/* 11 - Reserved by PKWARE */ -#define ZIP_CM_BZIP2 12 /* compressed using BZIP2 algorithm */ -/* 13 - Reserved by PKWARE */ -#define ZIP_CM_LZMA 14 /* LZMA (EFS) */ -/* 15-17 - Reserved by PKWARE */ -#define ZIP_CM_TERSE 18 /* compressed using IBM TERSE (new) */ -#define ZIP_CM_LZ77 19 /* IBM LZ77 z Architecture (PFS) */ -#define ZIP_CM_LZMA2 33 -#define ZIP_CM_XZ 95 /* XZ compressed data */ -#define ZIP_CM_JPEG 96 /* Compressed Jpeg data */ -#define ZIP_CM_WAVPACK 97 /* WavPack compressed data */ -#define ZIP_CM_PPMD 98 /* PPMd version I, Rev 1 */ - -/* encryption methods */ - -#define ZIP_EM_NONE 0 /* not encrypted */ -#define ZIP_EM_TRAD_PKWARE 1 /* traditional PKWARE encryption */ -#if 0 /* Strong Encryption Header not parsed yet */ -#define ZIP_EM_DES 0x6601 /* strong encryption: DES */ -#define ZIP_EM_RC2_OLD 0x6602 /* strong encryption: RC2, version < 5.2 */ -#define ZIP_EM_3DES_168 0x6603 -#define ZIP_EM_3DES_112 0x6609 -#define ZIP_EM_PKZIP_AES_128 0x660e -#define ZIP_EM_PKZIP_AES_192 0x660f -#define ZIP_EM_PKZIP_AES_256 0x6610 -#define ZIP_EM_RC2 0x6702 /* strong encryption: RC2, version >= 5.2 */ -#define ZIP_EM_RC4 0x6801 -#endif -#define ZIP_EM_AES_128 0x0101 /* Winzip AES encryption */ -#define ZIP_EM_AES_192 0x0102 -#define ZIP_EM_AES_256 0x0103 -#define ZIP_EM_UNKNOWN 0xffff /* unknown algorithm */ - -#define ZIP_OPSYS_DOS 0x00u -#define ZIP_OPSYS_AMIGA 0x01u -#define ZIP_OPSYS_OPENVMS 0x02u -#define ZIP_OPSYS_UNIX 0x03u -#define ZIP_OPSYS_VM_CMS 0x04u -#define ZIP_OPSYS_ATARI_ST 0x05u -#define ZIP_OPSYS_OS_2 0x06u -#define ZIP_OPSYS_MACINTOSH 0x07u -#define ZIP_OPSYS_Z_SYSTEM 0x08u -#define ZIP_OPSYS_CPM 0x09u -#define ZIP_OPSYS_WINDOWS_NTFS 0x0au -#define ZIP_OPSYS_MVS 0x0bu -#define ZIP_OPSYS_VSE 0x0cu -#define ZIP_OPSYS_ACORN_RISC 0x0du -#define ZIP_OPSYS_VFAT 0x0eu -#define ZIP_OPSYS_ALTERNATE_MVS 0x0fu -#define ZIP_OPSYS_BEOS 0x10u -#define ZIP_OPSYS_TANDEM 0x11u -#define ZIP_OPSYS_OS_400 0x12u -#define ZIP_OPSYS_OS_X 0x13u - -#define ZIP_OPSYS_DEFAULT ZIP_OPSYS_UNIX - - -enum zip_source_cmd { - ZIP_SOURCE_OPEN, /* prepare for reading */ - ZIP_SOURCE_READ, /* read data */ - ZIP_SOURCE_CLOSE, /* reading is done */ - ZIP_SOURCE_STAT, /* get meta information */ - ZIP_SOURCE_ERROR, /* get error information */ - ZIP_SOURCE_FREE, /* cleanup and free resources */ - ZIP_SOURCE_SEEK, /* set position for reading */ - ZIP_SOURCE_TELL, /* get read position */ - ZIP_SOURCE_BEGIN_WRITE, /* prepare for writing */ - ZIP_SOURCE_COMMIT_WRITE, /* writing is done */ - ZIP_SOURCE_ROLLBACK_WRITE, /* discard written changes */ - ZIP_SOURCE_WRITE, /* write data */ - ZIP_SOURCE_SEEK_WRITE, /* set position for writing */ - ZIP_SOURCE_TELL_WRITE, /* get write position */ - ZIP_SOURCE_SUPPORTS, /* check whether source supports command */ - ZIP_SOURCE_REMOVE, /* remove file */ - ZIP_SOURCE_GET_COMPRESSION_FLAGS, /* get compression flags, internal only */ - 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 */ -}; -typedef enum zip_source_cmd zip_source_cmd_t; - -#define ZIP_SOURCE_MAKE_COMMAND_BITMASK(cmd) (((zip_int64_t)1) << (cmd)) - -/* clang-format off */ - -#define ZIP_SOURCE_SUPPORTS_READABLE (ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_OPEN) \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_READ) \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_CLOSE) \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_STAT) \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ERROR) \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_FREE)) - -#define ZIP_SOURCE_SUPPORTS_SEEKABLE (ZIP_SOURCE_SUPPORTS_READABLE \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK) \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_TELL) \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SUPPORTS)) - -#define ZIP_SOURCE_SUPPORTS_WRITABLE (ZIP_SOURCE_SUPPORTS_SEEKABLE \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE) \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_COMMIT_WRITE) \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ROLLBACK_WRITE) \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_WRITE) \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK_WRITE) \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_TELL_WRITE) \ - | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_REMOVE)) - -/* clang-format on */ - -/* for use by sources */ -struct zip_source_args_seek { - zip_int64_t offset; - int whence; -}; - -typedef struct zip_source_args_seek zip_source_args_seek_t; -#define ZIP_SOURCE_GET_ARGS(type, data, len, error) ((len) < sizeof(type) ? zip_error_set((error), ZIP_ER_INVAL, 0), (type *)NULL : (type *)(data)) - - -/* error information */ -/* use zip_error_*() to access */ -struct zip_error { - int zip_err; /* libzip error code (ZIP_ER_*) */ - int sys_err; /* copy of errno (E*) or zlib error code */ - char * _Nullable str; /* string representation or NULL */ -}; - -#define ZIP_STAT_NAME 0x0001u -#define ZIP_STAT_INDEX 0x0002u -#define ZIP_STAT_SIZE 0x0004u -#define ZIP_STAT_COMP_SIZE 0x0008u -#define ZIP_STAT_MTIME 0x0010u -#define ZIP_STAT_CRC 0x0020u -#define ZIP_STAT_COMP_METHOD 0x0040u -#define ZIP_STAT_ENCRYPTION_METHOD 0x0080u -#define ZIP_STAT_FLAGS 0x0100u - -struct zip_stat { - zip_uint64_t valid; /* which fields have valid values */ - const char * _Nullable name; /* name of the file */ - zip_uint64_t index; /* index within archive */ - zip_uint64_t size; /* size of file (uncompressed) */ - zip_uint64_t comp_size; /* size of file (compressed) */ - time_t mtime; /* modification time */ - zip_uint32_t crc; /* crc of file data */ - zip_uint16_t comp_method; /* compression method used */ - zip_uint16_t encryption_method; /* encryption method used */ - zip_uint32_t flags; /* reserved for future use */ -}; - -struct zip_buffer_fragment { - zip_uint8_t * _Nonnull data; - zip_uint64_t length; -}; - -struct zip; -struct zip_file; -struct zip_source; - -typedef struct zip zip_t; -typedef struct zip_error zip_error_t; -typedef struct zip_file zip_file_t; -typedef struct zip_source zip_source_t; -typedef struct zip_stat zip_stat_t; -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 void (*zip_progress_callback)(zip_t * _Nonnull, double, void * _Nullable); -typedef int (*zip_cancel_callback)(zip_t * _Nonnull, void * _Nullable); - -#ifndef ZIP_DISABLE_DEPRECATED -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 */ -#endif - -ZIP_EXTERN int zip_close(zip_t * _Nonnull); -ZIP_EXTERN int zip_delete(zip_t * _Nonnull, zip_uint64_t); -ZIP_EXTERN zip_int64_t zip_dir_add(zip_t * _Nonnull, const char * _Nonnull, zip_flags_t); -ZIP_EXTERN void zip_discard(zip_t * _Nonnull); - -ZIP_EXTERN zip_error_t * _Nonnull zip_get_error(zip_t * _Nonnull); -ZIP_EXTERN void zip_error_clear(zip_t * _Nonnull); -ZIP_EXTERN int zip_error_code_zip(const zip_error_t * _Nonnull); -ZIP_EXTERN int zip_error_code_system(const zip_error_t * _Nonnull); -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 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); - -ZIP_EXTERN int zip_fclose(zip_file_t * _Nonnull); -ZIP_EXTERN zip_t * _Nullable zip_fdopen(int, int, int * _Nullable); -ZIP_EXTERN zip_int64_t zip_file_add(zip_t * _Nonnull, const char * _Nonnull, zip_source_t * _Nonnull, zip_flags_t); -ZIP_EXTERN void zip_file_error_clear(zip_file_t * _Nonnull); -ZIP_EXTERN int zip_file_extra_field_delete(zip_t * _Nonnull, zip_uint64_t, zip_uint16_t, zip_flags_t); -ZIP_EXTERN int zip_file_extra_field_delete_by_id(zip_t * _Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_flags_t); -ZIP_EXTERN int zip_file_extra_field_set(zip_t * _Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, const zip_uint8_t * _Nullable, zip_uint16_t, zip_flags_t); -ZIP_EXTERN zip_int16_t zip_file_extra_fields_count(zip_t * _Nonnull, zip_uint64_t, zip_flags_t); -ZIP_EXTERN zip_int16_t zip_file_extra_fields_count_by_id(zip_t * _Nonnull, zip_uint64_t, zip_uint16_t, zip_flags_t); -ZIP_EXTERN const zip_uint8_t * _Nullable zip_file_extra_field_get(zip_t * _Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t * _Nullable, zip_uint16_t * _Nullable, zip_flags_t); -ZIP_EXTERN const zip_uint8_t * _Nullable zip_file_extra_field_get_by_id(zip_t * _Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_uint16_t * _Nullable, zip_flags_t); -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_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); -ZIP_EXTERN int zip_file_set_dostime(zip_t * _Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_flags_t); -ZIP_EXTERN int zip_file_set_encryption(zip_t * _Nonnull, zip_uint64_t, zip_uint16_t, const char * _Nullable); -ZIP_EXTERN int zip_file_set_external_attributes(zip_t * _Nonnull, zip_uint64_t, zip_flags_t, zip_uint8_t, zip_uint32_t); -ZIP_EXTERN int zip_file_set_mtime(zip_t * _Nonnull, zip_uint64_t, time_t, zip_flags_t); -ZIP_EXTERN const char * _Nonnull zip_file_strerror(zip_file_t * _Nonnull); -ZIP_EXTERN zip_file_t * _Nullable zip_fopen(zip_t * _Nonnull, const char * _Nonnull, zip_flags_t); -ZIP_EXTERN zip_file_t * _Nullable zip_fopen_encrypted(zip_t * _Nonnull, const char * _Nonnull, zip_flags_t, const char * _Nullable); -ZIP_EXTERN zip_file_t * _Nullable zip_fopen_index(zip_t * _Nonnull, zip_uint64_t, zip_flags_t); -ZIP_EXTERN zip_file_t * _Nullable zip_fopen_index_encrypted(zip_t * _Nonnull, zip_uint64_t, zip_flags_t, const char * _Nullable); -ZIP_EXTERN zip_int64_t zip_fread(zip_file_t * _Nonnull, void * _Nonnull, zip_uint64_t); -ZIP_EXTERN zip_int8_t zip_fseek(zip_file_t * _Nonnull, zip_int64_t, int); -ZIP_EXTERN zip_int64_t zip_ftell(zip_file_t * _Nonnull); -ZIP_EXTERN const char * _Nullable zip_get_archive_comment(zip_t * _Nonnull, int * _Nullable, zip_flags_t); -ZIP_EXTERN int zip_get_archive_flag(zip_t * _Nonnull, zip_flags_t, zip_flags_t); -ZIP_EXTERN const char * _Nullable zip_get_name(zip_t * _Nonnull, zip_uint64_t, zip_flags_t); -ZIP_EXTERN zip_int64_t zip_get_num_entries(zip_t * _Nonnull, zip_flags_t); -ZIP_EXTERN const char * _Nonnull zip_libzip_version(void); -ZIP_EXTERN zip_int64_t zip_name_locate(zip_t * _Nonnull, const char * _Nonnull, zip_flags_t); -ZIP_EXTERN zip_t * _Nullable zip_open(const char * _Nonnull, int, int * _Nullable); -ZIP_EXTERN zip_t * _Nullable zip_open_from_source(zip_source_t * _Nonnull, int, zip_error_t * _Nullable); -ZIP_EXTERN int zip_register_progress_callback_with_state(zip_t * _Nonnull, double, zip_progress_callback _Nullable, void (* _Nullable)(void * _Nullable), void * _Nullable); -ZIP_EXTERN int zip_register_cancel_callback_with_state(zip_t * _Nonnull, zip_cancel_callback _Nullable, void (* _Nullable)(void * _Nullable), void * _Nullable); -ZIP_EXTERN int zip_set_archive_comment(zip_t * _Nonnull, const char * _Nullable, zip_uint16_t); -ZIP_EXTERN int zip_set_archive_flag(zip_t * _Nonnull, zip_flags_t, int); -ZIP_EXTERN int zip_set_default_password(zip_t * _Nonnull, const char * _Nullable); -ZIP_EXTERN int zip_set_file_compression(zip_t * _Nonnull, zip_uint64_t, zip_int32_t, zip_uint32_t); -ZIP_EXTERN int zip_source_begin_write(zip_source_t * _Nonnull); -ZIP_EXTERN int zip_source_begin_write_cloning(zip_source_t * _Nonnull, zip_uint64_t); -ZIP_EXTERN zip_source_t * _Nullable zip_source_buffer(zip_t * _Nonnull, const void * _Nullable, zip_uint64_t, int); -ZIP_EXTERN zip_source_t * _Nullable zip_source_buffer_create(const void * _Nullable, zip_uint64_t, int, zip_error_t * _Nullable); -ZIP_EXTERN zip_source_t * _Nullable zip_source_buffer_fragment(zip_t * _Nonnull, const zip_buffer_fragment_t * _Nonnull, zip_uint64_t, int); -ZIP_EXTERN zip_source_t * _Nullable zip_source_buffer_fragment_create(const zip_buffer_fragment_t * _Nullable, zip_uint64_t, int, zip_error_t * _Nullable); -ZIP_EXTERN int zip_source_close(zip_source_t * _Nonnull); -ZIP_EXTERN int zip_source_commit_write(zip_source_t * _Nonnull); -ZIP_EXTERN zip_error_t * _Nonnull zip_source_error(zip_source_t * _Nonnull); -ZIP_EXTERN zip_source_t * _Nullable zip_source_file(zip_t * _Nonnull, const char * _Nonnull, zip_uint64_t, zip_int64_t); -ZIP_EXTERN zip_source_t * _Nullable zip_source_file_create(const char * _Nonnull, zip_uint64_t, zip_int64_t, zip_error_t * _Nullable); -ZIP_EXTERN zip_source_t * _Nullable zip_source_filep(zip_t * _Nonnull, FILE * _Nonnull, zip_uint64_t, zip_int64_t); -ZIP_EXTERN zip_source_t * _Nullable zip_source_filep_create(FILE * _Nonnull, zip_uint64_t, zip_int64_t, zip_error_t * _Nullable); -ZIP_EXTERN void zip_source_free(zip_source_t * _Nullable); -ZIP_EXTERN zip_source_t * _Nullable zip_source_function(zip_t * _Nonnull, zip_source_callback _Nonnull , void * _Nullable); -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_is_deleted(zip_source_t * _Nonnull); -ZIP_EXTERN void zip_source_keep(zip_source_t * _Nonnull); -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_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); -ZIP_EXTERN zip_int64_t zip_source_seek_compute_offset(zip_uint64_t, zip_uint64_t, void * _Nonnull, zip_uint64_t, zip_error_t * _Nullable); -ZIP_EXTERN int zip_source_seek_write(zip_source_t * _Nonnull, zip_int64_t, int); -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 *); -#endif -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 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); -ZIP_EXTERN const char * _Nonnull zip_strerror(zip_t * _Nonnull); -ZIP_EXTERN int zip_unchange(zip_t * _Nonnull, zip_uint64_t); -ZIP_EXTERN int zip_unchange_all(zip_t * _Nonnull); -ZIP_EXTERN int zip_unchange_archive(zip_t * _Nonnull); - -#ifdef __cplusplus -} -#endif - -#endif /* _HAD_ZIP_H */ diff --git a/Sources/libzip/src/zip_algorithm_bzip2.c b/Sources/libzip/src/zip_algorithm_bzip2.c index a1d2898..a4f27e5 100644 --- a/Sources/libzip/src/zip_algorithm_bzip2.c +++ b/Sources/libzip/src/zip_algorithm_bzip2.c @@ -90,8 +90,8 @@ deallocate(void *ud) { } -static int -compression_flags(void *ud) { +static zip_uint16_t +general_purpose_bit_flags(void *ud) { return 0; } @@ -247,7 +247,8 @@ process(void *ud, zip_uint8_t *data, zip_uint64_t *length) { zip_compression_algorithm_t zip_algorithm_bzip2_compress = { compress_allocate, deallocate, - compression_flags, + general_purpose_bit_flags, + 46, start, end, input, @@ -259,7 +260,8 @@ zip_compression_algorithm_t zip_algorithm_bzip2_compress = { zip_compression_algorithm_t zip_algorithm_bzip2_decompress = { decompress_allocate, deallocate, - compression_flags, + general_purpose_bit_flags, + 46, start, end, input, diff --git a/Sources/libzip/src/zip_algorithm_deflate.c b/Sources/libzip/src/zip_algorithm_deflate.c index daf4a2c..d28a1ac 100644 --- a/Sources/libzip/src/zip_algorithm_deflate.c +++ b/Sources/libzip/src/zip_algorithm_deflate.c @@ -91,8 +91,8 @@ deallocate(void *ud) { } -static int -compression_flags(void *ud) { +static zip_uint16_t +general_purpose_bit_flags(void *ud) { struct ctx *ctx = (struct ctx *)ud; if (!ctx->compress) { @@ -100,10 +100,10 @@ compression_flags(void *ud) { } if (ctx->compression_flags < 3) { - return 2; + return 2 << 1; } else if (ctx->compression_flags > 7) { - return 1; + return 1 << 1; } return 0; } @@ -225,7 +225,8 @@ process(void *ud, zip_uint8_t *data, zip_uint64_t *length) { zip_compression_algorithm_t zip_algorithm_deflate_compress = { compress_allocate, deallocate, - compression_flags, + general_purpose_bit_flags, + 20, start, end, input, @@ -237,7 +238,8 @@ zip_compression_algorithm_t zip_algorithm_deflate_compress = { zip_compression_algorithm_t zip_algorithm_deflate_decompress = { decompress_allocate, deallocate, - compression_flags, + general_purpose_bit_flags, + 20, start, end, input, diff --git a/Sources/libzip/src/zip_algorithm_xz.c b/Sources/libzip/src/zip_algorithm_xz.c index 7edc089..945ab4e 100644 --- a/Sources/libzip/src/zip_algorithm_xz.c +++ b/Sources/libzip/src/zip_algorithm_xz.c @@ -35,13 +35,14 @@ #include "zipint.h" #include -#include #include +#include +#include struct ctx { zip_error_t *error; bool compress; - int compression_flags; + zip_uint32_t compression_flags; bool end_of_input; lzma_stream zstr; zip_uint16_t method; @@ -52,14 +53,19 @@ static void * allocate(bool compress, int compression_flags, zip_error_t *error, zip_uint16_t method) { struct ctx *ctx; + if (compression_flags < 0) { + zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + if ((ctx = (struct ctx *)malloc(sizeof(*ctx))) == NULL) { - zip_error_set(error, ZIP_ET_SYS, errno); + zip_error_set(error, ZIP_ER_MEMORY, 0); return NULL; } ctx->error = error; ctx->compress = compress; - ctx->compression_flags = compression_flags; + ctx->compression_flags = (zip_uint32_t)compression_flags; ctx->compression_flags |= LZMA_PRESET_EXTREME; ctx->end_of_input = false; memset(&ctx->zstr, 0, sizeof(ctx->zstr)); @@ -87,8 +93,8 @@ deallocate(void *ud) { } -static int -compression_flags(void *ud) { +static zip_uint16_t +general_purpose_bit_flags(void *ud) { /* struct ctx *ctx = (struct ctx *)ud; */ return 0; } @@ -96,17 +102,17 @@ compression_flags(void *ud) { static int map_error(lzma_ret ret) { switch (ret) { - case LZMA_UNSUPPORTED_CHECK: - return ZIP_ER_COMPRESSED_DATA; + case LZMA_UNSUPPORTED_CHECK: + return ZIP_ER_COMPRESSED_DATA; - case LZMA_MEM_ERROR: - return ZIP_ER_MEMORY; + case LZMA_MEM_ERROR: + return ZIP_ER_MEMORY; - case LZMA_OPTIONS_ERROR: - return ZIP_ER_INVAL; + case LZMA_OPTIONS_ERROR: + return ZIP_ER_INVAL; - default: - return ZIP_ER_INTERNAL; + default: + return ZIP_ER_INTERNAL; } } @@ -119,8 +125,8 @@ start(void *ud) { lzma_options_lzma opt_lzma; lzma_lzma_preset(&opt_lzma, ctx->compression_flags); lzma_filter filters[] = { - { .id = (ctx->method == ZIP_CM_LZMA ? LZMA_FILTER_LZMA1 : LZMA_FILTER_LZMA2), .options = &opt_lzma}, - { .id = LZMA_VLI_UNKNOWN, .options = NULL }, + {.id = (ctx->method == ZIP_CM_LZMA ? LZMA_FILTER_LZMA1 : LZMA_FILTER_LZMA2), .options = &opt_lzma}, + {.id = LZMA_VLI_UNKNOWN, .options = NULL}, }; ctx->zstr.avail_in = 0; @@ -129,20 +135,21 @@ start(void *ud) { ctx->zstr.next_out = NULL; if (ctx->compress) { - if (ctx->method == ZIP_CM_LZMA) - ret = lzma_alone_encoder(&ctx->zstr, filters[0].options); - else - ret = lzma_stream_encoder(&ctx->zstr, filters, LZMA_CHECK_CRC64); - } else { - if (ctx->method == ZIP_CM_LZMA) - ret = lzma_alone_decoder(&ctx->zstr, UINT64_MAX); - else - ret = lzma_stream_decoder(&ctx->zstr, UINT64_MAX, LZMA_CONCATENATED); + if (ctx->method == ZIP_CM_LZMA) + ret = lzma_alone_encoder(&ctx->zstr, filters[0].options); + else + ret = lzma_stream_encoder(&ctx->zstr, filters, LZMA_CHECK_CRC64); + } + else { + if (ctx->method == ZIP_CM_LZMA) + ret = lzma_alone_decoder(&ctx->zstr, UINT64_MAX); + else + ret = lzma_stream_decoder(&ctx->zstr, UINT64_MAX, LZMA_CONCATENATED); } if (ret != LZMA_OK) { - zip_error_set(ctx->error, map_error(ret), 0); - return false; + zip_error_set(ctx->error, map_error(ret), 0); + return false; } return true; @@ -163,8 +170,8 @@ input(void *ud, zip_uint8_t *data, zip_uint64_t length) { struct ctx *ctx = (struct ctx *)ud; if (length > UINT_MAX || ctx->zstr.avail_in > 0) { - zip_error_set(ctx->error, ZIP_ER_INVAL, 0); - return false; + zip_error_set(ctx->error, ZIP_ER_INVAL, 0); + return false; } ctx->zstr.avail_in = (uInt)length; @@ -195,10 +202,10 @@ process(void *ud, zip_uint8_t *data, zip_uint64_t *length) { switch (ret) { case LZMA_OK: - return ZIP_COMPRESSION_OK; + return ZIP_COMPRESSION_OK; case LZMA_STREAM_END: - return ZIP_COMPRESSION_END; + return ZIP_COMPRESSION_END; case LZMA_BUF_ERROR: if (ctx->zstr.avail_in == 0) { @@ -217,7 +224,8 @@ process(void *ud, zip_uint8_t *data, zip_uint64_t *length) { zip_compression_algorithm_t zip_algorithm_xz_compress = { compress_allocate, deallocate, - compression_flags, + general_purpose_bit_flags, + 63, start, end, input, @@ -229,7 +237,8 @@ zip_compression_algorithm_t zip_algorithm_xz_compress = { zip_compression_algorithm_t zip_algorithm_xz_decompress = { decompress_allocate, deallocate, - compression_flags, + general_purpose_bit_flags, + 63, start, end, input, diff --git a/Sources/libzip/src/zip_close.c b/Sources/libzip/src/zip_close.c index 2a9fed2..816fcef 100644 --- a/Sources/libzip/src/zip_close.c +++ b/Sources/libzip/src/zip_close.c @@ -36,25 +36,17 @@ #include #include -#include -#ifdef HAVE_STRINGS_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#include -#include #ifdef _WIN32 #include #include #endif -static int add_data(zip_t *, zip_source_t *, zip_dirent_t *); +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 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); ZIP_EXTERN int zip_close(zip_t *za) { @@ -204,6 +196,7 @@ zip_close(zip_t *za) { } if ((off = zip_source_tell_write(za->src)) < 0) { + _zip_error_set_from_source(&za->error, za->src); error = 1; break; } @@ -221,7 +214,7 @@ zip_close(zip_t *za) { } /* add_data writes dirent */ - if (add_data(za, zs ? zs : entry->source, de) < 0) { + if (add_data(za, zs ? zs : entry->source, de, entry->changes ? entry->changes->changed : 0) < 0) { error = 1; if (zs) zip_source_free(zs); @@ -233,8 +226,11 @@ zip_close(zip_t *za) { else { zip_uint64_t offset; - /* when copying data, all sizes are known -> no data descriptor needed */ - de->bitflags &= (zip_uint16_t)~ZIP_GPBF_DATA_DESCRIPTOR; + if (de->encryption_method != ZIP_EM_TRAD_PKWARE) { + /* when copying data, all sizes are known -> no data descriptor needed */ + /* except for PKWare encryption, where removing the data descriptor breaks password validation */ + de->bitflags &= (zip_uint16_t)~ZIP_GPBF_DATA_DESCRIPTOR; + } if (_zip_dirent_write(za, de, ZIP_FL_LOCAL) < 0) { error = 1; break; @@ -245,13 +241,20 @@ zip_close(zip_t *za) { } if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) { _zip_error_set_from_source(&za->error, za->src); - error = 1; + error = 1; break; } if (copy_data(za, de->comp_size) < 0) { - error = 1; + error = 1; break; } + + if (de->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) { + if (write_data_descriptor(za, de, _zip_dirent_needs_zip64(de, 0)) < 0) { + error = 1; + break; + } + } } } @@ -282,14 +285,14 @@ zip_close(zip_t *za) { static int -add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) { +add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) { zip_int64_t offstart, offdata, offend, data_length; - struct zip_stat st; + zip_stat_t st; + zip_file_attributes_t attributes; zip_source_t *src_final, *src_tmp; int ret; int is_zip64; zip_flags_t flags; - zip_int8_t compression_flags; bool needs_recompress, needs_decompress, needs_crc, needs_compress, needs_reencrypt, needs_decrypt, needs_encrypt; if (zip_source_stat(src, &st) < 0) { @@ -453,6 +456,9 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) { 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; @@ -471,7 +477,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) { ret = -1; } - if ((compression_flags = zip_source_get_compression_flags(src_final)) < 0) { + if (zip_source_get_file_attributes(src_final, &attributes) != 0) { _zip_error_set_from_source(&za->error, src_final); ret = -1; } @@ -507,8 +513,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) { de->crc = st.crc; de->uncomp_size = st.size; de->comp_size = (zip_uint64_t)(offend - offdata); - de->bitflags = (zip_uint16_t)((de->bitflags & (zip_uint16_t)~6) | ((zip_uint8_t)compression_flags << 1)); - _zip_dirent_set_version_needed(de, (flags & ZIP_FL_FORCE_ZIP64) != 0); + _zip_dirent_apply_attributes(de, &attributes, (flags & ZIP_FL_FORCE_ZIP64) != 0, changed); if ((ret = _zip_dirent_write(za, de, flags)) < 0) return -1; @@ -524,6 +529,12 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) { return -1; } + if (de->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) { + if (write_data_descriptor(za, de, is_zip64) < 0) { + return -1; + } + } + return 0; } @@ -656,3 +667,37 @@ _zip_changed(const zip_t *za, zip_uint64_t *survivorsp) { return changed; } + +static int +write_data_descriptor(zip_t *za, const zip_dirent_t *de, int is_zip64) { + zip_buffer_t *buffer = _zip_buffer_new(NULL, MAX_DATA_DESCRIPTOR_LENGTH); + int ret = 0; + + if (buffer == NULL) { + zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; + } + + _zip_buffer_put(buffer, DATADES_MAGIC, 4); + _zip_buffer_put_32(buffer, de->crc); + if (is_zip64) { + _zip_buffer_put_64(buffer, de->comp_size); + _zip_buffer_put_64(buffer, de->uncomp_size); + } + else { + _zip_buffer_put_32(buffer, (zip_uint32_t)de->comp_size); + _zip_buffer_put_32(buffer, (zip_uint32_t)de->uncomp_size); + } + + if (!_zip_buffer_ok(buffer)) { + zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + ret = -1; + } + else { + ret = _zip_write(za, _zip_buffer_data(buffer), _zip_buffer_offset(buffer)); + } + + _zip_buffer_free(buffer); + + return ret; +} diff --git a/Sources/libzip/src/zip_crypto_gnutls.h b/Sources/libzip/src/zip_crypto_gnutls.h index 484ddbb..30645ef 100644 --- a/Sources/libzip/src/zip_crypto_gnutls.h +++ b/Sources/libzip/src/zip_crypto_gnutls.h @@ -40,6 +40,7 @@ #include #include + #include typedef struct { diff --git a/Sources/libzip/src/zip_crypto_mbedtls.c b/Sources/libzip/src/zip_crypto_mbedtls.c index f0049ea..c348ad2 100644 --- a/Sources/libzip/src/zip_crypto_mbedtls.c +++ b/Sources/libzip/src/zip_crypto_mbedtls.c @@ -34,6 +34,7 @@ #include #include "zipint.h" + #include "zip_crypto.h" #include diff --git a/Sources/libzip/src/zip_crypto_openssl.c b/Sources/libzip/src/zip_crypto_openssl.c index 14e366a..1cb0047 100644 --- a/Sources/libzip/src/zip_crypto_openssl.c +++ b/Sources/libzip/src/zip_crypto_openssl.c @@ -52,7 +52,7 @@ _zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t * zip_error_set(error, ZIP_ER_MEMORY, 0); return NULL; } - + AES_set_encrypt_key(key, key_size, aes); return aes; diff --git a/Sources/libzip/src/zip_crypto_win.c b/Sources/libzip/src/zip_crypto_win.c index abdd7e0..7eb42c3 100644 --- a/Sources/libzip/src/zip_crypto_win.c +++ b/Sources/libzip/src/zip_crypto_win.c @@ -40,6 +40,7 @@ #define NOCRYPT #include + #include #pragma comment(lib, "bcrypt.lib") @@ -216,7 +217,7 @@ hmacCalculate(PRF_CTX *pContext, PUCHAR pbData, DWORD cbData, PUCHAR pbDigest) { } static void -xor(LPBYTE ptr1, LPBYTE ptr2, DWORD dwLen) { +myxor(LPBYTE ptr1, LPBYTE ptr2, DWORD dwLen) { while (dwLen--) *ptr1++ ^= *ptr2++; } @@ -267,7 +268,7 @@ pbkdf2(PUCHAR pbPassword, ULONG cbPassword, PUCHAR pbSalt, ULONG cbSalt, DWORD c goto PBKDF2_end; } - xor(Ti, V, DIGEST_SIZE); + myxor(Ti, V, DIGEST_SIZE); } if (i != l) { diff --git a/Sources/libzip/src/zip_dirent.c b/Sources/libzip/src/zip_dirent.c index 2bbb63d..1691071 100644 --- a/Sources/libzip/src/zip_dirent.c +++ b/Sources/libzip/src/zip_dirent.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include @@ -522,29 +521,54 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo return -1; } - if (zde->uncomp_size == ZIP_UINT32_MAX) + 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) + if (zde->comp_size == ZIP_UINT32_MAX) { zde->comp_size = _zip_buffer_get_64(ef_buffer); + } if (!local) { - if (zde->offset == ZIP_UINT32_MAX) + if (zde->offset == ZIP_UINT32_MAX) { zde->offset = _zip_buffer_get_64(ef_buffer); - if (zde->disk_number == ZIP_UINT16_MAX) + } + if (zde->disk_number == ZIP_UINT16_MAX) { zde->disk_number = _zip_buffer_get_32(ef_buffer); + } } if (!_zip_buffer_eof(ef_buffer)) { - zip_error_set(error, ZIP_ER_INCONS, 0); - _zip_buffer_free(ef_buffer); - if (!from_buffer) { - _zip_buffer_free(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 (!from_buffer) { + _zip_buffer_free(buffer); + } + return -1; } - return -1; } _zip_buffer_free(ef_buffer); } @@ -572,7 +596,7 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo zde->extra_fields = _zip_ef_remove_internal(zde->extra_fields); - return (zip_int64_t)(size + variable_size); + return (zip_int64_t)size + (zip_int64_t)variable_size; } @@ -867,9 +891,9 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) { _zip_buffer_put(buffer, (flags & ZIP_FL_LOCAL) ? LOCAL_MAGIC : CENTRAL_MAGIC, 4); if ((flags & ZIP_FL_LOCAL) == 0) { - _zip_buffer_put_16(buffer, (zip_uint16_t)(is_really_zip64 ? 45 : de->version_madeby)); + _zip_buffer_put_16(buffer, de->version_madeby); } - _zip_buffer_put_16(buffer, (zip_uint16_t)(is_really_zip64 ? 45 : de->version_needed)); + _zip_buffer_put_16(buffer, ZIP_MAX(is_really_zip64 ? 45 : 0, de->version_needed)); _zip_buffer_put_16(buffer, de->bitflags); if (is_winzip_aes) { _zip_buffer_put_16(buffer, ZIP_CM_WINZIP_AES); @@ -1074,7 +1098,7 @@ _zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate) { tpm = localtime(&intime); #endif 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; @@ -1091,36 +1115,49 @@ _zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate) { void -_zip_dirent_set_version_needed(zip_dirent_t *de, bool force_zip64) { +_zip_dirent_apply_attributes(zip_dirent_t *de, zip_file_attributes_t *attributes, bool force_zip64, zip_uint32_t changed) { zip_uint16_t length; + if (attributes->valid & ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS) { + zip_uint16_t mask = attributes->general_purpose_bit_mask & ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS_ALLOWED_MASK; + de->bitflags = (de->bitflags & ~mask) | (attributes->general_purpose_bit_flags & mask); + } + if (attributes->valid & ZIP_FILE_ATTRIBUTES_ASCII) { + de->int_attrib = (de->int_attrib & ~0x1) | (attributes->ascii ? 1 : 0); + } + /* manually set attributes are preferred over attributes provided by source */ + if ((changed & ZIP_DIRENT_ATTRIBUTES) == 0 && (attributes->valid & ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES)) { + de->ext_attrib = attributes->external_file_attributes; + } + if (de->comp_method == ZIP_CM_LZMA) { de->version_needed = 63; - return; } - - if (de->comp_method == ZIP_CM_BZIP2) { + else if (de->encryption_method == ZIP_EM_AES_128 || de->encryption_method == ZIP_EM_AES_192 || de->encryption_method == ZIP_EM_AES_256) { + de->version_needed = 51; + } + else if (de->comp_method == ZIP_CM_BZIP2) { de->version_needed = 46; - return; } - - if (force_zip64 || _zip_dirent_needs_zip64(de, 0)) { + else if (force_zip64 || _zip_dirent_needs_zip64(de, 0)) { de->version_needed = 45; - return; } - - if (de->comp_method == ZIP_CM_DEFLATE || de->encryption_method == ZIP_EM_TRAD_PKWARE) { + else if (de->comp_method == ZIP_CM_DEFLATE || de->encryption_method == ZIP_EM_TRAD_PKWARE) { + de->version_needed = 20; + } + else if ((length = _zip_string_length(de->filename)) > 0 && de->filename->raw[length - 1] == '/') { de->version_needed = 20; - return; + } + else { + de->version_needed = 10; } - /* directory */ - if ((length = _zip_string_length(de->filename)) > 0) { - if (de->filename->raw[length - 1] == '/') { - de->version_needed = 20; - return; - } + if (attributes->valid & ZIP_FILE_ATTRIBUTES_VERSION_NEEDED) { + de->version_needed = ZIP_MAX(de->version_needed, attributes->version_needed); } - de->version_needed = 10; + de->version_madeby = 63 | (de->version_madeby & 0xff00); + if ((changed & ZIP_DIRENT_ATTRIBUTES) == 0 && (attributes->valid & ZIP_FILE_ATTRIBUTES_HOST_SYSTEM)) { + de->version_madeby = (de->version_madeby & 0xff) | (zip_uint16_t)(attributes->host_system << 8); + } } diff --git a/Sources/libzip/src/zip_err_str.c b/Sources/libzip/src/zip_err_str.c index e0a04a9..1a6cd88 100644 --- a/Sources/libzip/src/zip_err_str.c +++ b/Sources/libzip/src/zip_err_str.c @@ -1,6 +1,6 @@ /* - This file was generated automatically by ./make_zip_err_str.sh - from ./zip.h; make changes there. + This file was generated automatically by CMake + from zip.h; make changes there. */ #include "zipint.h" diff --git a/Sources/libzip/src/zip_error_strerror.c b/Sources/libzip/src/zip_error_strerror.c index 6358577..93b24ea 100644 --- a/Sources/libzip/src/zip_error_strerror.c +++ b/Sources/libzip/src/zip_error_strerror.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "zipint.h" diff --git a/Sources/libzip/src/zip_error_to_str.c b/Sources/libzip/src/zip_error_to_str.c index 13faf96..34a3331 100644 --- a/Sources/libzip/src/zip_error_to_str.c +++ b/Sources/libzip/src/zip_error_to_str.c @@ -33,8 +33,8 @@ #include -#include #include +#include #define _ZIP_COMPILING_DEPRECATED #include "zipint.h" diff --git a/Sources/libzip/src/zip_file_get_offset.c b/Sources/libzip/src/zip_file_get_offset.c index 9ea8909..2cf4480 100644 --- a/Sources/libzip/src/zip_file_get_offset.c +++ b/Sources/libzip/src/zip_file_get_offset.c @@ -33,10 +33,7 @@ #include -#include #include -#include -#include #include "zipint.h" diff --git a/Sources/libzip/src/zip_filerange_crc.c b/Sources/libzip/src/zip_filerange_crc.c deleted file mode 100644 index b887363..0000000 --- a/Sources/libzip/src/zip_filerange_crc.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - zip_filerange_crc.c -- compute CRC32 for a range of a file - Copyright (C) 2008-2019 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" - - -int -_zip_filerange_crc(zip_source_t *src, zip_uint64_t start, zip_uint64_t len, uLong *crcp, zip_error_t *error) { - DEFINE_BYTE_ARRAY(buf, BUFSIZE); - - zip_int64_t n; - - *crcp = crc32(0L, Z_NULL, 0); - - if (start > ZIP_INT64_MAX) { - zip_error_set(error, ZIP_ER_SEEK, EFBIG); - return -1; - } - - if (zip_source_seek(src, (zip_int64_t)start, SEEK_SET) != 0) { - _zip_error_set_from_source(error, src); - return -1; - } - - if (!byte_array_init(buf, BUFSIZE)) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return -1; - } - - while (len > 0) { - n = (zip_int64_t)(len > BUFSIZE ? BUFSIZE : len); - if ((n = zip_source_read(src, buf, (zip_uint64_t)n)) < 0) { - _zip_error_set_from_source(error, src); - byte_array_fini(buf); - return -1; - } - if (n == 0) { - zip_error_set(error, ZIP_ER_EOF, 0); - byte_array_fini(buf); - return -1; - } - - *crcp = crc32(*crcp, buf, (uInt)n); - - len -= (zip_uint64_t)n; - } - - byte_array_fini(buf); - - return 0; -} diff --git a/Sources/libzip/src/zip_fopen_index.c b/Sources/libzip/src/zip_fopen_index.c index ffca281..e5205b7 100644 --- a/Sources/libzip/src/zip_fopen_index.c +++ b/Sources/libzip/src/zip_fopen_index.c @@ -32,9 +32,6 @@ */ -#include -#include - #include "zipint.h" diff --git a/Sources/libzip/src/zip_fseek.c b/Sources/libzip/src/zip_fseek.c index 86d3865..dc6d978 100644 --- a/Sources/libzip/src/zip_fseek.c +++ b/Sources/libzip/src/zip_fseek.c @@ -33,7 +33,6 @@ #include "zipint.h" -#include ZIP_EXTERN zip_int8_t zip_fseek(zip_file_t *zf, zip_int64_t offset, int whence) { diff --git a/Sources/libzip/src/zip_ftell.c b/Sources/libzip/src/zip_ftell.c index 9502dd6..944db7b 100644 --- a/Sources/libzip/src/zip_ftell.c +++ b/Sources/libzip/src/zip_ftell.c @@ -33,7 +33,6 @@ #include "zipint.h" -#include ZIP_EXTERN zip_int64_t zip_ftell(zip_file_t *zf) { diff --git a/Sources/libzip/src/zip_get_encryption_implementation.c b/Sources/libzip/src/zip_get_encryption_implementation.c index c9d52ad..3909e6f 100644 --- a/Sources/libzip/src/zip_get_encryption_implementation.c +++ b/Sources/libzip/src/zip_get_encryption_implementation.c @@ -39,10 +39,7 @@ zip_encryption_implementation _zip_get_encryption_implementation(zip_uint16_t em, int operation) { switch (em) { case ZIP_EM_TRAD_PKWARE: - if (operation == ZIP_CODEC_ENCODE) { - return NULL; - } - return zip_source_pkware; + return operation == ZIP_CODEC_DECODE ? zip_source_pkware_decode : zip_source_pkware_encode; #if defined(HAVE_CRYPTO) case ZIP_EM_AES_128: @@ -55,3 +52,11 @@ _zip_get_encryption_implementation(zip_uint16_t em, int operation) { return NULL; } } + +ZIP_EXTERN int +zip_encryption_method_supported(zip_uint16_t method, int encode) { + if (method == ZIP_EM_NONE) { + return 1; + } + return _zip_get_encryption_implementation(method, encode ? ZIP_CODEC_ENCODE : ZIP_CODEC_DECODE) != NULL; +} diff --git a/Sources/libzip/src/zip_mkstempm.c b/Sources/libzip/src/zip_mkstempm.c index a38ba61..c1afade 100644 --- a/Sources/libzip/src/zip_mkstempm.c +++ b/Sources/libzip/src/zip_mkstempm.c @@ -31,11 +31,10 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include #include #include -#include #include +#include #include "zipint.h" @@ -65,18 +64,18 @@ _zip_mkstempm(char *path, int mode) { start++; for (;;) { - zip_uint32_t value = zip_random_uint32(); + 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'; - } + char digit = value % 36; + if (digit < 10) { + *(xs++) = digit + '0'; + } + else { + *(xs++) = digit - 10 + 'a'; + } value /= 36; } diff --git a/Sources/libzip/src/zip_open.c b/Sources/libzip/src/zip_open.c index 4e29c5b..019cd98 100644 --- a/Sources/libzip/src/zip_open.c +++ b/Sources/libzip/src/zip_open.c @@ -32,19 +32,13 @@ */ -#include #include #include #include -#include #include "zipint.h" -typedef enum { - EXISTS_ERROR = -1, - EXISTS_NOT = 0, - EXISTS_OK -} exists_t; +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 zip_cdir_t *_zip_find_central_dir(zip_t *za, zip_uint64_t len); diff --git a/Sources/libzip/src/zip_pkware.c b/Sources/libzip/src/zip_pkware.c new file mode 100644 index 0000000..eb12b1e --- /dev/null +++ b/Sources/libzip/src/zip_pkware.c @@ -0,0 +1,112 @@ +/* + zip_pkware.c -- Traditional PKWARE de/encryption backend routines + 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 + + 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 "zipint.h" + +#define PKWARE_KEY0 305419896 +#define PKWARE_KEY1 591751049 +#define PKWARE_KEY2 878082192 + + +static void +update_keys(zip_pkware_keys_t *keys, zip_uint8_t b) { + keys->key[0] = (zip_uint32_t)crc32(keys->key[0] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL; + keys->key[1] = (keys->key[1] + (keys->key[0] & 0xff)) * 134775813 + 1; + b = (zip_uint8_t)(keys->key[1] >> 24); + keys->key[2] = (zip_uint32_t)crc32(keys->key[2] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL; +} + + +static zip_uint8_t +crypt_byte(zip_pkware_keys_t *keys) { + zip_uint16_t tmp; + tmp = (zip_uint16_t)(keys->key[2] | 2); + tmp = (zip_uint16_t)(((zip_uint32_t)tmp * (tmp ^ 1)) >> 8); + return (zip_uint8_t)tmp; +} + + +void +_zip_pkware_keys_reset(zip_pkware_keys_t *keys) { + keys->key[0] = PKWARE_KEY0; + keys->key[1] = PKWARE_KEY1; + keys->key[2] = PKWARE_KEY2; +} + + +void +_zip_pkware_encrypt(zip_pkware_keys_t *keys, zip_uint8_t *out, const zip_uint8_t *in, zip_uint64_t len) { + zip_uint64_t i; + zip_uint8_t b; + zip_uint8_t tmp; + + for (i = 0; i < len; i++) { + b = in[i]; + + if (out != NULL) { + tmp = crypt_byte(keys); + update_keys(keys, b); + b ^= tmp; + out[i] = b; + } + else { + /* during initialization, we're only interested in key updates */ + update_keys(keys, b); + } + } +} + + +void +_zip_pkware_decrypt(zip_pkware_keys_t *keys, zip_uint8_t *out, const zip_uint8_t *in, zip_uint64_t len) { + zip_uint64_t i; + zip_uint8_t b; + zip_uint8_t tmp; + + for (i = 0; i < len; i++) { + b = in[i]; + + /* during initialization, we're only interested in key updates */ + if (out != NULL) { + tmp = crypt_byte(keys); + b ^= tmp; + out[i] = b; + } + + update_keys(keys, b); + } +} diff --git a/Sources/libzip/src/zip_progress.c b/Sources/libzip/src/zip_progress.c index d48ae56..ddb47c7 100644 --- a/Sources/libzip/src/zip_progress.c +++ b/Sources/libzip/src/zip_progress.c @@ -209,10 +209,8 @@ _zip_progress_update(zip_progress_t *progress, double sub_current) { ZIP_EXTERN int zip_register_progress_callback_with_state(zip_t *za, double precision, zip_progress_callback callback, void (*ud_free)(void *), void *ud) { - zip_progress_t *progress = NULL; - if (callback != NULL) { - if (za->progress == NULL) { + if (za->progress == NULL) { if ((za->progress = _zip_progress_new(za)) == NULL) { return -1; } @@ -238,10 +236,8 @@ zip_register_progress_callback_with_state(zip_t *za, double precision, zip_progr ZIP_EXTERN int zip_register_cancel_callback_with_state(zip_t *za, zip_cancel_callback callback, void (*ud_free)(void *), void *ud) { - zip_progress_t *progress = NULL; - if (callback != NULL) { - if (za->progress == NULL) { + if (za->progress == NULL) { if ((za->progress = _zip_progress_new(za)) == NULL) { return -1; } diff --git a/Sources/libzip/src/zip_random_unix.c b/Sources/libzip/src/zip_random_unix.c index 24c7c1f..1d0c967 100644 --- a/Sources/libzip/src/zip_random_unix.c +++ b/Sources/libzip/src/zip_random_unix.c @@ -37,7 +37,6 @@ #include "zip_crypto.h" #endif - #ifdef HAVE_ARC4RANDOM #include @@ -87,17 +86,17 @@ zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length) { zip_uint32_t zip_random_uint32(void) { static bool seeded = false; - + zip_uint32_t value; - + if (zip_secure_random((zip_uint8_t *)&value, sizeof(value))) { - return value; + return value; } - + if (!seeded) { - srandom((unsigned int)time(NULL)); + srandom((unsigned int)time(NULL)); } - + return (zip_uint32_t)random(); } #endif diff --git a/Sources/libzip/src/zip_random_uwp.c b/Sources/libzip/src/zip_random_uwp.c index cec7ec6..f83c78f 100644 --- a/Sources/libzip/src/zip_random_uwp.c +++ b/Sources/libzip/src/zip_random_uwp.c @@ -43,8 +43,6 @@ #include #include -#include "zipwin32.h" - ZIP_EXTERN bool zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length) { BCRYPT_ALG_HANDLE hAlg = NULL; @@ -72,11 +70,11 @@ zip_random_uint32(void) { zip_uint32_t value; if (zip_secure_random((zip_uint8_t *)&value, sizeof(value))) { - return value; + return value; } if (!seeded) { - srand((unsigned int)time(NULL)); + srand((unsigned int)time(NULL)); } return (zip_uint32_t)rand(); diff --git a/Sources/libzip/src/zip_random_win32.c b/Sources/libzip/src/zip_random_win32.c index 052bd4f..19d488e 100644 --- a/Sources/libzip/src/zip_random_win32.c +++ b/Sources/libzip/src/zip_random_win32.c @@ -32,12 +32,13 @@ */ #include "zipint.h" -#include "zipwin32.h" #ifdef HAVE_CRYPTO #include "zip_crypto.h" #endif +#include + #ifndef HAVE_SECURE_RANDOM #include @@ -68,11 +69,11 @@ zip_random_uint32(void) { zip_uint32_t value; if (zip_secure_random((zip_uint8_t *)&value, sizeof(value))) { - return value; + return value; } if (!seeded) { - srand((unsigned int)time(NULL)); + srand((unsigned int)time(NULL)); } return (zip_uint32_t)rand(); diff --git a/Sources/libzip/src/zip_rename.c b/Sources/libzip/src/zip_rename.c index e5f1682..75b456d 100644 --- a/Sources/libzip/src/zip_rename.c +++ b/Sources/libzip/src/zip_rename.c @@ -32,8 +32,6 @@ */ -#include - #define _ZIP_COMPILING_DEPRECATED #include "zipint.h" diff --git a/Sources/libzip/src/zip_set_file_comment.c b/Sources/libzip/src/zip_set_file_comment.c index 1fa01ae..4277893 100644 --- a/Sources/libzip/src/zip_set_file_comment.c +++ b/Sources/libzip/src/zip_set_file_comment.c @@ -32,8 +32,6 @@ */ -#include - #define _ZIP_COMPILING_DEPRECATED #include "zipint.h" diff --git a/Sources/libzip/src/zip_source_buffer.c b/Sources/libzip/src/zip_source_buffer.c index 0685fb3..519d2c3 100644 --- a/Sources/libzip/src/zip_source_buffer.c +++ b/Sources/libzip/src/zip_source_buffer.c @@ -61,6 +61,7 @@ typedef struct buffer buffer_t; struct read_data { zip_error_t error; time_t mtime; + zip_file_attributes_t attributes; buffer_t *in; buffer_t *out; }; @@ -79,33 +80,42 @@ static zip_int64_t buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_u static zip_int64_t read_data(void *, void *, zip_uint64_t, zip_source_cmd_t); +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); +zip_source_t *zip_source_buffer_fragment_with_attributes_create(const zip_buffer_fragment_t *fragments, zip_uint64_t nfragments, int freep, zip_file_attributes_t *attributes, zip_error_t *error); + ZIP_EXTERN zip_source_t * zip_source_buffer(zip_t *za, const void *data, zip_uint64_t len, int freep) { if (za == NULL) return NULL; - return zip_source_buffer_create(data, len, freep, &za->error); + return zip_source_buffer_with_attributes_create(data, len, freep, NULL, &za->error); } ZIP_EXTERN zip_source_t * zip_source_buffer_create(const void *data, zip_uint64_t len, int freep, zip_error_t *error) { + return zip_source_buffer_with_attributes_create(data, len, freep, NULL, error); +} + + +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) { zip_buffer_fragment_t fragment; if (data == NULL) { - if (len > 0) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } + if (len > 0) { + zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } - return zip_source_buffer_fragment_create(NULL, 0, freep, error); + return zip_source_buffer_fragment_with_attributes_create(NULL, 0, freep, attributes, error); } fragment.data = (zip_uint8_t *)data; fragment.length = len; - return zip_source_buffer_fragment_create(&fragment, 1, freep, error); + return zip_source_buffer_fragment_with_attributes_create(&fragment, 1, freep, attributes, error); } @@ -115,12 +125,17 @@ zip_source_buffer_fragment(zip_t *za, const zip_buffer_fragment_t *fragments, zi return NULL; } - return zip_source_buffer_fragment_create(fragments, nfragments, freep, &za->error); + return zip_source_buffer_fragment_with_attributes_create(fragments, nfragments, freep, NULL, &za->error); } ZIP_EXTERN zip_source_t * zip_source_buffer_fragment_create(const zip_buffer_fragment_t *fragments, zip_uint64_t nfragments, int freep, zip_error_t *error) { + return zip_source_buffer_fragment_with_attributes_create(fragments, nfragments, freep, NULL, error); +} + +zip_source_t * +zip_source_buffer_fragment_with_attributes_create(const zip_buffer_fragment_t *fragments, zip_uint64_t nfragments, int freep, zip_file_attributes_t *attributes, zip_error_t *error) { struct read_data *ctx; zip_source_t *zs; buffer_t *buffer; @@ -143,6 +158,12 @@ zip_source_buffer_fragment_create(const zip_buffer_fragment_t *fragments, zip_ui ctx->in = buffer; ctx->out = NULL; ctx->mtime = time(NULL); + if (attributes) { + memcpy(&ctx->attributes, attributes, sizeof(ctx->attributes)); + } + else { + zip_file_attributes_init(&ctx->attributes); + } zip_error_init(&ctx->error); if ((zs = zip_source_function_create(read_data, ctx, error)) == NULL) { @@ -155,6 +176,11 @@ zip_source_buffer_fragment_create(const zip_buffer_fragment_t *fragments, zip_ui } +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) { + return zip_source_buffer_with_attributes_create(data, len, freep, attributes, &za->error); +} + static zip_int64_t read_data(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { struct read_data *ctx = (struct read_data *)state; @@ -194,6 +220,17 @@ read_data(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { free(ctx); return 0; + case ZIP_SOURCE_GET_FILE_ATTRIBUTES: { + if (len < sizeof(ctx->attributes)) { + zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); + return -1; + } + + memcpy(data, &ctx->attributes, sizeof(ctx->attributes)); + + return sizeof(ctx->attributes); + } + case ZIP_SOURCE_OPEN: ctx->in->offset = 0; ctx->in->current_fragment = 0; @@ -250,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_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, -1); case ZIP_SOURCE_TELL: if (ctx->in->offset > ZIP_INT64_MAX) { diff --git a/Sources/libzip/src/zip_source_compress.c b/Sources/libzip/src/zip_source_compress.c index 59b1212..e49929f 100644 --- a/Sources/libzip/src/zip_source_compress.c +++ b/Sources/libzip/src/zip_source_compress.c @@ -31,7 +31,6 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include #include #include @@ -68,12 +67,12 @@ static struct implementation implementations[] = { {ZIP_CM_BZIP2, &zip_algorithm_bzip2_compress, &zip_algorithm_bzip2_decompress}, #endif #if defined(HAVE_LIBLZMA) -/* Disabled - because 7z isn't able to unpack ZIP+LZMA ZIP+LZMA2 - archives made this way - and vice versa. + /* Disabled - because 7z isn't able to unpack ZIP+LZMA ZIP+LZMA2 + archives made this way - and vice versa. - {ZIP_CM_LZMA, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress}, - {ZIP_CM_LZMA2, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress}, -*/ + {ZIP_CM_LZMA, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress}, + {ZIP_CM_LZMA2, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress}, + */ {ZIP_CM_XZ, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress}, #endif @@ -106,10 +105,10 @@ get_algorithm(zip_int32_t method, bool compress) { return NULL; } -bool -zip_compression_method_supported(zip_int32_t method, bool compress) { +ZIP_EXTERN int +zip_compression_method_supported(zip_int32_t method, int compress) { if (method == ZIP_CM_STORE) { - return true; + return 1; } return get_algorithm(method, compress) != NULL; } @@ -357,9 +356,6 @@ compress_callback(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip } return 0; - case ZIP_SOURCE_GET_COMPRESSION_FLAGS: - return ctx->is_stored ? 0 : ctx->algorithm->compression_flags(ctx->ud); - case ZIP_SOURCE_ERROR: return zip_error_to_data(&ctx->error, data, len); @@ -367,8 +363,24 @@ compress_callback(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip context_free(ctx); return 0; + case ZIP_SOURCE_GET_FILE_ATTRIBUTES: { + zip_file_attributes_t *attributes = (zip_file_attributes_t *)data; + + if (len < sizeof(*attributes)) { + zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); + return -1; + } + + attributes->valid |= ZIP_FILE_ATTRIBUTES_VERSION_NEEDED | ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS; + attributes->version_needed = ctx->algorithm->version_needed; + attributes->general_purpose_bit_mask = ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS_ALLOWED_MASK; + attributes->general_purpose_bit_flags = (ctx->is_stored ? 0 : ctx->algorithm->general_purpose_bit_flags(ctx->ud)); + + return sizeof(*attributes); + } + case ZIP_SOURCE_SUPPORTS: - return ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_GET_COMPRESSION_FLAGS, -1); + return ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_GET_FILE_ATTRIBUTES, -1); default: zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0); diff --git a/Sources/libzip/src/zip_source_crc.c b/Sources/libzip/src/zip_source_crc.c index 56572c0..4f3f223 100644 --- a/Sources/libzip/src/zip_source_crc.c +++ b/Sources/libzip/src/zip_source_crc.c @@ -34,7 +34,7 @@ #include #include -#include +#include #include "zipint.h" @@ -167,7 +167,7 @@ crc_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source 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_COMPRESSION_FLAGS, -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); } case ZIP_SOURCE_SEEK: { diff --git a/Sources/libzip/src/zip_source_file.c b/Sources/libzip/src/zip_source_file.c deleted file mode 100644 index 3fff4e3..0000000 --- a/Sources/libzip/src/zip_source_file.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - zip_source_file.c -- create data source from file - Copyright (C) 1999-2019 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" - -#ifdef _WIN32 -#error This file is incompatible with Windows, use zip_source_win32utf8.c instead. -#error Something probably went wrong with configure/cmake. -#endif - -ZIP_EXTERN zip_source_t * -zip_source_file(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t len) { - if (za == NULL) - return NULL; - - return zip_source_file_create(fname, start, len, &za->error); -} - - -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) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } - - return _zip_source_file_or_p(fname, NULL, start, length, NULL, error); -} diff --git a/Sources/libzip/src/zip_source_file.h b/Sources/libzip/src/zip_source_file.h new file mode 100644 index 0000000..43a4645 --- /dev/null +++ b/Sources/libzip/src/zip_source_file.h @@ -0,0 +1,90 @@ +/* + zip_source_file.h -- header for common file operations + 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 + + 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. +*/ + +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 regular_file; /* must always be valid */ +}; + +typedef struct zip_source_file_context zip_source_file_context_t; +typedef struct zip_source_file_operations zip_source_file_operations_t; +typedef struct zip_source_file_stat zip_source_file_stat_t; + +struct zip_source_file_context { + zip_error_t error; /* last error information */ + zip_int64_t supports; + + /* reading */ + char *fname; /* name of file to read from */ + void *f; /* file to read from */ + zip_stat_t st; /* stat information passed in */ + zip_file_attributes_t attributes; /* additional file attributes */ + zip_error_t stat_error; /* error returned for stat */ + zip_uint64_t start; /* start offset of data to read */ + zip_uint64_t len; /* length of the file, 0 for up to EOF */ + zip_uint64_t offset; /* current offset relative to start (0 is beginning of part we read) */ + + /* writing */ + char *tmpname; + void *fout; + + zip_source_file_operations_t *ops; + void *ops_userdata; +}; + + +/* The following methods must be implemented to support each feature: + - close, read, seek, and stat must always be implemented. + - To support specifying the file by name, open, and strdup must be implemented. + - For write support, the file must be specified by name and close, commit_write, create_temp_output, remove, rollback_write, and tell must be implemented. + - create_temp_output_cloning is always optional. */ + +struct zip_source_file_operations { + void (*close)(zip_source_file_context_t *ctx); + zip_int64_t (*commit_write)(zip_source_file_context_t *ctx); + zip_int64_t (*create_temp_output)(zip_source_file_context_t *ctx); + zip_int64_t (*create_temp_output_cloning)(zip_source_file_context_t *ctx, zip_uint64_t len); + bool (*open)(zip_source_file_context_t *ctx); + zip_int64_t (*read)(zip_source_file_context_t *ctx, void *buf, zip_uint64_t len); + zip_int64_t (*remove)(zip_source_file_context_t *ctx); + void (*rollback_write)(zip_source_file_context_t *ctx); + bool (*seek)(zip_source_file_context_t *ctx, void *f, zip_int64_t offset, int whence); + bool (*stat)(zip_source_file_context_t *ctx, zip_source_file_stat_t *st); + char *(*string_duplicate)(zip_source_file_context_t *ctx, const char *); + zip_int64_t (*tell)(zip_source_file_context_t *ctx, void *f); + zip_int64_t (*write)(zip_source_file_context_t *ctx, const void *data, zip_uint64_t len); +}; + +zip_source_t *zip_source_file_common_new(const char *fname, void *file, zip_uint64_t start, zip_int64_t len, const zip_stat_t *st, zip_source_file_operations_t *ops, void *ops_userdata, zip_error_t *error); diff --git a/Sources/libzip/src/zip_source_file_common.c b/Sources/libzip/src/zip_source_file_common.c new file mode 100644 index 0000000..74e2100 --- /dev/null +++ b/Sources/libzip/src/zip_source_file_common.c @@ -0,0 +1,378 @@ +/* + zip_source_file_common.c -- create data source from file + Copyright (C) 1999-2019 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 "zipint.h" + +#include "zip_source_file.h" + +static zip_int64_t read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd); + +static void +zip_source_file_stat_init(zip_source_file_stat_t *st) { + st->size = 0; + st->mtime = time(NULL); + st->exists = false; + st->regular_file = false; +} + +zip_source_t * +zip_source_file_common_new(const char *fname, void *file, zip_uint64_t start, zip_int64_t len, const zip_stat_t *st, zip_source_file_operations_t *ops, void *ops_userdata, zip_error_t *error) { + zip_source_file_context_t *ctx; + zip_source_t *zs; + zip_source_file_stat_t sb; + + if (ops == NULL) { + zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + + if (ops->close == NULL || ops->read == NULL || ops->seek == NULL || ops->stat == NULL) { + zip_error_set(error, ZIP_ER_INTERNAL, 0); + return NULL; + } + + if (ops->write != NULL && (ops->commit_write == NULL || ops->create_temp_output == NULL || ops->remove == NULL || ops->rollback_write == NULL || ops->tell == NULL)) { + zip_error_set(error, ZIP_ER_INTERNAL, 0); + return NULL; + } + + if (fname != NULL) { + if (ops->open == NULL || ops->string_duplicate == NULL) { + zip_error_set(error, ZIP_ER_INTERNAL, 0); + return NULL; + } + } + else if (file == NULL) { + zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + + if (len < 0) { + len = 0; + } + + if (start > ZIP_INT64_MAX || start + (zip_uint64_t)len < start) { + zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((ctx = (zip_source_file_context_t *)malloc(sizeof(zip_source_file_context_t))) == NULL) { + zip_error_set(error, ZIP_ER_MEMORY, 0); + return NULL; + } + + ctx->ops = ops; + ctx->ops_userdata = ops_userdata; + ctx->fname = NULL; + if (fname) { + if ((ctx->fname = ops->string_duplicate(ctx, fname)) == NULL) { + zip_error_set(error, ZIP_ER_MEMORY, 0); + free(ctx); + return NULL; + } + } + ctx->f = file; + ctx->start = start; + ctx->len = (zip_uint64_t)len; + if (st) { + memcpy(&ctx->st, st, sizeof(ctx->st)); + ctx->st.name = NULL; + ctx->st.valid &= ~ZIP_STAT_NAME; + } + else { + zip_stat_init(&ctx->st); + } + + if (ctx->len > 0) { + ctx->st.size = ctx->len; + ctx->st.valid |= ZIP_STAT_SIZE; + } + + zip_error_init(&ctx->stat_error); + + ctx->tmpname = NULL; + ctx->fout = NULL; + + 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); + + zip_source_file_stat_init(&sb); + if (!ops->stat(ctx, &sb)) { + _zip_error_copy(error, &ctx->error); + free(ctx->fname); + free(ctx); + return NULL; + } + + if (!sb.exists) { + if (ctx->fname && ctx->start == 0 && ctx->len == 0 && ops->write != NULL) { + ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE; + /* zip_open_from_source checks for this to detect non-existing files */ + zip_error_set(&ctx->stat_error, ZIP_ER_READ, ENOENT); + } + else { + zip_error_set(&ctx->stat_error, ZIP_ER_READ, ENOENT); + free(ctx->fname); + free(ctx); + return NULL; + } + } + else { + if ((ctx->st.valid & ZIP_STAT_MTIME) == 0) { + ctx->st.mtime = sb.mtime; + ctx->st.valid |= ZIP_STAT_MTIME; + } + if (sb.regular_file) { + ctx->supports = ZIP_SOURCE_SUPPORTS_SEEKABLE; + + if (ctx->start + ctx->len > sb.size) { + zip_error_set(error, ZIP_ER_INVAL, 0); + free(ctx->fname); + free(ctx); + return NULL; + } + + if (ctx->len == 0) { + 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) { + ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE; + } + } + } + + ctx->supports |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_GET_FILE_ATTRIBUTES); + } + + ctx->supports |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ACCEPT_EMPTY); + if (ops->create_temp_output_cloning != NULL) { + if (ctx->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE)) { + ctx->supports |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE_CLONING); + } + } + + if ((zs = zip_source_function_create(read_file, ctx, error)) == NULL) { + free(ctx->fname); + free(ctx); + return NULL; + } + + return zs; +} + + +static zip_int64_t +read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { + zip_source_file_context_t *ctx; + char *buf; + + ctx = (zip_source_file_context_t *)state; + buf = (char *)data; + + switch (cmd) { + case ZIP_SOURCE_ACCEPT_EMPTY: + return 0; + + case ZIP_SOURCE_BEGIN_WRITE: + /* write support should not be set if fname is NULL */ + if (ctx->fname == NULL) { + zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0); + return -1; + } + return ctx->ops->create_temp_output(ctx); + + case ZIP_SOURCE_BEGIN_WRITE_CLONING: + /* write support should not be set if fname is NULL */ + if (ctx->fname == NULL) { + zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0); + return -1; + } + return ctx->ops->create_temp_output_cloning(ctx, len); + + case ZIP_SOURCE_CLOSE: + if (ctx->fname) { + ctx->ops->close(ctx); + ctx->f = NULL; + } + return 0; + + case ZIP_SOURCE_COMMIT_WRITE: { + zip_int64_t ret = ctx->ops->commit_write(ctx); + ctx->fout = NULL; + if (ret == 0) { + free(ctx->tmpname); + ctx->tmpname = NULL; + } + return ret; + } + + case ZIP_SOURCE_ERROR: + return zip_error_to_data(&ctx->error, data, len); + + case ZIP_SOURCE_FREE: + free(ctx->fname); + free(ctx->tmpname); + if (ctx->f) { + ctx->ops->close(ctx); + } + free(ctx); + return 0; + + case ZIP_SOURCE_GET_FILE_ATTRIBUTES: + if (len < sizeof(ctx->attributes)) { + zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); + return -1; + } + memcpy(data, &ctx->attributes, sizeof(ctx->attributes)); + return sizeof(ctx->attributes); + + case ZIP_SOURCE_OPEN: + if (ctx->fname) { + if (ctx->ops->open(ctx) == false) { + return -1; + } + } + + 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; + } + } + ctx->offset = 0; + return 0; + + case ZIP_SOURCE_READ: { + zip_int64_t i; + zip_uint64_t n; + + if (ctx->len > 0) { + n = ZIP_MIN(ctx->len - ctx->offset, len); + } + else { + n = len; + } + + if ((i = ctx->ops->read(ctx, buf, n)) < 0) { + zip_error_set(&ctx->error, ZIP_ER_READ, errno); + return -1; + } + ctx->offset += (zip_uint64_t)i; + + return i; + } + + case ZIP_SOURCE_REMOVE: + return ctx->ops->remove(ctx); + + case ZIP_SOURCE_ROLLBACK_WRITE: + ctx->ops->rollback_write(ctx); + ctx->fout = NULL; + free(ctx->tmpname); + ctx->tmpname = NULL; + return 0; + + case ZIP_SOURCE_SEEK: { + zip_int64_t new_offset = zip_source_seek_compute_offset(ctx->offset, ctx->len, data, len, &ctx->error); + + if (new_offset < 0) { + return -1; + } + + /* The actual offset inside the file must be representable as zip_int64_t. */ + if (new_offset > ZIP_INT64_MAX - (zip_int64_t)ctx->start) { + zip_error_set(&ctx->error, ZIP_ER_SEEK, EOVERFLOW); + return -1; + } + + ctx->offset = (zip_uint64_t)new_offset; + + if (ctx->ops->seek(ctx, ctx->f, (zip_int64_t)(ctx->offset + ctx->start), SEEK_SET) == false) { + return -1; + } + return 0; + } + + case ZIP_SOURCE_SEEK_WRITE: { + zip_source_args_seek_t *args; + + args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error); + if (args == NULL) { + return -1; + } + + if (ctx->ops->seek(ctx, ctx->fout, args->offset, args->whence) == false) { + return -1; + } + return 0; + } + + case ZIP_SOURCE_STAT: { + if (len < sizeof(ctx->st)) + return -1; + + if (zip_error_code_zip(&ctx->stat_error) != 0) { + zip_error_set(&ctx->error, zip_error_code_zip(&ctx->stat_error), zip_error_code_system(&ctx->stat_error)); + return -1; + } + + memcpy(data, &ctx->st, sizeof(ctx->st)); + return sizeof(ctx->st); + } + + case ZIP_SOURCE_SUPPORTS: + return ctx->supports; + + case ZIP_SOURCE_TELL: + return (zip_int64_t)ctx->offset; + + case ZIP_SOURCE_TELL_WRITE: + return ctx->ops->tell(ctx, ctx->fout); + + case ZIP_SOURCE_WRITE: + return ctx->ops->write(ctx, data, len); + + default: + zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0); + return -1; + } +} diff --git a/Sources/libzip/src/zip_source_file_stdio.c b/Sources/libzip/src/zip_source_file_stdio.c new file mode 100644 index 0000000..4a22f78 --- /dev/null +++ b/Sources/libzip/src/zip_source_file_stdio.c @@ -0,0 +1,208 @@ +/* + zip_source_file_stdio.c -- read-only stdio file source implementation + 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 + + 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 "zipint.h" + +#include "zip_source_file.h" +#include "zip_source_file_stdio.h" + +#include +#include +#include +#include + +#ifdef _WIN32 +#ifndef S_IWUSR +#define S_IWUSR _S_IWRITE +#endif +#endif + +/* clang-format off */ +static zip_source_file_operations_t ops_stdio_read = { + _zip_stdio_op_close, + NULL, + NULL, + NULL, + NULL, + _zip_stdio_op_read, + NULL, + NULL, + _zip_stdio_op_seek, + _zip_stdio_op_stat, + NULL, + _zip_stdio_op_tell, + NULL +}; +/* clang-format on */ + + +ZIP_EXTERN zip_source_t * +zip_source_filep(zip_t *za, FILE *file, zip_uint64_t start, zip_int64_t len) { + if (za == NULL) { + return NULL; + } + + return zip_source_filep_create(file, start, len, &za->error); +} + + +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) { + zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + + return zip_source_file_common_new(NULL, file, start, length, NULL, &ops_stdio_read, NULL, error); +} + + +void +_zip_stdio_op_close(zip_source_file_context_t *ctx) { + fclose((FILE *)ctx->f); +} + + +zip_int64_t +_zip_stdio_op_read(zip_source_file_context_t *ctx, void *buf, zip_uint64_t len) { + size_t i; + if (len > SIZE_MAX) { + len = SIZE_MAX; + } + + if ((i = fread(buf, 1, (size_t)len, ctx->f)) == 0) { + if (ferror((FILE *)ctx->f)) { + zip_error_set(&ctx->error, ZIP_ER_READ, errno); + return -1; + } + } + + return (zip_int64_t)i; +} + + +bool +_zip_stdio_op_seek(zip_source_file_context_t *ctx, void *f, zip_int64_t offset, int whence) { +#if ZIP_FSEEK_MAX > ZIP_INT64_MAX + if (offset > ZIP_FSEEK_MAX || offset < ZIP_FSEEK_MIN) { + zip_error_set(&ctx->error, ZIP_ER_SEEK, EOVERFLOW); + return false; + } +#endif + + if (fseeko((FILE *)f, (off_t)offset, whence) < 0) { + zip_error_set(&ctx->error, ZIP_ER_SEEK, errno); + return false; + } + return true; +} + + +bool +_zip_stdio_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st) { + struct stat sb; + + int ret; + + if (ctx->fname) { + ret = stat(ctx->fname, &sb); + } + else { + ret = fstat(fileno((FILE *)ctx->f), &sb); + } + + if (ret < 0) { + if (errno == ENOENT) { + st->exists = false; + return true; + } + zip_error_set(&ctx->error, ZIP_ER_READ, errno); + return false; + } + + st->size = (zip_uint64_t)sb.st_size; + st->mtime = sb.st_mtime; + + st->regular_file = S_ISREG(sb.st_mode); + st->exists = true; + + /* We're using UNIX file API, even on Windows; thus, we supply external file attributes with Unix values. */ + /* TODO: This could be improved on Windows by providing Windows-specific file attributes */ + ctx->attributes.valid = ZIP_FILE_ATTRIBUTES_HOST_SYSTEM | ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES; + ctx->attributes.host_system = ZIP_OPSYS_UNIX; + ctx->attributes.external_file_attributes = (((zip_uint32_t)sb.st_mode) << 16) | ((sb.st_mode & S_IWUSR) ? 0 : 1); + + return true; +} + + +zip_int64_t +_zip_stdio_op_tell(zip_source_file_context_t *ctx, void *f) { + off_t offset = ftello((FILE *)f); + + if (offset < 0) { + zip_error_set(&ctx->error, ZIP_ER_SEEK, errno); + } + + 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/Sources/libzip/src/zip_source_get_compression_flags.c b/Sources/libzip/src/zip_source_file_stdio.h similarity index 67% rename from Sources/libzip/src/zip_source_get_compression_flags.c rename to Sources/libzip/src/zip_source_file_stdio.h index 7e04bed..1bf698c 100644 --- a/Sources/libzip/src/zip_source_get_compression_flags.c +++ b/Sources/libzip/src/zip_source_file_stdio.h @@ -1,6 +1,9 @@ +#ifndef _HAD_ZIP_SOURCE_FILE_STDIO_H +#define _HAD_ZIP_SOURCE_FILE_STDIO_H + /* - zip_source_get_compression_flags.c -- get compression flags for entry - Copyright (C) 2017-2019 Dieter Baron and Thomas Klausner + zip_source_file_stdio.h -- common header for stdio file implementation + 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 @@ -31,27 +34,14 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include + +void _zip_stdio_op_close(zip_source_file_context_t *ctx); +zip_int64_t _zip_stdio_op_read(zip_source_file_context_t *ctx, void *buf, zip_uint64_t len); +bool _zip_stdio_op_seek(zip_source_file_context_t *ctx, void *f, zip_int64_t offset, int whence); +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); -#include "zipint.h" - -#define ZIP_COMPRESSION_BITFLAG_MAX 3 - -zip_int8_t -zip_source_get_compression_flags(zip_source_t *src) { - while (src) { - if ((src->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_GET_COMPRESSION_FLAGS))) { - zip_int64_t ret = _zip_source_call(src, NULL, 0, ZIP_SOURCE_GET_COMPRESSION_FLAGS); - if (ret < 0) { - return -1; - } - if (ret > ZIP_COMPRESSION_BITFLAG_MAX) { - zip_error_set(&src->error, ZIP_ER_INTERNAL, 0); - return -1; - } - return (zip_int8_t)ret; - } - src = src->src; - } - - return 0; -} +#endif /* _HAD_ZIP_SOURCE_FILE_STDIO_H */ diff --git a/Sources/libzip/src/zip_source_file_stdio_named.c b/Sources/libzip/src/zip_source_file_stdio_named.c new file mode 100644 index 0000000..dae8177 --- /dev/null +++ b/Sources/libzip/src/zip_source_file_stdio_named.c @@ -0,0 +1,313 @@ +/* + zip_source_file_stdio_named.c -- source for stdio file opened by 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 "zipint.h" + +#include "zip_source_file.h" +#include "zip_source_file_stdio.h" + +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_CLONEFILE +#include +#include +#define CAN_CLONE +#endif +#ifdef HAVE_FICLONERANGE +#include +#include +#define CAN_CLONE +#endif + +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 +static zip_int64_t _zip_stdio_op_create_temp_output_cloning(zip_source_file_context_t *ctx, zip_uint64_t offset); +#endif +static bool _zip_stdio_op_open(zip_source_file_context_t *ctx); +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); + +/* clang-format off */ +static zip_source_file_operations_t ops_stdio_named = { + _zip_stdio_op_close, + _zip_stdio_op_commit_write, + _zip_stdio_op_create_temp_output, +#ifdef CAN_CLONE + _zip_stdio_op_create_temp_output_cloning, +#else + NULL, +#endif + _zip_stdio_op_open, + _zip_stdio_op_read, + _zip_stdio_op_remove, + _zip_stdio_op_rollback_write, + _zip_stdio_op_seek, + _zip_stdio_op_stat, + _zip_stdio_op_strdup, + _zip_stdio_op_tell, + _zip_stdio_op_write +}; +/* clang-format on */ + +ZIP_EXTERN zip_source_t * +zip_source_file(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t len) { + if (za == NULL) + return NULL; + + return zip_source_file_create(fname, start, len, &za->error); +} + + +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) { + zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + + return zip_source_file_common_new(fname, NULL, start, length, NULL, &ops_stdio_named, NULL, error); +} + + +static zip_int64_t +_zip_stdio_op_commit_write(zip_source_file_context_t *ctx) { + if (fclose(ctx->fout) < 0) { + zip_error_set(&ctx->error, ZIP_ER_WRITE, errno); + return -1; + } + if (rename(ctx->tmpname, ctx->fname) < 0) { + zip_error_set(&ctx->error, ZIP_ER_RENAME, errno); + return -1; + } + + return 0; +} + + +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); + return -1; + } + + if ((tfp = fdopen(tfd, "r+b")) == NULL) { + zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); + close(tfd); + (void)remove(temp); + free(temp); + 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); + return -1; + } +#endif + + if (clonefile(ctx->fname, temp, 0) < 0) { + zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); + free(temp); + return -1; + } + if ((tfp = _zip_fopen_close_on_exec(temp, true)) == NULL) { + zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); + (void)remove(temp); + free(temp); + return -1; + } +#else + { + 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); + 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; + if (range.src_length > st.st_size) { + range.src_length = 0; + } + range.dest_offset = 0; + if (ioctl(fd, FICLONERANGE, &range) < 0) { + zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); + (void)close(fd); + (void)remove(temp); + free(temp); + 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); + return -1; + } + } +#endif + + if (ftruncate(fileno(tfp), (off_t)offset) < 0) { + (void)fclose(tfp); + (void)remove(temp); + free(temp); + 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); + } + + ctx->fout = tfp; + ctx->tmpname = temp; + + return 0; +} +#endif + +static bool +_zip_stdio_op_open(zip_source_file_context_t *ctx) { + if ((ctx->f = _zip_fopen_close_on_exec(ctx->fname, false)) == NULL) { + zip_error_set(&ctx->error, ZIP_ER_OPEN, errno); + return false; + } + return true; +} + + +static zip_int64_t +_zip_stdio_op_remove(zip_source_file_context_t *ctx) { + if (remove(ctx->fname) < 0) { + zip_error_set(&ctx->error, ZIP_ER_REMOVE, errno); + return -1; + } + return 0; +} + + +static void +_zip_stdio_op_rollback_write(zip_source_file_context_t *ctx) { + if (ctx->fout) { + fclose(ctx->fout); + } + (void)remove(ctx->tmpname); +} + +static char * +_zip_stdio_op_strdup(zip_source_file_context_t *ctx, const char *string) { + return strdup(string); +} + + +static zip_int64_t +_zip_stdio_op_write(zip_source_file_context_t *ctx, const void *data, zip_uint64_t len) { + size_t ret; + + clearerr((FILE *)ctx->fout); + ret = fwrite(data, 1, len, (FILE *)ctx->fout); + if (ret != len || ferror((FILE *)ctx->fout)) { + zip_error_set(&ctx->error, ZIP_ER_WRITE, errno); + return -1; + } + + return (zip_int64_t)ret; +} diff --git a/Sources/libzip/src/zip_source_file_win32.c b/Sources/libzip/src/zip_source_file_win32.c new file mode 100644 index 0000000..2fe838f --- /dev/null +++ b/Sources/libzip/src/zip_source_file_win32.c @@ -0,0 +1,230 @@ +/* + zip_source_file_win32.c -- read-only Windows file source implementation + 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 bool _zip_win32_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st); + +static bool _zip_stat_win32(zip_source_file_context_t *ctx, zip_source_file_stat_t *st, HANDLE h); + +static zip_source_file_operations_t ops_win32_read = { + _zip_win32_op_close, + NULL, + NULL, + NULL, + NULL, + _zip_win32_op_read, + NULL, + NULL, + _zip_win32_op_seek, + _zip_win32_op_stat, + NULL, + _zip_win32_op_tell, + NULL +}; + + +ZIP_EXTERN zip_source_t * +zip_source_win32handle(zip_t *za, HANDLE h, zip_uint64_t start, zip_int64_t len) { + if (za == NULL) { + return NULL; + } + + return zip_source_win32handle_create(h, start, len, &za->error); +} + + +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) { + zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + + return zip_source_file_common_new(NULL, h, start, length, NULL, &ops_win32_read, NULL, error); +} + + +void +_zip_win32_op_close(zip_source_file_context_t *ctx) { + CloseHandle((HANDLE)ctx->f); +} + + +zip_int64_t +_zip_win32_op_read(zip_source_file_context_t *ctx, void *buf, zip_uint64_t len) { + DWORD i; + + /* TODO: cap len to "DWORD_MAX" */ + if (!ReadFile((HANDLE)ctx->f, buf, (DWORD)len, &i, NULL)) { + zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError())); + return -1; + } + + return (zip_int64_t)i; +} + + +bool +_zip_win32_op_seek(zip_source_file_context_t *ctx, void *f, zip_int64_t offset, int whence) { + LARGE_INTEGER li; + DWORD method; + + switch (whence) { + case SEEK_SET: + method = FILE_BEGIN; + break; + case SEEK_END: + method = FILE_END; + break; + case SEEK_CUR: + method = FILE_CURRENT; + break; + default: + zip_error_set(&ctx->error, ZIP_ER_SEEK, EINVAL); + return -1; + } + + li.QuadPart = (LONGLONG)offset; + if (!SetFilePointerEx((HANDLE)f, li, NULL, method)) { + zip_error_set(&ctx->error, ZIP_ER_SEEK, _zip_win32_error_to_errno(GetLastError())); + return false; + } + + return true; +} + + +static bool +_zip_win32_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st) { + return _zip_stat_win32(ctx, st, (HANDLE)ctx->f); +} + + +zip_int64_t +_zip_win32_op_tell(zip_source_file_context_t *ctx, void *f) { + LARGE_INTEGER zero; + LARGE_INTEGER new_offset; + + zero.QuadPart = 0; + if (!SetFilePointerEx((HANDLE)f, zero, &new_offset, FILE_CURRENT)) { + zip_error_set(&ctx->error, ZIP_ER_SEEK, _zip_win32_error_to_errno(GetLastError())); + return -1; + } + + return (zip_int64_t)new_offset.QuadPart; +} + + +int +_zip_win32_error_to_errno(DWORD win32err) { + /* Note: This list isn't exhaustive, but should cover common cases. */ + switch (win32err) { + case ERROR_INVALID_PARAMETER: + return EINVAL; + case ERROR_FILE_NOT_FOUND: + return ENOENT; + case ERROR_INVALID_HANDLE: + return EBADF; + case ERROR_ACCESS_DENIED: + return EACCES; + case ERROR_FILE_EXISTS: + return EEXIST; + case ERROR_TOO_MANY_OPEN_FILES: + return EMFILE; + case ERROR_DISK_FULL: + return ENOSPC; + default: + return 10000 + win32err; + } +} + + +static bool +_zip_stat_win32(zip_source_file_context_t *ctx, zip_source_file_stat_t *st, HANDLE h) { + FILETIME mtimeft; + time_t mtime; + LARGE_INTEGER size; + + if (!GetFileTime(h, NULL, NULL, &mtimeft)) { + 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) { + zip_error_set(&ctx->error, ZIP_ER_READ, ERANGE); + return false; + } + + st->exists = true; + st->mtime = mtime; + + if (GetFileType(h) == FILE_TYPE_DISK) { + st->regular_file = 1; + + if (!GetFileSizeEx(h, &size)) { + zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError())); + return false; + } + + st->size = (zip_uint64_t)size.QuadPart; + } + + /* TODO: fill in ctx->attributes */ + + return true; +} + + +bool +_zip_filetime_to_time_t(FILETIME ft, time_t *t) { + /* + Inspired by http://stackoverflow.com/questions/6161776/convert-windows-filetime-to-second-in-unix-linux + */ + const zip_int64_t WINDOWS_TICK = 10000000LL; + const zip_int64_t SEC_TO_UNIX_EPOCH = 11644473600LL; + ULARGE_INTEGER li; + zip_int64_t secs; + time_t temp; + + li.LowPart = ft.dwLowDateTime; + li.HighPart = ft.dwHighDateTime; + secs = (li.QuadPart / WINDOWS_TICK - SEC_TO_UNIX_EPOCH); + + temp = (time_t)secs; + if (secs != (zip_int64_t)temp) { + return false; + } + + *t = temp; + return true; +} diff --git a/Sources/libzip/src/zip_source_file_win32.h b/Sources/libzip/src/zip_source_file_win32.h new file mode 100644 index 0000000..5092e63 --- /dev/null +++ b/Sources/libzip/src/zip_source_file_win32.h @@ -0,0 +1,74 @@ +#ifndef _HAD_ZIP_SOURCE_FILE_WIN32_H +#define _HAD_ZIP_SOURCE_FILE_WIN32_H + +/* + zip_source_file_win32.h -- common header for Windows file implementation + 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 + + 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. +*/ + +/* 0x0501 => Windows XP; needs to be at least this value because of GetFileSizeEx */ +#if !defined(MS_UWP) && !defined(_WIN32_WINNT) +#define _WIN32_WINNT 0x0501 +#endif + +#include + +#include + +#include "zipint.h" + +#include "zip_source_file.h" + +struct zip_win32_file_operations { + char *(*allocate_tempname)(const char *name, size_t extra_chars, size_t *lengthp); + HANDLE (__stdcall *create_file)(const void *name, DWORD access, DWORD share_mode, PSECURITY_ATTRIBUTES security_attributes, DWORD creation_disposition, DWORD file_attributes, HANDLE template_file); + BOOL (__stdcall *delete_file)(const void *name); + DWORD (__stdcall *get_file_attributes)(const void *name); + BOOL (__stdcall *get_file_attributes_ex)(const void *name, GET_FILEEX_INFO_LEVELS info_level, void *information); + void (*make_tempname)(char *buf, size_t len, const char *name, zip_uint32_t i); + BOOL (__stdcall *move_file)(const void *from, const void *to, DWORD flags); + BOOL (__stdcall *set_file_attributes)(const void *name, DWORD attributes); + char *(*string_duplicate)(const char *string); +}; + +typedef struct zip_win32_file_operations zip_win32_file_operations_t; + +extern zip_source_file_operations_t _zip_source_file_win32_named_ops; + +void _zip_win32_op_close(zip_source_file_context_t *ctx); +zip_int64_t _zip_win32_op_read(zip_source_file_context_t *ctx, void *buf, zip_uint64_t len); +bool _zip_win32_op_seek(zip_source_file_context_t *ctx, void *f, zip_int64_t offset, int whence); +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); + +#endif /* _HAD_ZIP_SOURCE_FILE_WIN32_H */ diff --git a/Sources/libzip/src/zip_source_file_win32_ansi.c b/Sources/libzip/src/zip_source_file_win32_ansi.c new file mode 100644 index 0000000..573b74e --- /dev/null +++ b/Sources/libzip/src/zip_source_file_win32_ansi.c @@ -0,0 +1,81 @@ +/* + 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); + +zip_win32_file_operations_t ops_ansi = { + ansi_allocate_tempname, + CreateFileA, + DeleteFileA, + GetFileAttributesA, + GetFileAttributesExA, + ansi_make_tempname, + MoveFileExA, + SetFileAttributesA, + strdup +}; + +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 < -1) { + 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(buf, len, "%s.%08x", name, i); +} diff --git a/Sources/libzip/src/zip_source_file_win32_named.c b/Sources/libzip/src/zip_source_file_win32_named.c new file mode 100644 index 0000000..9591b26 --- /dev/null +++ b/Sources/libzip/src/zip_source_file_win32_named.c @@ -0,0 +1,266 @@ +/* + zip_source_file_win32_named.c -- source for Windows file opened by 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 zip_int64_t _zip_win32_named_op_commit_write(zip_source_file_context_t *ctx); +static zip_int64_t _zip_win32_named_op_create_temp_output(zip_source_file_context_t *ctx); +static bool _zip_win32_named_op_open(zip_source_file_context_t *ctx); +static zip_int64_t _zip_win32_named_op_remove(zip_source_file_context_t *ctx); +static void _zip_win32_named_op_rollback_write(zip_source_file_context_t *ctx); +static bool _zip_win32_named_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st); +static char *_zip_win32_named_op_string_duplicate(zip_source_file_context_t *ctx, const char *string); +static zip_int64_t _zip_win32_named_op_write(zip_source_file_context_t *ctx, const void *data, zip_uint64_t len); + +static HANDLE win32_named_open(zip_source_file_context_t *ctx, const char *name, bool temporary, PSECURITY_ATTRIBUTES security_attributes); + +/* clang-format off */ +zip_source_file_operations_t _zip_source_file_win32_named_ops = { + _zip_win32_op_close, + _zip_win32_named_op_commit_write, + _zip_win32_named_op_create_temp_output, + NULL, + _zip_win32_named_op_open, + _zip_win32_op_read, + _zip_win32_named_op_remove, + _zip_win32_named_op_rollback_write, + _zip_win32_op_seek, + _zip_win32_named_op_stat, + _zip_win32_named_op_string_duplicate, + _zip_win32_op_tell, + _zip_win32_named_op_write +}; +/* clang-format on */ + +static zip_int64_t +_zip_win32_named_op_commit_write(zip_source_file_context_t *ctx) { + zip_win32_file_operations_t *file_ops = (zip_win32_file_operations_t *)ctx->ops_userdata; + + if (!CloseHandle((HANDLE)ctx->fout)) { + zip_error_set(&ctx->error, ZIP_ER_WRITE, _zip_win32_error_to_errno(GetLastError())); + return -1; + } + + DWORD attributes = file_ops->get_file_attributes(ctx->tmpname); + if (attributes == INVALID_FILE_ATTRIBUTES) { + zip_error_set(&ctx->error, ZIP_ER_RENAME, _zip_win32_error_to_errno(GetLastError())); + return -1; + } + + if (attributes & FILE_ATTRIBUTE_TEMPORARY) { + if (!file_ops->set_file_attributes(ctx->tmpname, attributes & ~FILE_ATTRIBUTE_TEMPORARY)) { + zip_error_set(&ctx->error, ZIP_ER_RENAME, _zip_win32_error_to_errno(GetLastError())); + return -1; + } + } + + if (!file_ops->move_file(ctx->tmpname, ctx->fname, MOVEFILE_REPLACE_EXISTING)) { + zip_error_set(&ctx->error, ZIP_ER_RENAME, _zip_win32_error_to_errno(GetLastError())); + return -1; + } + + return 0; +} + +static zip_int64_t +_zip_win32_named_op_create_temp_output(zip_source_file_context_t *ctx) { + zip_win32_file_operations_t *file_ops = (zip_win32_file_operations_t *)ctx->ops_userdata; + + zip_uint32_t value, i; + HANDLE th = INVALID_HANDLE_VALUE; + void *temp = NULL; + PSECURITY_DESCRIPTOR psd = NULL; + PSECURITY_ATTRIBUTES psa = NULL; + SECURITY_ATTRIBUTES sa; + SECURITY_INFORMATION si; + DWORD success; + PACL dacl = NULL; + char *tempname = NULL; + size_t tempname_size = 0; + + if ((HANDLE)ctx->f != INVALID_HANDLE_VALUE && GetFileType((HANDLE)ctx->f) == FILE_TYPE_DISK) { + si = DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION; + success = GetSecurityInfo((HANDLE)ctx->f, SE_FILE_OBJECT, si, NULL, NULL, &dacl, NULL, &psd); + if (success == ERROR_SUCCESS) { + sa.nLength = sizeof(SECURITY_ATTRIBUTES); + sa.bInheritHandle = FALSE; + sa.lpSecurityDescriptor = psd; + psa = &sa; + } + } + + #ifndef MS_UWP + value = GetTickCount(); +#else + value = (zip_uint32_t)(GetTickCount64() & 0xffffffff); +#endif + + if ((tempname = file_ops->allocate_tempname(ctx->fname, 10, &tempname_size)) == NULL) { + zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0); + return -1; + } + + for (i = 0; i < 1024 && th == INVALID_HANDLE_VALUE; i++) { + file_ops->make_tempname(tempname, tempname_size, ctx->fname, value + i); + + th = win32_named_open(ctx, tempname, true, psa); + if (th == INVALID_HANDLE_VALUE && GetLastError() != ERROR_FILE_EXISTS) + break; + } + + if (th == INVALID_HANDLE_VALUE) { + free(tempname); + LocalFree(psd); + zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, _zip_win32_error_to_errno(GetLastError())); + return -1; + } + + LocalFree(psd); + ctx->fout = th; + ctx->tmpname = tempname; + + return 0; +} + + +static bool +_zip_win32_named_op_open(zip_source_file_context_t *ctx) { + HANDLE h = win32_named_open(ctx, ctx->fname, false, NULL); + + if (h == INVALID_HANDLE_VALUE) { + return false; + } + + ctx->f = h; + return true; +} + + +static zip_int64_t +_zip_win32_named_op_remove(zip_source_file_context_t *ctx) { + zip_win32_file_operations_t *file_ops = (zip_win32_file_operations_t *)ctx->ops_userdata; + + if (!file_ops->delete_file(ctx->fname)) { + zip_error_set(&ctx->error, ZIP_ER_REMOVE, _zip_win32_error_to_errno(GetLastError())); + return -1; + } + + return 0; +} + + +static void +_zip_win32_named_op_rollback_write(zip_source_file_context_t *ctx) { + zip_win32_file_operations_t *file_ops = (zip_win32_file_operations_t *)ctx->ops_userdata; + + if (ctx->fout) { + CloseHandle((HANDLE)ctx->fout); + } + file_ops->delete_file(ctx->tmpname); +} + + +static bool +_zip_win32_named_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st) { + zip_win32_file_operations_t *file_ops = (zip_win32_file_operations_t *)ctx->ops_userdata; + + WIN32_FILE_ATTRIBUTE_DATA file_attributes; + + if (!file_ops->get_file_attributes_ex(ctx->fname, GetFileExInfoStandard, &file_attributes)) { + DWORD error = GetLastError(); + if (error == ERROR_FILE_NOT_FOUND) { + st->exists = false; + return true; + } + zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(error)); + return false; + } + + st->exists = true; + st->regular_file = true; /* TODO: Is this always right? How to determine without a HANDLE? */ + if (!_zip_filetime_to_time_t(file_attributes.ftLastWriteTime, &st->mtime)) { + zip_error_set(&ctx->error, ZIP_ER_READ, ERANGE); + return false; + } + st->size = ((zip_uint64_t)file_attributes.nFileSizeHigh << 32) | file_attributes.nFileSizeLow; + + /* TODO: fill in ctx->attributes */ + + return true; +} + + +static char * +_zip_win32_named_op_string_duplicate(zip_source_file_context_t *ctx, const char *string) { + zip_win32_file_operations_t *file_ops = (zip_win32_file_operations_t *)ctx->ops_userdata; + + return file_ops->string_duplicate(string); +} + + +static zip_int64_t +_zip_win32_named_op_write(zip_source_file_context_t *ctx, const void *data, zip_uint64_t len) { + DWORD ret; + if (!WriteFile((HANDLE)ctx->fout, data, (DWORD)len, &ret, NULL) || ret != len) { + zip_error_set(&ctx->error, ZIP_ER_WRITE, _zip_win32_error_to_errno(GetLastError())); + return -1; + } + + return (zip_int64_t)ret; +} + + +static HANDLE +win32_named_open(zip_source_file_context_t *ctx, const char *name, bool temporary, PSECURITY_ATTRIBUTES security_attributes) { + zip_win32_file_operations_t *file_ops = (zip_win32_file_operations_t *)ctx->ops_userdata; + + DWORD access = GENERIC_READ; + DWORD share_mode = FILE_SHARE_READ | FILE_SHARE_WRITE; + DWORD creation_disposition = OPEN_EXISTING; + DWORD file_attributes = FILE_ATTRIBUTE_NORMAL; + + if (temporary) { + access = GENERIC_READ | GENERIC_WRITE; + share_mode = FILE_SHARE_READ; + creation_disposition = CREATE_NEW; + file_attributes = FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY; + } + + HANDLE h = file_ops->create_file(name, access, share_mode, security_attributes, creation_disposition, file_attributes, NULL); + + if (h == INVALID_HANDLE_VALUE) { + zip_error_set(&ctx->error, ZIP_ER_OPEN, _zip_win32_error_to_errno(GetLastError())); + } + + return h; +} diff --git a/Sources/libzip/src/zip_source_file_win32_utf16.c b/Sources/libzip/src/zip_source_file_win32_utf16.c new file mode 100644 index 0000000..3fa0aa1 --- /dev/null +++ b/Sources/libzip/src/zip_source_file_win32_utf16.c @@ -0,0 +1,108 @@ +/* + zip_source_file_win32_utf16.c -- source for Windows file opened by UTF-16 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 *utf16_allocate_tempname(const char *name, size_t extra_chars, size_t *lengthp); +static HANDLE __stdcall utf16_create_file(const char *name, DWORD access, DWORD share_mode, PSECURITY_ATTRIBUTES security_attributes, DWORD creation_disposition, DWORD file_attributes, HANDLE template_file); +static void utf16_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i); +static char *utf16_strdup(const char *string); + +zip_win32_file_operations_t ops_utf16 = { + utf16_allocate_tempname, + utf16_create_file, + DeleteFileW, + GetFileAttributesW, + GetFileAttributesExW, + utf16_make_tempname, + MoveFileExW, + SetFileAttributesW, + utf16_strdup +}; + +ZIP_EXTERN zip_source_t * +zip_source_win32w(zip_t *za, const wchar_t *fname, zip_uint64_t start, zip_int64_t len) { + if (za == NULL) + return NULL; + + return zip_source_win32w_create(fname, start, len, &za->error); +} + + +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) { + zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + + + return zip_source_file_common_new((const char *)fname, NULL, start, length, NULL, &_zip_source_file_win32_named_ops, &ops_utf16, error); +} + + +static char * +utf16_allocate_tempname(const char *name, size_t extra_chars, size_t *lengthp) { + *lengthp = wcslen((const wchar_t *)name) + extra_chars; + return (char *)malloc(*lengthp * sizeof(wchar_t)); +} + + +static HANDLE __stdcall +utf16_create_file(const char *name, DWORD access, DWORD share_mode, PSECURITY_ATTRIBUTES security_attributes, DWORD creation_disposition, DWORD file_attributes, HANDLE template_file) { +#ifdef MS_UWP + CREATEFILE2_EXTENDED_PARAMETERS extParams = {0}; + extParams.dwFileAttributes = file_attributes; + extParams.dwFileFlags = FILE_FLAG_RANDOM_ACCESS; + extParams.dwSecurityQosFlags = SECURITY_ANONYMOUS; + extParams.dwSize = sizeof(extParams); + extParams.hTemplateFile = template_file; + extParams.lpSecurityAttributes = security_attributes; + + return CreateFile2((const wchar_t *)name, access, share_mode, creation_disposition, &extParams); +#else + return CreateFileW((const wchar_t *)name, access, share_mode, security_attributes, creation_disposition, file_attributes, template_file); +#endif +} + + +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); +} + + +static char * +utf16_strdup(const char *string) { + return (char *)_wcsdup((const wchar_t *)string); +} diff --git a/Sources/libzip/src/zip_source_win32utf8.c b/Sources/libzip/src/zip_source_file_win32_utf8.c similarity index 84% rename from Sources/libzip/src/zip_source_win32utf8.c rename to Sources/libzip/src/zip_source_file_win32_utf8.c index 3d2ce39..4f258bc 100644 --- a/Sources/libzip/src/zip_source_win32utf8.c +++ b/Sources/libzip/src/zip_source_file_win32_utf8.c @@ -1,6 +1,6 @@ /* - zip_source_win32utf8.c -- create data source from Windows file (UTF-8) - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner + zip_source_file_win32_ansi.c -- source for Windows file opened by UTF-8 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 @@ -31,18 +31,14 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -#include - -#include "zipint.h" -#include "zipwin32.h" - +#include "zip_source_file_win32.h" ZIP_EXTERN zip_source_t * zip_source_file(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t len) { - if (za == NULL) - return NULL; - + if (za == NULL) { + return NULL; + } + return zip_source_file_create(fname, start, len, &za->error); } @@ -54,24 +50,24 @@ zip_source_file_create(const char *fname, zip_uint64_t start, zip_int64_t length zip_source_t *source; if (fname == NULL || length < -1) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; + zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; } /* Convert fname from UTF-8 to Windows-friendly UTF-16. */ size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, fname, -1, NULL, 0); if (size == 0) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; + zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; } if ((wfname = (wchar_t *)malloc(sizeof(wchar_t) * size)) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return NULL; + zip_error_set(error, ZIP_ER_MEMORY, 0); + return NULL; } MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, fname, -1, wfname, size); source = zip_source_win32w_create(wfname, start, length, error); - + free(wfname); return source; } diff --git a/Sources/libzip/src/zip_source_filep.c b/Sources/libzip/src/zip_source_filep.c deleted file mode 100644 index 1d89c1d..0000000 --- a/Sources/libzip/src/zip_source_filep.c +++ /dev/null @@ -1,664 +0,0 @@ -/* - zip_source_filep.c -- create data source from FILE * - Copyright (C) 1999-2019 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 -#include - -#include "zipint.h" - -#ifdef HAVE_UNISTD_H -#include -#endif - -#ifdef HAVE_CLONEFILE -#include -#include -#define CAN_CLONE -#endif -#ifdef HAVE_FICLONERANGE -#include -#include -#define CAN_CLONE -#endif - -struct read_file { - zip_error_t error; /* last error information */ - zip_int64_t supports; - - /* reading */ - char *fname; /* name of file to read from */ - FILE *f; /* file to read from */ - struct zip_stat st; /* stat information passed in */ - zip_error_t stat_error; /* error returned for stat */ - zip_uint64_t start; /* start offset of data to read */ - zip_uint64_t end; /* end offset of data to read relative to start, 0 for up to EOF */ - zip_uint64_t current; /* current offset relative to start (0 is beginning of part we read) */ - - /* writing */ - char *tmpname; - FILE *fout; -}; - -static zip_int64_t read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd); -#ifdef CAN_CLONE -static zip_int64_t create_temp_output_cloning(struct read_file *ctx, zip_uint64_t offset); -#endif -static FILE *_zip_fopen(const char *name, bool writeable); -static int _zip_fseek_u(FILE *f, zip_uint64_t offset, int whence, zip_error_t *error); -static int _zip_fseek(FILE *f, zip_int64_t offset, int whence, zip_error_t *error); - - -ZIP_EXTERN zip_source_t * -zip_source_filep(zip_t *za, FILE *file, zip_uint64_t start, zip_int64_t len) { - if (za == NULL) - return NULL; - - return zip_source_filep_create(file, start, len, &za->error); -} - - -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) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } - - return _zip_source_file_or_p(NULL, file, start, length, NULL, error); -} - - -zip_source_t * -_zip_source_file_or_p(const char *fname, FILE *file, zip_uint64_t start, zip_int64_t len, const zip_stat_t *st, zip_error_t *error) { - struct read_file *ctx; - zip_source_t *zs; - struct stat sb; - bool stat_valid; - - if (file == NULL && fname == NULL) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } - - if (len < 0) { - len = 0; - } - - if (start > ZIP_INT64_MAX || start + (zip_uint64_t)len < start) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } - - if ((ctx = (struct read_file *)malloc(sizeof(struct read_file))) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return NULL; - } - - ctx->fname = NULL; - if (fname) { - if ((ctx->fname = strdup(fname)) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - free(ctx); - return NULL; - } - } - ctx->f = file; - ctx->start = start; - ctx->end = (zip_uint64_t)len; - if (st) { - memcpy(&ctx->st, st, sizeof(ctx->st)); - ctx->st.name = NULL; - ctx->st.valid &= ~ZIP_STAT_NAME; - } - else { - zip_stat_init(&ctx->st); - } - - if (ctx->end > 0) { - ctx->st.size = ctx->end; - ctx->st.valid |= ZIP_STAT_SIZE; - } - - zip_error_init(&ctx->stat_error); - - ctx->tmpname = NULL; - ctx->fout = NULL; - - zip_error_init(&ctx->error); - - ctx->supports = ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1); - - if (ctx->fname) { - stat_valid = stat(ctx->fname, &sb) >= 0; - - if (!stat_valid) { - if (ctx->start == 0 && ctx->end == 0) { - ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE; - } - } - } - else { - stat_valid = fstat(fileno(ctx->f), &sb) >= 0; - } - - if (!stat_valid) { - zip_error_set(&ctx->stat_error, ZIP_ER_READ, errno); - } - else { - if ((ctx->st.valid & ZIP_STAT_MTIME) == 0) { - ctx->st.mtime = sb.st_mtime; - ctx->st.valid |= ZIP_STAT_MTIME; - } - if (S_ISREG(sb.st_mode)) { - ctx->supports = ZIP_SOURCE_SUPPORTS_SEEKABLE; - - if (ctx->start + ctx->end > (zip_uint64_t)sb.st_size) { - zip_error_set(error, ZIP_ER_INVAL, 0); - free(ctx->fname); - free(ctx); - return NULL; - } - - if (ctx->end == 0) { - ctx->st.size = (zip_uint64_t)sb.st_size - ctx->start; - ctx->st.valid |= ZIP_STAT_SIZE; - - if (ctx->fname && start == 0) { - ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE; - } - } - } - } - - ctx->supports |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ACCEPT_EMPTY); -#ifdef CAN_CLONE - if (ctx->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE)) { - ctx->supports |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE_CLONING); - } -#endif - - if ((zs = zip_source_function_create(read_file, ctx, error)) == NULL) { - free(ctx->fname); - free(ctx); - return NULL; - } - - return zs; -} - - -#ifndef _WIN32 -static int -create_temp_output(struct read_file *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); - return -1; - } - - if ((tfp = fdopen(tfd, "r+b")) == NULL) { - zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); - close(tfd); - (void)remove(temp); - free(temp); - return -1; - } - - ctx->fout = tfp; - ctx->tmpname = temp; - - return 0; -} -#endif - -#ifdef CAN_CLONE -zip_int64_t static create_temp_output_cloning(struct read_file *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); - return -1; - } -#endif - - if (clonefile(ctx->fname, temp, 0) < 0) { - zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); - free(temp); - return -1; - } - if ((tfp = _zip_fopen(temp, true)) == NULL) { - zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); - (void)remove(temp); - free(temp); - return -1; - } -#else - { - 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); - return -1; - } - - if ((fd = mkstemp(temp)) < 0) { - zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); - free(temp); - 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; - if (range.src_length > st.st_size) { - range.src_length = 0; - } - range.dest_offset = 0; - if (ioctl(fd, FICLONERANGE, &range) < 0) { - zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); - (void)close(fd); - (void)remove(temp); - free(temp); - 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); - return -1; - } - } -#endif - - if (ftruncate(fileno(tfp), (off_t)offset) < 0) { - (void)fclose(tfp); - (void)remove(temp); - free(temp); - 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); - } - - ctx->fout = tfp; - ctx->tmpname = temp; - - return 0; -} -#endif - - -static zip_int64_t -read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { - struct read_file *ctx; - char *buf; - zip_uint64_t n; - size_t i; - - ctx = (struct read_file *)state; - buf = (char *)data; - - switch (cmd) { - case ZIP_SOURCE_ACCEPT_EMPTY: - return 0; - - case ZIP_SOURCE_BEGIN_WRITE: -#ifdef _WIN32 - return -1; -#else - if (ctx->fname == NULL) { - zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0); - return -1; - } - return create_temp_output(ctx); -#endif - -#ifdef CAN_CLONE - case ZIP_SOURCE_BEGIN_WRITE_CLONING: - if (ctx->fname == NULL) { - zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0); - return -1; - } - return create_temp_output_cloning(ctx, len); -#endif - - case ZIP_SOURCE_CLOSE: - if (ctx->fname) { - fclose(ctx->f); - ctx->f = NULL; - } - return 0; - - case ZIP_SOURCE_COMMIT_WRITE: { - if (fclose(ctx->fout) < 0) { - ctx->fout = NULL; - zip_error_set(&ctx->error, ZIP_ER_WRITE, errno); - } - ctx->fout = NULL; - if (rename(ctx->tmpname, ctx->fname) < 0) { - zip_error_set(&ctx->error, ZIP_ER_RENAME, errno); - return -1; - } - free(ctx->tmpname); - ctx->tmpname = NULL; - return 0; - } - - case ZIP_SOURCE_ERROR: - return zip_error_to_data(&ctx->error, data, len); - - case ZIP_SOURCE_FREE: - free(ctx->fname); - free(ctx->tmpname); - if (ctx->f) - fclose(ctx->f); - free(ctx); - return 0; - - case ZIP_SOURCE_OPEN: - if (ctx->fname) { - if ((ctx->f = _zip_fopen(ctx->fname, false)) == NULL) { - zip_error_set(&ctx->error, ZIP_ER_OPEN, errno); - return -1; - } - } - - if (ctx->start > 0) { - if (_zip_fseek_u(ctx->f, ctx->start, SEEK_SET, &ctx->error) < 0) { - /* TODO: skip by reading */ - return -1; - } - } - ctx->current = 0; - return 0; - - case ZIP_SOURCE_READ: - if (ctx->end > 0) { - n = ctx->end - ctx->current; - if (n > len) { - n = len; - } - } - else { - n = len; - } - - if (n > SIZE_MAX) - n = SIZE_MAX; - - if ((i = fread(buf, 1, (size_t)n, ctx->f)) == 0) { - if (ferror(ctx->f)) { - zip_error_set(&ctx->error, ZIP_ER_READ, errno); - return -1; - } - } - ctx->current += i; - - return (zip_int64_t)i; - - case ZIP_SOURCE_REMOVE: - if (remove(ctx->fname) < 0) { - zip_error_set(&ctx->error, ZIP_ER_REMOVE, errno); - return -1; - } - return 0; - - case ZIP_SOURCE_ROLLBACK_WRITE: - if (ctx->fout) { - fclose(ctx->fout); - ctx->fout = NULL; - } - (void)remove(ctx->tmpname); - free(ctx->tmpname); - ctx->tmpname = NULL; - return 0; - - case ZIP_SOURCE_SEEK: { - zip_int64_t new_current; - int need_seek; - zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error); - - if (args == NULL) - return -1; - - need_seek = 1; - - switch (args->whence) { - case SEEK_SET: - new_current = args->offset; - break; - - case SEEK_END: - if (ctx->end == 0) { - if (_zip_fseek(ctx->f, args->offset, SEEK_END, &ctx->error) < 0) { - return -1; - } - if ((new_current = ftello(ctx->f)) < 0) { - zip_error_set(&ctx->error, ZIP_ER_SEEK, errno); - return -1; - } - new_current -= (zip_int64_t)ctx->start; - need_seek = 0; - } - else { - new_current = (zip_int64_t)ctx->end + args->offset; - } - break; - - case SEEK_CUR: - new_current = (zip_int64_t)ctx->current + args->offset; - break; - - default: - zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (new_current < 0 || (ctx->end != 0 && (zip_uint64_t)new_current > ctx->end) || (zip_uint64_t)new_current + ctx->start < ctx->start) { - zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); - return -1; - } - - ctx->current = (zip_uint64_t)new_current; - - if (need_seek) { - if (_zip_fseek_u(ctx->f, ctx->current + ctx->start, SEEK_SET, &ctx->error) < 0) { - return -1; - } - } - return 0; - } - - case ZIP_SOURCE_SEEK_WRITE: { - zip_source_args_seek_t *args; - - args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error); - if (args == NULL) { - return -1; - } - - if (_zip_fseek(ctx->fout, args->offset, args->whence, &ctx->error) < 0) { - return -1; - } - return 0; - } - - case ZIP_SOURCE_STAT: { - if (len < sizeof(ctx->st)) - return -1; - - if (zip_error_code_zip(&ctx->stat_error) != 0) { - zip_error_set(&ctx->error, zip_error_code_zip(&ctx->stat_error), zip_error_code_system(&ctx->stat_error)); - return -1; - } - - memcpy(data, &ctx->st, sizeof(ctx->st)); - return sizeof(ctx->st); - } - - case ZIP_SOURCE_SUPPORTS: - return ctx->supports; - - case ZIP_SOURCE_TELL: - return (zip_int64_t)ctx->current; - - case ZIP_SOURCE_TELL_WRITE: { - off_t ret = ftello(ctx->fout); - - if (ret < 0) { - zip_error_set(&ctx->error, ZIP_ER_TELL, errno); - return -1; - } - return ret; - } - - case ZIP_SOURCE_WRITE: { - size_t ret; - - clearerr(ctx->fout); - ret = fwrite(data, 1, len, ctx->fout); - if (ret != len || ferror(ctx->fout)) { - zip_error_set(&ctx->error, ZIP_ER_WRITE, errno); - return -1; - } - - return (zip_int64_t)ret; - } - - default: - zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0); - return -1; - } -} - - -static int -_zip_fseek_u(FILE *f, zip_uint64_t offset, int whence, zip_error_t *error) { - if (offset > ZIP_INT64_MAX) { - zip_error_set(error, ZIP_ER_SEEK, EOVERFLOW); - return -1; - } - return _zip_fseek(f, (zip_int64_t)offset, whence, error); -} - - -static int -_zip_fseek(FILE *f, zip_int64_t offset, int whence, zip_error_t *error) { - if (offset > ZIP_FSEEK_MAX || offset < ZIP_FSEEK_MIN) { - zip_error_set(error, ZIP_ER_SEEK, EOVERFLOW); - return -1; - } - if (fseeko(f, (off_t)offset, whence) < 0) { - zip_error_set(error, ZIP_ER_SEEK, errno); - return -1; - } - return 0; -} - - -/* - * 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(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/Sources/libzip/src/zip_source_get_file_attributes.c b/Sources/libzip/src/zip_source_get_file_attributes.c new file mode 100644 index 0000000..acbede1 --- /dev/null +++ b/Sources/libzip/src/zip_source_get_file_attributes.c @@ -0,0 +1,104 @@ +/* + zip_source_get_file_attributes.c -- get attributes for file from source + 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 + + 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 "zipint.h" + +ZIP_EXTERN void +zip_file_attributes_init(zip_file_attributes_t *attributes) { + attributes->valid = 0; + attributes->version = 1; +} + +int +zip_source_get_file_attributes(zip_source_t *src, zip_file_attributes_t *attributes) { + if (src->source_closed) { + return -1; + } + if (attributes == NULL) { + zip_error_set(&src->error, ZIP_ER_INVAL, 0); + return -1; + } + + zip_file_attributes_init(attributes); + + if (src->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_GET_FILE_ATTRIBUTES)) { + if (_zip_source_call(src, attributes, sizeof(*attributes), ZIP_SOURCE_GET_FILE_ATTRIBUTES) < 0) { + return -1; + } + } + + if (ZIP_SOURCE_IS_LAYERED(src)) { + zip_file_attributes_t lower_attributes; + + if (zip_source_get_file_attributes(src->src, &lower_attributes) < 0) { + _zip_error_set_from_source(&src->error, src->src); + return -1; + } + + if ((lower_attributes.valid & ZIP_FILE_ATTRIBUTES_HOST_SYSTEM) && (attributes->valid & ZIP_FILE_ATTRIBUTES_HOST_SYSTEM) == 0) { + attributes->host_system = lower_attributes.host_system; + attributes->valid |= ZIP_FILE_ATTRIBUTES_HOST_SYSTEM; + } + if ((lower_attributes.valid & ZIP_FILE_ATTRIBUTES_ASCII) && (attributes->valid & ZIP_FILE_ATTRIBUTES_ASCII) == 0) { + attributes->ascii = lower_attributes.ascii; + attributes->valid |= ZIP_FILE_ATTRIBUTES_ASCII; + } + if ((lower_attributes.valid & ZIP_FILE_ATTRIBUTES_VERSION_NEEDED)) { + if (attributes->valid & ZIP_FILE_ATTRIBUTES_VERSION_NEEDED) { + attributes->version_needed = ZIP_MAX(lower_attributes.version_needed, attributes->version_needed); + } + else { + attributes->version_needed = lower_attributes.version_needed; + attributes->valid |= ZIP_FILE_ATTRIBUTES_VERSION_NEEDED; + } + } + if ((lower_attributes.valid & ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES) && (attributes->valid & ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES) == 0) { + attributes->external_file_attributes = lower_attributes.external_file_attributes; + attributes->valid |= ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES; + } + if ((lower_attributes.valid & ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS)) { + if (attributes->valid & ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS) { + attributes->general_purpose_bit_flags &= ~lower_attributes.general_purpose_bit_mask; + attributes->general_purpose_bit_flags |= lower_attributes.general_purpose_bit_flags & lower_attributes.general_purpose_bit_mask; + attributes->general_purpose_bit_mask |= lower_attributes.general_purpose_bit_mask; + } + else { + attributes->valid |= ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS; + attributes->general_purpose_bit_flags = lower_attributes.general_purpose_bit_flags; + attributes->general_purpose_bit_mask = lower_attributes.general_purpose_bit_mask; + } + } + } + + return 0; +} diff --git a/Sources/libzip/src/zip_source_pkware.c b/Sources/libzip/src/zip_source_pkware_decode.c similarity index 63% rename from Sources/libzip/src/zip_source_pkware.c rename to Sources/libzip/src/zip_source_pkware_decode.c index 1b59d7a..d5489a5 100644 --- a/Sources/libzip/src/zip_source_pkware.c +++ b/Sources/libzip/src/zip_source_pkware_decode.c @@ -1,6 +1,6 @@ /* - zip_source_pkware.c -- Traditional PKWARE de/encryption routines - Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner + zip_source_pkware_decode.c -- Traditional PKWARE decryption routines + 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 @@ -38,24 +38,20 @@ #include "zipint.h" struct trad_pkware { + char *password; + zip_pkware_keys_t keys; zip_error_t error; - zip_uint32_t key[3]; }; -#define HEADERLEN 12 -#define KEY0 305419896 -#define KEY1 591751049 -#define KEY2 878082192 - -static void decrypt(struct trad_pkware *, zip_uint8_t *, const zip_uint8_t *, zip_uint64_t, int); static int decrypt_header(zip_source_t *, struct trad_pkware *); static zip_int64_t pkware_decrypt(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t); -static void pkware_free(struct trad_pkware *); +static struct trad_pkware *trad_pkware_new(const char *password, zip_error_t *error); +static void trad_pkware_free(struct trad_pkware *); zip_source_t * -zip_source_pkware(zip_t *za, zip_source_t *src, zip_uint16_t em, int flags, const char *password) { +zip_source_pkware_decode(zip_t *za, zip_source_t *src, zip_uint16_t em, int flags, const char *password) { struct trad_pkware *ctx; zip_source_t *s2; @@ -68,20 +64,12 @@ zip_source_pkware(zip_t *za, zip_source_t *src, zip_uint16_t em, int flags, cons return NULL; } - if ((ctx = (struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + if ((ctx = trad_pkware_new(password, &za->error)) == NULL) { return NULL; } - zip_error_init(&ctx->error); - - ctx->key[0] = KEY0; - ctx->key[1] = KEY1; - ctx->key[2] = KEY2; - decrypt(ctx, NULL, (const zip_uint8_t *)password, strlen(password), 1); - if ((s2 = zip_source_layered(za, src, pkware_decrypt, ctx)) == NULL) { - pkware_free(ctx); + trad_pkware_free(ctx); return NULL; } @@ -89,62 +77,51 @@ zip_source_pkware(zip_t *za, zip_source_t *src, zip_uint16_t em, int flags, cons } -static void -decrypt(struct trad_pkware *ctx, zip_uint8_t *out, const zip_uint8_t *in, zip_uint64_t len, int update_only) { - zip_uint16_t tmp; - zip_uint64_t i; - Bytef b; - - for (i = 0; i < len; i++) { - b = in[i]; - - if (!update_only) { - /* decrypt next byte */ - tmp = (zip_uint16_t)(ctx->key[2] | 2); - tmp = (zip_uint16_t)(((zip_uint32_t)tmp * (tmp ^ 1)) >> 8); - b ^= (Bytef)tmp; - } - - /* store cleartext */ - if (out) - out[i] = b; - - /* update keys */ - ctx->key[0] = (zip_uint32_t)crc32(ctx->key[0] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL; - ctx->key[1] = (ctx->key[1] + (ctx->key[0] & 0xff)) * 134775813 + 1; - b = (Bytef)(ctx->key[1] >> 24); - ctx->key[2] = (zip_uint32_t)crc32(ctx->key[2] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL; - } -} - - static int decrypt_header(zip_source_t *src, struct trad_pkware *ctx) { - zip_uint8_t header[HEADERLEN]; + zip_uint8_t header[ZIP_CRYPTO_PKWARE_HEADERLEN]; struct zip_stat st; zip_int64_t n; - unsigned short dostime, dosdate; - if ((n = zip_source_read(src, header, HEADERLEN)) < 0) { + if ((n = zip_source_read(src, header, ZIP_CRYPTO_PKWARE_HEADERLEN)) < 0) { _zip_error_set_from_source(&ctx->error, src); return -1; } - if (n != HEADERLEN) { + if (n != ZIP_CRYPTO_PKWARE_HEADERLEN) { zip_error_set(&ctx->error, ZIP_ER_EOF, 0); return -1; } - decrypt(ctx, header, header, HEADERLEN, 0); + _zip_pkware_decrypt(&ctx->keys, header, header, ZIP_CRYPTO_PKWARE_HEADERLEN); - if (zip_source_stat(src, &st) < 0) { + if (zip_source_stat(src, &st)) { /* stat failed, skip password validation */ return 0; } - _zip_u2d_time(st.mtime, &dostime, &dosdate); + /* password verification - two ways: + * mtime - InfoZIP way, to avoid computing complete CRC before encrypting data + * CRC - old PKWare way + */ + + bool ok = false; + + if (st.valid & ZIP_STAT_MTIME) { + unsigned short dostime, dosdate; + _zip_u2d_time(st.mtime, &dostime, &dosdate); + if (header[ZIP_CRYPTO_PKWARE_HEADERLEN - 1] == dostime >> 8) { + ok = true; + } + } + + if (st.valid & ZIP_STAT_CRC) { + if (header[ZIP_CRYPTO_PKWARE_HEADERLEN - 1] == st.crc >> 24) { + ok = true; + } + } - if (header[HEADERLEN - 1] != st.crc >> 24 && header[HEADERLEN - 1] != dostime >> 8) { + if (!ok && ((st.valid & (ZIP_STAT_MTIME | ZIP_STAT_CRC)) != 0)) { zip_error_set(&ctx->error, ZIP_ER_WRONGPASSWD, 0); return -1; } @@ -162,8 +139,11 @@ pkware_decrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_so switch (cmd) { case ZIP_SOURCE_OPEN: - if (decrypt_header(src, ctx) < 0) + _zip_pkware_keys_reset(&ctx->keys); + _zip_pkware_decrypt(&ctx->keys, NULL, (const zip_uint8_t *)ctx->password, strlen(ctx->password)); + if (decrypt_header(src, ctx) < 0) { return -1; + } return 0; case ZIP_SOURCE_READ: @@ -172,7 +152,7 @@ pkware_decrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_so return -1; } - decrypt((struct trad_pkware *)ud, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n, 0); + _zip_pkware_decrypt(&ctx->keys, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n); return n; case ZIP_SOURCE_CLOSE: @@ -185,9 +165,9 @@ pkware_decrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_so st->encryption_method = ZIP_EM_NONE; st->valid |= ZIP_STAT_ENCRYPTION_METHOD; - /* TODO: deduce HEADERLEN from size for uncompressed */ - if (st->valid & ZIP_STAT_COMP_SIZE) - st->comp_size -= HEADERLEN; + if (st->valid & ZIP_STAT_COMP_SIZE) { + st->comp_size -= ZIP_CRYPTO_PKWARE_HEADERLEN; + } return 0; } @@ -199,7 +179,7 @@ pkware_decrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_so return zip_error_to_data(&ctx->error, data, len); case ZIP_SOURCE_FREE: - pkware_free(ctx); + trad_pkware_free(ctx); return 0; default: @@ -209,7 +189,33 @@ pkware_decrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_so } +static struct trad_pkware * +trad_pkware_new(const char *password, zip_error_t *error) { + struct trad_pkware *ctx; + + if ((ctx = (struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) { + zip_error_set(error, ZIP_ER_MEMORY, 0); + return NULL; + } + + if ((ctx->password = strdup(password)) == NULL) { + zip_error_set(error, ZIP_ER_MEMORY, 0); + free(ctx); + return NULL; + } + + zip_error_init(&ctx->error); + + return ctx; +} + + static void -pkware_free(struct trad_pkware *ctx) { +trad_pkware_free(struct trad_pkware *ctx) { + if (ctx == NULL) { + return; + } + + free(ctx->password); free(ctx); } diff --git a/Sources/libzip/src/zip_source_pkware_encode.c b/Sources/libzip/src/zip_source_pkware_encode.c new file mode 100644 index 0000000..1e8f42c --- /dev/null +++ b/Sources/libzip/src/zip_source_pkware_encode.c @@ -0,0 +1,249 @@ +/* + zip_source_pkware_encode.c -- Traditional PKWARE encryption routines + 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 + + 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 "zipint.h" + +struct trad_pkware { + char *password; + zip_pkware_keys_t keys; + zip_buffer_t *buffer; + bool eof; + zip_error_t error; +}; + + +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); + + +zip_source_t * +zip_source_pkware_encode(zip_t *za, zip_source_t *src, zip_uint16_t em, int flags, const char *password) { + struct trad_pkware *ctx; + zip_source_t *s2; + + if (password == NULL || src == NULL || em != ZIP_EM_TRAD_PKWARE) { + zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + if (!(flags & ZIP_CODEC_ENCODE)) { + zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0); + return NULL; + } + + if ((ctx = trad_pkware_new(password, &za->error)) == NULL) { + return NULL; + } + + if ((s2 = zip_source_layered(za, src, pkware_encrypt, ctx)) == NULL) { + trad_pkware_free(ctx); + return NULL; + } + + return s2; +} + + +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; + } + + _zip_u2d_time(st.mtime, &dostime, &dosdate); + + if ((ctx->buffer = _zip_buffer_new(NULL, ZIP_CRYPTO_PKWARE_HEADERLEN)) == NULL) { + zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0); + return -1; + } + + header = _zip_buffer_data(ctx->buffer); + + /* 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)) { + zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0); + _zip_buffer_free(ctx->buffer); + ctx->buffer = NULL; + return -1; + } + header[ZIP_CRYPTO_PKWARE_HEADERLEN - 1] = (zip_uint8_t)((dostime >> 8) & 0xff); + + _zip_pkware_encrypt(&ctx->keys, header, header, ZIP_CRYPTO_PKWARE_HEADERLEN); + + return 0; +} + + +static zip_int64_t +pkware_encrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t length, zip_source_cmd_t cmd) { + struct trad_pkware *ctx; + zip_int64_t n; + zip_uint64_t buffer_n; + + ctx = (struct trad_pkware *)ud; + + switch (cmd) { + case ZIP_SOURCE_OPEN: + ctx->eof = false; + + /* initialize keys */ + _zip_pkware_keys_reset(&ctx->keys); + _zip_pkware_encrypt(&ctx->keys, NULL, (const zip_uint8_t *)ctx->password, strlen(ctx->password)); + + if (encrypt_header(src, ctx) < 0) { + return -1; + } + return 0; + + case ZIP_SOURCE_READ: + buffer_n = 0; + + if (ctx->buffer) { + /* write header values to data */ + buffer_n = _zip_buffer_read(ctx->buffer, data, length); + data = (zip_uint8_t *)data + buffer_n; + length -= buffer_n; + + if (_zip_buffer_eof(ctx->buffer)) { + _zip_buffer_free(ctx->buffer); + ctx->buffer = NULL; + } + } + + if (ctx->eof) { + return (zip_int64_t)buffer_n; + } + + if ((n = zip_source_read(src, data, length)) < 0) { + _zip_error_set_from_source(&ctx->error, src); + return -1; + } + + _zip_pkware_encrypt(&ctx->keys, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n); + + if ((zip_uint64_t)n < length) { + ctx->eof = true; + } + + return (zip_int64_t)buffer_n + n; + + case ZIP_SOURCE_CLOSE: + _zip_buffer_free(ctx->buffer); + ctx->buffer = NULL; + return 0; + + case ZIP_SOURCE_STAT: { + zip_stat_t *st; + + st = (zip_stat_t *)data; + st->encryption_method = ZIP_EM_TRAD_PKWARE; + st->valid |= ZIP_STAT_ENCRYPTION_METHOD; + if (st->valid & ZIP_STAT_COMP_SIZE) { + st->comp_size += ZIP_CRYPTO_PKWARE_HEADERLEN; + } + + return 0; + } + + case ZIP_SOURCE_GET_FILE_ATTRIBUTES: { + zip_file_attributes_t *attributes = (zip_file_attributes_t *)data; + if (length < sizeof(*attributes)) { + zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); + return -1; + } + attributes->valid |= ZIP_FILE_ATTRIBUTES_VERSION_NEEDED; + attributes->version_needed = 20; + + return 0; + } + + 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, ZIP_SOURCE_GET_FILE_ATTRIBUTES, -1); + + case ZIP_SOURCE_ERROR: + return zip_error_to_data(&ctx->error, data, length); + + case ZIP_SOURCE_FREE: + trad_pkware_free(ctx); + return 0; + + default: + zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); + return -1; + } +} + + +static struct trad_pkware * +trad_pkware_new(const char *password, zip_error_t *error) { + struct trad_pkware *ctx; + + if ((ctx = (struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) { + zip_error_set(error, ZIP_ER_MEMORY, 0); + return NULL; + } + + if ((ctx->password = strdup(password)) == NULL) { + zip_error_set(error, ZIP_ER_MEMORY, 0); + free(ctx); + return NULL; + } + ctx->buffer = NULL; + zip_error_init(&ctx->error); + + return ctx; +} + + +static void +trad_pkware_free(struct trad_pkware *ctx) { + if (ctx == NULL) { + return; + } + + free(ctx->password); + _zip_buffer_free(ctx->buffer); + zip_error_fini(&ctx->error); + free(ctx); +} diff --git a/Sources/libzip/src/zip_source_win32a.c b/Sources/libzip/src/zip_source_win32a.c deleted file mode 100644 index 825598c..0000000 --- a/Sources/libzip/src/zip_source_win32a.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - zip_source_win32a.c -- create data source from Windows file (ANSI) - Copyright (C) 1999-2019 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 "zipint.h" -#include "zipwin32.h" - -static void *_win32_strdup_a(const void *str); -static HANDLE _win32_open_a(_zip_source_win32_read_file_t *ctx); -static HANDLE _win32_create_temp_a(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa); -static int _win32_rename_temp_a(_zip_source_win32_read_file_t *ctx); -static int _win32_remove_a(const void *fname); - -/* clang-format off */ -static _zip_source_win32_file_ops_t win32_ops_a = { - _win32_strdup_a, - _win32_open_a, - _win32_create_temp_a, - _win32_rename_temp_a, - _win32_remove_a -}; -/* 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 < -1) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } - - return _zip_source_win32_handle_or_name(fname, INVALID_HANDLE_VALUE, start, length, 1, NULL, &win32_ops_a, error); -} - - -static void * -_win32_strdup_a(const void *str) { - return strdup((const char *)str); -} - - -static HANDLE -_win32_open_a(_zip_source_win32_read_file_t *ctx) { - return CreateFileA(ctx->fname, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); -} - - -static HANDLE -_win32_create_temp_a(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa) { - size_t len; - - len = strlen((const char *)ctx->fname) + 10; - if (*temp == NULL) { - if ((*temp = malloc(sizeof(char) * len)) == NULL) { - zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0); - return INVALID_HANDLE_VALUE; - } - } - if (sprintf((char *)*temp, "%s.%08x", (const char *)ctx->fname, value) != len - 1) { - return INVALID_HANDLE_VALUE; - } - - return CreateFileA((const char *)*temp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, sa, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY, NULL); -} - - -static int -_win32_rename_temp_a(_zip_source_win32_read_file_t *ctx) { - DWORD attributes = GetFileAttributesA(ctx->tmpname); - if (INVALID_FILE_ATTRIBUTES == attributes) - return -1; - - if (FILE_ATTRIBUTE_TEMPORARY & attributes) { - if (!SetFileAttributesA(ctx->tmpname, attributes & ~FILE_ATTRIBUTE_TEMPORARY)) - return -1; - } - - if (!MoveFileExA(ctx->tmpname, ctx->fname, MOVEFILE_REPLACE_EXISTING)) - return -1; - - return 0; -} - - -static int -_win32_remove_a(const void *fname) { - DeleteFileA((const char *)fname); - return 0; -} diff --git a/Sources/libzip/src/zip_source_win32handle.c b/Sources/libzip/src/zip_source_win32handle.c deleted file mode 100644 index 8746cdd..0000000 --- a/Sources/libzip/src/zip_source_win32handle.c +++ /dev/null @@ -1,602 +0,0 @@ -/* - zip_source_win32file.c -- create data source from HANDLE (Win32) - Copyright (C) 1999-2019 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" -#include "zipwin32.h" - -static zip_int64_t _win32_read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd); -static int _win32_create_temp_file(_zip_source_win32_read_file_t *ctx); -static int _zip_filetime_to_time_t(FILETIME ft, time_t *t); -static int _zip_seek_win32_u(void *h, zip_uint64_t offset, int whence, zip_error_t *error); -static int _zip_seek_win32(void *h, zip_int64_t offset, int whence, zip_error_t *error); -static int _zip_win32_error_to_errno(unsigned long win32err); -static int _zip_stat_win32(void *h, zip_stat_t *st, _zip_source_win32_read_file_t *ctx); - -ZIP_EXTERN zip_source_t * -zip_source_win32handle(zip_t *za, HANDLE h, zip_uint64_t start, zip_int64_t len) { - if (za == NULL) - return NULL; - - return zip_source_win32handle_create(h, start, len, &za->error); -} - - -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) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } - - return _zip_source_win32_handle_or_name(NULL, h, start, length, 1, NULL, NULL, error); -} - - -zip_source_t * -_zip_source_win32_handle_or_name(const void *fname, HANDLE h, zip_uint64_t start, zip_int64_t len, int closep, const zip_stat_t *st, _zip_source_win32_file_ops_t *ops, zip_error_t *error) { - _zip_source_win32_read_file_t *ctx; - zip_source_t *zs; - - if (h == INVALID_HANDLE_VALUE && fname == NULL) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } - - if ((ctx = (_zip_source_win32_read_file_t *)malloc(sizeof(_zip_source_win32_read_file_t))) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return NULL; - } - - ctx->fname = NULL; - if (fname) { - if ((ctx->fname = ops->op_strdup(fname)) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - free(ctx); - return NULL; - } - } - - ctx->ops = ops; - ctx->h = h; - ctx->start = start; - ctx->end = (len < 0 ? 0 : start + (zip_uint64_t)len); - ctx->closep = ctx->fname ? 1 : closep; - if (st) { - memcpy(&ctx->st, st, sizeof(ctx->st)); - ctx->st.name = NULL; - ctx->st.valid &= ~ZIP_STAT_NAME; - } - else { - zip_stat_init(&ctx->st); - } - - ctx->tmpname = NULL; - ctx->hout = INVALID_HANDLE_VALUE; - - zip_error_init(&ctx->error); - - ctx->supports = ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1); - if (ctx->fname) { - HANDLE th; - - th = ops->op_open(ctx); - if (th == INVALID_HANDLE_VALUE || GetFileType(th) == FILE_TYPE_DISK) { - ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE; - } - if (th != INVALID_HANDLE_VALUE) { - CloseHandle(th); - } - } - else if (GetFileType(ctx->h) == FILE_TYPE_DISK) { - ctx->supports = ZIP_SOURCE_SUPPORTS_SEEKABLE; - } - - ctx->supports |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ACCEPT_EMPTY); - - if ((zs = zip_source_function_create(_win32_read_file, ctx, error)) == NULL) { - free(ctx->fname); - free(ctx); - return NULL; - } - - return zs; -} - - -static zip_int64_t -_win32_read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { - _zip_source_win32_read_file_t *ctx; - char *buf; - zip_uint64_t n; - DWORD i; - - ctx = (_zip_source_win32_read_file_t *)state; - buf = (char *)data; - - switch (cmd) { - case ZIP_SOURCE_ACCEPT_EMPTY: - return 0; - - case ZIP_SOURCE_BEGIN_WRITE: - if (ctx->fname == NULL) { - zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0); - return -1; - } - return _win32_create_temp_file(ctx); - - case ZIP_SOURCE_COMMIT_WRITE: { - if (!CloseHandle(ctx->hout)) { - ctx->hout = INVALID_HANDLE_VALUE; - zip_error_set(&ctx->error, ZIP_ER_WRITE, _zip_win32_error_to_errno(GetLastError())); - } - ctx->hout = INVALID_HANDLE_VALUE; - if (ctx->ops->op_rename_temp(ctx) < 0) { - zip_error_set(&ctx->error, ZIP_ER_RENAME, _zip_win32_error_to_errno(GetLastError())); - return -1; - } - free(ctx->tmpname); - ctx->tmpname = NULL; - return 0; - } - - case ZIP_SOURCE_CLOSE: - if (ctx->fname) { - CloseHandle(ctx->h); - ctx->h = INVALID_HANDLE_VALUE; - } - return 0; - - case ZIP_SOURCE_ERROR: - return zip_error_to_data(&ctx->error, data, len); - - case ZIP_SOURCE_FREE: - free(ctx->fname); - free(ctx->tmpname); - if (ctx->closep && ctx->h != INVALID_HANDLE_VALUE) - CloseHandle(ctx->h); - free(ctx); - return 0; - - case ZIP_SOURCE_OPEN: - if (ctx->fname) { - if ((ctx->h = ctx->ops->op_open(ctx)) == INVALID_HANDLE_VALUE) { - zip_error_set(&ctx->error, ZIP_ER_OPEN, _zip_win32_error_to_errno(GetLastError())); - return -1; - } - } - - if (ctx->closep && ctx->start > 0) { - if (_zip_seek_win32_u(ctx->h, ctx->start, SEEK_SET, &ctx->error) < 0) { - return -1; - } - } - ctx->current = ctx->start; - return 0; - - case ZIP_SOURCE_READ: - if (ctx->end > 0) { - n = ctx->end - ctx->current; - if (n > len) { - n = len; - } - } - else { - n = len; - } - - if (n > SIZE_MAX) - n = SIZE_MAX; - - if (!ctx->closep) { - if (_zip_seek_win32_u(ctx->h, ctx->current, SEEK_SET, &ctx->error) < 0) { - return -1; - } - } - - if (!ReadFile(ctx->h, buf, (DWORD)n, &i, NULL)) { - zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError())); - return -1; - } - ctx->current += i; - - return (zip_int64_t)i; - - case ZIP_SOURCE_REMOVE: - if (ctx->ops->op_remove(ctx->fname) < 0) { - zip_error_set(&ctx->error, ZIP_ER_REMOVE, _zip_win32_error_to_errno(GetLastError())); - return -1; - } - return 0; - - case ZIP_SOURCE_ROLLBACK_WRITE: - if (ctx->hout) { - CloseHandle(ctx->hout); - ctx->hout = INVALID_HANDLE_VALUE; - } - ctx->ops->op_remove(ctx->tmpname); - free(ctx->tmpname); - ctx->tmpname = NULL; - return 0; - - case ZIP_SOURCE_SEEK: { - zip_int64_t new_current; - int need_seek; - zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error); - - if (args == NULL) - return -1; - - need_seek = ctx->closep; - - switch (args->whence) { - case SEEK_SET: - new_current = args->offset + ctx->start; - break; - - case SEEK_END: - if (ctx->end == 0) { - LARGE_INTEGER zero; - LARGE_INTEGER new_offset; - - if (_zip_seek_win32(ctx->h, args->offset, SEEK_END, &ctx->error) < 0) { - return -1; - } - zero.QuadPart = 0; - if (!SetFilePointerEx(ctx->h, zero, &new_offset, FILE_CURRENT)) { - zip_error_set(&ctx->error, ZIP_ER_SEEK, _zip_win32_error_to_errno(GetLastError())); - return -1; - } - new_current = new_offset.QuadPart; - need_seek = 0; - } - else { - new_current = (zip_int64_t)ctx->end + args->offset; - } - break; - case SEEK_CUR: - new_current = (zip_int64_t)ctx->current + args->offset; - break; - - default: - zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (new_current < 0 || (zip_uint64_t)new_current < ctx->start || (ctx->end != 0 && (zip_uint64_t)new_current > ctx->end)) { - zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); - return -1; - } - - ctx->current = (zip_uint64_t)new_current; - - if (need_seek) { - if (_zip_seek_win32_u(ctx->h, ctx->current, SEEK_SET, &ctx->error) < 0) { - return -1; - } - } - return 0; - } - - case ZIP_SOURCE_SEEK_WRITE: { - zip_source_args_seek_t *args; - - args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error); - if (args == NULL) { - return -1; - } - - if (_zip_seek_win32(ctx->hout, args->offset, args->whence, &ctx->error) < 0) { - return -1; - } - return 0; - } - - case ZIP_SOURCE_STAT: { - if (len < sizeof(ctx->st)) - return -1; - - if (ctx->st.valid != 0) - memcpy(data, &ctx->st, sizeof(ctx->st)); - else { - DWORD win32err; - zip_stat_t *st; - HANDLE h; - int success; - - st = (zip_stat_t *)data; - - if (ctx->h != INVALID_HANDLE_VALUE) { - h = ctx->h; - } - else { - h = ctx->ops->op_open(ctx); - if (h == INVALID_HANDLE_VALUE) { - win32err = GetLastError(); - if (win32err == ERROR_FILE_NOT_FOUND || win32err == ERROR_PATH_NOT_FOUND) { - zip_error_set(&ctx->error, ZIP_ER_READ, ENOENT); - return -1; - } - } - } - - success = _zip_stat_win32(h, st, ctx); - win32err = GetLastError(); - - /* We're done with the handle, so close it if we just opened it. */ - if (h != ctx->h) { - CloseHandle(h); - } - - if (success < 0) { - /* TODO: Is this the correct error to return in all cases? */ - zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(win32err)); - return -1; - } - } - return sizeof(ctx->st); - } - - case ZIP_SOURCE_SUPPORTS: - return ctx->supports; - - case ZIP_SOURCE_TELL: - return (zip_int64_t)ctx->current; - - case ZIP_SOURCE_TELL_WRITE: { - LARGE_INTEGER zero; - LARGE_INTEGER offset; - - zero.QuadPart = 0; - if (!SetFilePointerEx(ctx->hout, zero, &offset, FILE_CURRENT)) { - zip_error_set(&ctx->error, ZIP_ER_TELL, _zip_win32_error_to_errno(GetLastError())); - return -1; - } - - return offset.QuadPart; - } - - case ZIP_SOURCE_WRITE: { - DWORD ret; - if (!WriteFile(ctx->hout, data, (DWORD)len, &ret, NULL) || ret != len) { - zip_error_set(&ctx->error, ZIP_ER_WRITE, _zip_win32_error_to_errno(GetLastError())); - return -1; - } - - return (zip_int64_t)ret; - } - - default: - zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0); - return -1; - } -} - - -static int -_win32_create_temp_file(_zip_source_win32_read_file_t *ctx) { - zip_uint32_t value; - /* - Windows has GetTempFileName(), but it closes the file after - creation, leaving it open to a horrible race condition. So - we reinvent the wheel. - */ - int i; - HANDLE th = INVALID_HANDLE_VALUE; - void *temp = NULL; - PSECURITY_DESCRIPTOR psd = NULL; - PSECURITY_ATTRIBUTES psa = NULL; - SECURITY_ATTRIBUTES sa; - SECURITY_INFORMATION si; - DWORD success; - PACL dacl = NULL; - - /* - Read the DACL from the original file, so we can copy it to the temp file. - If there is no original file, or if we can't read the DACL, we'll use the - default security descriptor. - */ - if (ctx->h != INVALID_HANDLE_VALUE && GetFileType(ctx->h) == FILE_TYPE_DISK) { - si = DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION; - success = GetSecurityInfo(ctx->h, SE_FILE_OBJECT, si, NULL, NULL, &dacl, NULL, &psd); - if (success == ERROR_SUCCESS) { - sa.nLength = sizeof(SECURITY_ATTRIBUTES); - sa.bInheritHandle = FALSE; - sa.lpSecurityDescriptor = psd; - psa = &sa; - } - } - - -#ifndef MS_UWP - value = GetTickCount(); -#else - value = (zip_uint32_t)GetTickCount64(); -#endif - - for (i = 0; i < 1024 && th == INVALID_HANDLE_VALUE; i++) { - th = ctx->ops->op_create_temp(ctx, &temp, value + i, psa); - if (th == INVALID_HANDLE_VALUE && GetLastError() != ERROR_FILE_EXISTS) - break; - } - - if (th == INVALID_HANDLE_VALUE) { - free(temp); - LocalFree(psd); - zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, _zip_win32_error_to_errno(GetLastError())); - return -1; - } - - LocalFree(psd); - ctx->hout = th; - ctx->tmpname = temp; - - return 0; -} - - -static int -_zip_seek_win32_u(HANDLE h, zip_uint64_t offset, int whence, zip_error_t *error) { - if (offset > ZIP_INT64_MAX) { - zip_error_set(error, ZIP_ER_SEEK, EOVERFLOW); - return -1; - } - return _zip_seek_win32(h, (zip_int64_t)offset, whence, error); -} - - -static int -_zip_seek_win32(HANDLE h, zip_int64_t offset, int whence, zip_error_t *error) { - LARGE_INTEGER li; - DWORD method; - - switch (whence) { - case SEEK_SET: - method = FILE_BEGIN; - break; - case SEEK_END: - method = FILE_END; - break; - case SEEK_CUR: - method = FILE_CURRENT; - break; - default: - zip_error_set(error, ZIP_ER_SEEK, EINVAL); - return -1; - } - - li.QuadPart = (LONGLONG)offset; - if (!SetFilePointerEx(h, li, NULL, method)) { - zip_error_set(error, ZIP_ER_SEEK, _zip_win32_error_to_errno(GetLastError())); - return -1; - } - - return 0; -} - - -static int -_zip_win32_error_to_errno(DWORD win32err) { - /* - Note: This list isn't exhaustive, but should cover common cases. - */ - switch (win32err) { - case ERROR_INVALID_PARAMETER: - return EINVAL; - case ERROR_FILE_NOT_FOUND: - return ENOENT; - case ERROR_INVALID_HANDLE: - return EBADF; - case ERROR_ACCESS_DENIED: - return EACCES; - case ERROR_FILE_EXISTS: - return EEXIST; - case ERROR_TOO_MANY_OPEN_FILES: - return EMFILE; - case ERROR_DISK_FULL: - return ENOSPC; - default: - return 0; - } -} - - -static int -_zip_stat_win32(HANDLE h, zip_stat_t *st, _zip_source_win32_read_file_t *ctx) { - FILETIME mtimeft; - time_t mtime; - LARGE_INTEGER size; - int regularp; - - if (!GetFileTime(h, NULL, NULL, &mtimeft)) { - zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError())); - return -1; - } - if (_zip_filetime_to_time_t(mtimeft, &mtime) < 0) { - zip_error_set(&ctx->error, ZIP_ER_READ, ERANGE); - return -1; - } - - regularp = 0; - if (GetFileType(h) == FILE_TYPE_DISK) { - regularp = 1; - } - - if (!GetFileSizeEx(h, &size)) { - zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError())); - return -1; - } - - zip_stat_init(st); - st->mtime = mtime; - st->valid |= ZIP_STAT_MTIME; - if (ctx->end != 0) { - st->size = ctx->end - ctx->start; - st->valid |= ZIP_STAT_SIZE; - } - else if (regularp) { - st->size = (zip_uint64_t)size.QuadPart; - st->valid |= ZIP_STAT_SIZE; - } - - return 0; -} - - -static int -_zip_filetime_to_time_t(FILETIME ft, time_t *t) { - /* - Inspired by http://stackoverflow.com/questions/6161776/convert-windows-filetime-to-second-in-unix-linux - */ - const zip_int64_t WINDOWS_TICK = 10000000LL; - const zip_int64_t SEC_TO_UNIX_EPOCH = 11644473600LL; - ULARGE_INTEGER li; - zip_int64_t secs; - time_t temp; - - li.LowPart = ft.dwLowDateTime; - li.HighPart = ft.dwHighDateTime; - secs = (li.QuadPart / WINDOWS_TICK - SEC_TO_UNIX_EPOCH); - - temp = (time_t)secs; - if (secs != (zip_int64_t)temp) - return -1; - - *t = temp; - return 0; -} diff --git a/Sources/libzip/src/zip_source_win32w.c b/Sources/libzip/src/zip_source_win32w.c deleted file mode 100644 index f62a658..0000000 --- a/Sources/libzip/src/zip_source_win32w.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - zip_source_win32w.c -- create data source from Windows file (UTF-16) - Copyright (C) 1999-2019 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 "zipint.h" -#include "zipwin32.h" - -static void *_win32_strdup_w(const void *str); -static HANDLE _win32_open_w(_zip_source_win32_read_file_t *ctx); -static HANDLE _win32_create_temp_w(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa); -static int _win32_rename_temp_w(_zip_source_win32_read_file_t *ctx); -static int _win32_remove_w(const void *fname); - -/* clang-format off */ -static _zip_source_win32_file_ops_t win32_ops_w = { - _win32_strdup_w, - _win32_open_w, - _win32_create_temp_w, - _win32_rename_temp_w, - _win32_remove_w -}; -/* clang-format on */ - -ZIP_EXTERN zip_source_t * -zip_source_win32w(zip_t *za, const wchar_t *fname, zip_uint64_t start, zip_int64_t len) { - if (za == NULL) - return NULL; - - return zip_source_win32w_create(fname, start, len, &za->error); -} - - -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) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } - - return _zip_source_win32_handle_or_name(fname, INVALID_HANDLE_VALUE, start, length, 1, NULL, &win32_ops_w, error); -} - - -static void * -_win32_strdup_w(const void *str) { - return _wcsdup((const wchar_t *)str); -} - - -static HANDLE -_win32_open_w(_zip_source_win32_read_file_t *ctx) { -#ifdef MS_UWP - CREATEFILE2_EXTENDED_PARAMETERS extParams = {0}; - extParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; - extParams.dwFileFlags = FILE_FLAG_RANDOM_ACCESS; - extParams.dwSecurityQosFlags = SECURITY_ANONYMOUS; - extParams.dwSize = sizeof(extParams); - extParams.hTemplateFile = NULL; - extParams.lpSecurityAttributes = NULL; - - return CreateFile2(ctx->fname, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING, &extParams); -#else - return CreateFileW(ctx->fname, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); -#endif -} - - -static HANDLE -_win32_create_temp_w(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa) { - size_t len; - - len = wcslen((const wchar_t *)ctx->fname) + 10; - if (*temp == NULL) { - if ((*temp = malloc(sizeof(wchar_t) * len)) == NULL) { - zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0); - return INVALID_HANDLE_VALUE; - } - } - if (_snwprintf((wchar_t *)*temp, len, L"%s.%08x", (const wchar_t *)ctx->fname, value) != len - 1) { - return INVALID_HANDLE_VALUE; - } - -#ifdef MS_UWP - CREATEFILE2_EXTENDED_PARAMETERS extParams = {0}; - extParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY; - extParams.dwFileFlags = FILE_FLAG_RANDOM_ACCESS; - extParams.dwSecurityQosFlags = SECURITY_ANONYMOUS; - extParams.dwSize = sizeof(extParams); - extParams.hTemplateFile = NULL; - extParams.lpSecurityAttributes = NULL; - - return CreateFile2((const wchar_t *)*temp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, CREATE_NEW, &extParams); -#else - return CreateFileW((const wchar_t *)*temp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, sa, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY, NULL); -#endif -} - - -static int -_win32_rename_temp_w(_zip_source_win32_read_file_t *ctx) { - DWORD attributes = GetFileAttributesW(ctx->tmpname); - if (INVALID_FILE_ATTRIBUTES == attributes) - return -1; - - if (FILE_ATTRIBUTE_TEMPORARY & attributes) { - if (!SetFileAttributesW(ctx->tmpname, attributes & ~FILE_ATTRIBUTE_TEMPORARY)) - return -1; - } - - if (!MoveFileExW(ctx->tmpname, ctx->fname, MOVEFILE_REPLACE_EXISTING)) - return -1; - - return 0; -} - - -static int -_win32_remove_w(const void *fname) { - DeleteFileW((const wchar_t *)fname); - return 0; -} diff --git a/Sources/libzip/src/zip_source_window.c b/Sources/libzip/src/zip_source_window.c index 1276485..d996015 100644 --- a/Sources/libzip/src/zip_source_window.c +++ b/Sources/libzip/src/zip_source_window.c @@ -48,7 +48,7 @@ struct window { zip_uint64_t offset; /* offset in src for next read */ zip_stat_t stat; - zip_int8_t compression_flags; + zip_file_attributes_t attributes; zip_error_t error; zip_int64_t supports; bool needs_seek; @@ -64,7 +64,7 @@ zip_source_window(zip_t *za, zip_source_t *src, zip_uint64_t start, zip_uint64_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_int8_t compression_flags, 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_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) { struct window *ctx; if (src == NULL || start + length < start || (source_archive == NULL && source_index != 0)) { @@ -80,11 +80,16 @@ _zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_uint64_t lengt ctx->start = start; ctx->end = start + length; zip_stat_init(&ctx->stat); - ctx->compression_flags = compression_flags; + if (attributes != NULL) { + memcpy(&ctx->attributes, attributes, sizeof(ctx->attributes)); + } + else { + zip_file_attributes_init(&ctx->attributes); + } 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_COMPRESSION_FLAGS, ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1)); + 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->needs_seek = (ctx->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK)) ? true : false; if (st) { @@ -173,7 +178,7 @@ window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_sou return -1; } } - + byte_array_fini(b); } @@ -231,8 +236,14 @@ window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_sou return 0; } - case ZIP_SOURCE_GET_COMPRESSION_FLAGS: - return ctx->compression_flags; + case ZIP_SOURCE_GET_FILE_ATTRIBUTES: + if (len < sizeof(ctx->attributes)) { + zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); + return -1; + } + + memcpy(data, &ctx->attributes, sizeof(ctx->attributes)); + return sizeof(ctx->attributes); case ZIP_SOURCE_SUPPORTS: return ctx->supports; diff --git a/Sources/libzip/src/zip_source_winzip_aes_encode.c b/Sources/libzip/src/zip_source_winzip_aes_encode.c index 7df5faf..f9ae555 100644 --- a/Sources/libzip/src/zip_source_winzip_aes_encode.c +++ b/Sources/libzip/src/zip_source_winzip_aes_encode.c @@ -184,8 +184,20 @@ winzip_aes_encrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t length, return 0; } + case ZIP_SOURCE_GET_FILE_ATTRIBUTES: { + zip_file_attributes_t *attributes = (zip_file_attributes_t *)data; + if (length < sizeof(*attributes)) { + zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); + return -1; + } + attributes->valid |= ZIP_FILE_ATTRIBUTES_VERSION_NEEDED; + attributes->version_needed = 51; + + return 0; + } + 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_GET_FILE_ATTRIBUTES, -1); case ZIP_SOURCE_ERROR: return zip_error_to_data(&ctx->error, data, length); diff --git a/Sources/libzip/src/zip_source_zip.c b/Sources/libzip/src/zip_source_zip.c index 1f77aaa..8a7feaa 100644 --- a/Sources/libzip/src/zip_source_zip.c +++ b/Sources/libzip/src/zip_source_zip.c @@ -33,7 +33,6 @@ #include -#include #include "zipint.h" diff --git a/Sources/libzip/src/zip_source_zip_new.c b/Sources/libzip/src/zip_source_zip_new.c index f36609b..6d547f0 100644 --- a/Sources/libzip/src/zip_source_zip_new.c +++ b/Sources/libzip/src/zip_source_zip_new.c @@ -36,15 +36,19 @@ #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; - struct zip_stat st; + 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) + if (za == NULL) { return NULL; + } if (srcza == NULL || srcidx >= srcza->nentry) { zip_error_set(&za->error, ZIP_ER_INVAL, 0); @@ -61,8 +65,9 @@ _zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t fl return NULL; } - if (flags & ZIP_FL_ENCRYPTED) + 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); @@ -95,8 +100,13 @@ _zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t fl } } + 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(za, NULL, 0, 0); + return zip_source_buffer_with_attributes(za, NULL, 0, 0, &attributes); } if (partial_data && !needs_decrypt && !needs_decompress) { @@ -108,17 +118,12 @@ _zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t fl 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, 0, srcza, srcidx, &za->error)) == NULL) { + if ((src = _zip_source_window_new(srcza->src, start, len, &st2, &attributes, srcza, srcidx, &za->error)) == NULL) { return NULL; } } else { - zip_dirent_t *de; - - if ((de = _zip_get_dirent(srcza, srcidx, flags, &za->error)) == NULL) { - return NULL; - } - if ((src = _zip_source_window_new(srcza->src, 0, st.comp_size, &st, (de->bitflags >> 1) & 3, srcza, srcidx, &za->error)) == NULL) { + if ((src = _zip_source_window_new(srcza->src, 0, st.comp_size, &st, &attributes, srcza, srcidx, &za->error)) == NULL) { return NULL; } } @@ -173,3 +178,14 @@ _zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t fl 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/Sources/libzip/src/zip_stat_index.c b/Sources/libzip/src/zip_stat_index.c index 71f8049..7799325 100644 --- a/Sources/libzip/src/zip_stat_index.c +++ b/Sources/libzip/src/zip_stat_index.c @@ -48,7 +48,7 @@ zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags, zip_stat_t *st) if ((flags & ZIP_FL_UNCHANGED) == 0 && ZIP_ENTRY_DATA_CHANGED(za->entry + index)) { - zip_entry_t *entry = 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); diff --git a/Sources/libzip/src/zip_string.c b/Sources/libzip/src/zip_string.c index a6edbc5..122721d 100644 --- a/Sources/libzip/src/zip_string.c +++ b/Sources/libzip/src/zip_string.c @@ -34,10 +34,10 @@ #include #include +#include #include "zipint.h" - zip_uint32_t _zip_string_crc32(const zip_string_t *s) { zip_uint32_t crc; @@ -145,7 +145,7 @@ _zip_string_new(const zip_uint8_t *raw, zip_uint16_t length, zip_flags_t flags, return NULL; } - if ((s->raw = (zip_uint8_t *)malloc((size_t)(length + 1))) == NULL) { + if ((s->raw = (zip_uint8_t *)malloc((size_t)length + 1)) == NULL) { free(s); return NULL; } diff --git a/Sources/libzip/src/zip_unchange_all.c b/Sources/libzip/src/zip_unchange_all.c index 5e7df80..2ae742f 100644 --- a/Sources/libzip/src/zip_unchange_all.c +++ b/Sources/libzip/src/zip_unchange_all.c @@ -32,8 +32,6 @@ */ -#include - #include "zipint.h" diff --git a/Sources/libzip/src/zip_winzip_aes.c b/Sources/libzip/src/zip_winzip_aes.c index 188b4bb..c86ef88 100644 --- a/Sources/libzip/src/zip_winzip_aes.c +++ b/Sources/libzip/src/zip_winzip_aes.c @@ -35,7 +35,6 @@ #include "zip_crypto.h" -#include #include #include diff --git a/Sources/libzip/src/zipint.h b/Sources/libzip/src/zipint.h index 06133d1..99c1806 100644 --- a/Sources/libzip/src/zipint.h +++ b/Sources/libzip/src/zipint.h @@ -34,18 +34,13 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifdef HAVE_CONFIG_H #include "config.h" -#endif - #include "compat.h" #ifdef ZIP_ALLOCATE_BUFFER #include #endif -#include - #ifndef _ZIP_COMPILING_DEPRECATED #define ZIP_DISABLE_DEPRECATED #endif @@ -69,6 +64,9 @@ #define BUFSIZE 8192 #define EFZIP64SIZE 28 #define EF_WINZIP_AES_SIZE 7 +#define MAX_DATA_DESCRIPTOR_LENGTH 24 + +#define ZIP_CRYPTO_PKWARE_HEADERLEN 12 #define ZIP_CM_REPLACED_DEFAULT (-2) #define ZIP_CM_WINZIP_AES 99 /* Winzip AES encrypted */ @@ -95,6 +93,7 @@ /* according to unzip-6.0's zipinfo.c, this corresponds to a directory with rwx permissions for everyone */ #define ZIP_EXT_ATTRIB_DEFAULT_DIR (0040777u << 16) +#define ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS_ALLOWED_MASK 0x0836 #define ZIP_MAX(a, b) ((a) > (b) ? (a) : (b)) #define ZIP_MIN(a, b) ((a) < (b) ? (a) : (b)) @@ -128,7 +127,9 @@ struct zip_compression_algorithm { void (*deallocate)(void *ctx); /* get compression specific general purpose bitflags */ - int (*compression_flags)(void *ctx); + zip_uint16_t (*general_purpose_bit_flags)(void *ctx); + /* minimum version needed when using this algorithm */ + zip_uint8_t version_needed; /* start processing */ bool (*start)(void *ctx); @@ -154,8 +155,6 @@ extern zip_compression_algorithm_t zip_algorithm_xz_compress; extern zip_compression_algorithm_t zip_algorithm_xz_decompress; -bool zip_compression_method_supported(zip_int32_t method, bool compress); - /* This API is not final yet, but we need it internally, so it's private for now. */ const zip_uint8_t *zip_get_extra_field_by_id(zip_t *, int, int, zip_uint16_t, int, zip_uint16_t *); @@ -170,13 +169,14 @@ zip_source_t *zip_source_crc(zip_t *, zip_source_t *, int); 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(zip_t *, zip_source_t *, zip_uint16_t, int, const char *); +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 *); - +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); /* error source for layered sources */ @@ -381,13 +381,13 @@ struct zip_string { for those, use malloc()/free() */ #ifdef ZIP_ALLOCATE_BUFFER -#define DEFINE_BYTE_ARRAY(buf, size) zip_uint8_t *buf -#define byte_array_init(buf, size) (((buf) = (zip_uint8_t *)malloc(size)) != NULL) -#define byte_array_fini(buf) (free(buf)) +#define DEFINE_BYTE_ARRAY(buf, size) zip_uint8_t *buf +#define byte_array_init(buf, size) (((buf) = (zip_uint8_t *)malloc(size)) != NULL) +#define byte_array_fini(buf) (free(buf)) #else -#define DEFINE_BYTE_ARRAY(buf, size) zip_uint8_t buf[size] -#define byte_array_init(buf, size) (1) -#define byte_array_fini(buf) ((void)0) +#define DEFINE_BYTE_ARRAY(buf, size) zip_uint8_t buf[size] +#define byte_array_init(buf, size) (1) +#define byte_array_fini(buf) ((void)0) #endif @@ -414,6 +414,11 @@ typedef struct zip_filelist zip_filelist_t; struct _zip_winzip_aes; typedef struct _zip_winzip_aes zip_winzip_aes_t; +struct _zip_pkware_keys { + zip_uint32_t key[3]; +}; +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[]; @@ -466,7 +471,6 @@ int _zip_buffer_skip(zip_buffer_t *buffer, zip_uint64_t length); int _zip_buffer_set_offset(zip_buffer_t *buffer, zip_uint64_t offset); zip_uint64_t _zip_buffer_size(zip_buffer_t *buffer); -int _zip_cdir_compute_crc(zip_t *, uLong *); void _zip_cdir_free(zip_cdir_t *); bool _zip_cdir_grow(zip_cdir_t *cd, zip_uint64_t additional_entries, zip_error_t *error); zip_cdir_t *_zip_cdir_new(zip_uint64_t, zip_error_t *); @@ -474,6 +478,7 @@ zip_int64_t _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint6 time_t _zip_d2u_time(zip_uint16_t, zip_uint16_t); void _zip_deregister_source(zip_t *za, zip_source_t *src); +void _zip_dirent_apply_attributes(zip_dirent_t *, zip_file_attributes_t *, bool, zip_uint32_t); zip_dirent_t *_zip_dirent_clone(const zip_dirent_t *); void _zip_dirent_free(zip_dirent_t *); void _zip_dirent_finalize(zip_dirent_t *); @@ -512,8 +517,6 @@ int _zip_file_fillbuf(void *, size_t, zip_file_t *); zip_uint64_t _zip_file_get_end(const zip_t *za, zip_uint64_t index, zip_error_t *error); zip_uint64_t _zip_file_get_offset(const zip_t *, zip_uint64_t, zip_error_t *); -int _zip_filerange_crc(zip_source_t *src, zip_uint64_t offset, zip_uint64_t length, uLong *crcp, zip_error_t *error); - zip_dirent_t *_zip_get_dirent(zip_t *, zip_uint64_t, zip_flags_t, zip_error_t *); enum zip_encoding_type _zip_guess_encoding(zip_string_t *, enum zip_encoding_type); @@ -545,7 +548,7 @@ int _zip_read(zip_source_t *src, zip_uint8_t *data, zip_uint64_t length, zip_err int _zip_read_at_offset(zip_source_t *src, zip_uint64_t offset, unsigned char *b, size_t length, zip_error_t *error); zip_uint8_t *_zip_read_data(zip_buffer_t *buffer, zip_source_t *src, size_t length, bool nulp, zip_error_t *error); int _zip_read_local_ef(zip_t *, zip_uint64_t); -zip_string_t *_zip_read_string(zip_buffer_t *buffer, zip_source_t *src, zip_uint16_t lenght, bool nulp, zip_error_t *error); +zip_string_t *_zip_read_string(zip_buffer_t *buffer, zip_source_t *src, zip_uint16_t length, bool nulp, zip_error_t *error); int _zip_register_source(zip_t *za, zip_source_t *src); void _zip_set_open_error(int *zep, const zip_error_t *err, int ze); @@ -554,12 +557,11 @@ bool zip_source_accept_empty(zip_source_t *src); zip_int64_t _zip_source_call(zip_source_t *src, void *data, zip_uint64_t length, zip_source_cmd_t command); bool _zip_source_eof(zip_source_t *); zip_source_t *_zip_source_file_or_p(const char *, FILE *, zip_uint64_t, zip_int64_t, const zip_stat_t *, zip_error_t *error); -zip_int8_t zip_source_get_compression_flags(zip_source_t *); 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_int8_t compression_flags, zip_t *source_archive, zip_uint64_t source_index, zip_error_t *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_t *_zip_source_zip_new(zip_t *, zip_t *, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_uint64_t, const char *); int _zip_stat_merge(zip_stat_t *dst, const zip_stat_t *src, zip_error_t *error); @@ -576,6 +578,12 @@ bool _zip_winzip_aes_finish(zip_winzip_aes_t *ctx, zip_uint8_t *hmac); void _zip_winzip_aes_free(zip_winzip_aes_t *ctx); zip_winzip_aes_t *_zip_winzip_aes_new(const zip_uint8_t *password, zip_uint64_t password_length, const zip_uint8_t *salt, zip_uint16_t key_size, zip_uint8_t *password_verify, zip_error_t *error); +void _zip_pkware_encrypt(zip_pkware_keys_t *keys, zip_uint8_t *out, const zip_uint8_t *in, zip_uint64_t len); +void _zip_pkware_decrypt(zip_pkware_keys_t *keys, zip_uint8_t *out, const zip_uint8_t *in, zip_uint64_t len); +zip_pkware_keys_t *_zip_pkware_keys_new(zip_error_t *error); +void _zip_pkware_keys_free(zip_pkware_keys_t *keys); +void _zip_pkware_keys_reset(zip_pkware_keys_t *keys); + int _zip_changed(const zip_t *, zip_uint64_t *); const char *_zip_get_name(zip_t *, zip_uint64_t, zip_flags_t, zip_error_t *); int _zip_local_header_read(zip_t *, int); diff --git a/Sources/libzip/src/zipwin32.h b/Sources/libzip/src/zipwin32.h deleted file mode 100644 index 870f1d5..0000000 --- a/Sources/libzip/src/zipwin32.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef _HAD_ZIPWIN32_H -#define _HAD_ZIPWIN32_H - -/* - zipwin32.h -- internal declarations for Windows. - Copyright (C) 1999-2019 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. -*/ - -/* 0x0501 => Windows XP; needs to be at least this value because of GetFileSizeEx */ -#if !defined(MS_UWP) && !defined(_WIN32_WINNT) -#define _WIN32_WINNT 0x0501 -#endif - -#include - -/* context for Win32 source */ - -struct _zip_source_win32_file_ops; - -struct _zip_source_win32_read_file { - zip_error_t error; /* last error information */ - zip_int64_t supports; - - /* operations */ - struct _zip_source_win32_file_ops *ops; - - /* reading */ - void *fname; /* name of file to read from - ANSI (char *) or Unicode (wchar_t *) */ - void *h; /* HANDLE for file to read from */ - int closep; /* whether to close f on ZIP_CMD_FREE */ - struct zip_stat st; /* stat information passed in */ - zip_uint64_t start; /* start offset of data to read */ - zip_uint64_t end; /* end offset of data to read, 0 for up to EOF */ - zip_uint64_t current; /* current offset */ - - /* writing */ - void *tmpname; /* name of temp file - ANSI (char *) or Unicode (wchar_t *) */ - void *hout; /* HANDLE for output file */ -}; - -typedef struct _zip_source_win32_read_file _zip_source_win32_read_file_t; - -/* internal operations for Win32 source */ - -struct _zip_source_win32_file_ops { - void *(*op_strdup)(const void *); - void *(*op_open)(_zip_source_win32_read_file_t *); - void *(*op_create_temp)(_zip_source_win32_read_file_t *, void **, zip_uint32_t, PSECURITY_ATTRIBUTES); - int (*op_rename_temp)(_zip_source_win32_read_file_t *); - int (*op_remove)(const void *); -}; - -typedef struct _zip_source_win32_file_ops _zip_source_win32_file_ops_t; - -zip_source_t *_zip_source_win32_handle_or_name(const void *, void *, zip_uint64_t, zip_int64_t, int, const zip_stat_t *, _zip_source_win32_file_ops_t *, zip_error_t *); - -#endif /* zipwin32.h */