mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2025-11-11 11:08:02 -06:00
Libzip (#1152)
* Update LZMA to latest * Update Libzip Libzip updated to latest.
This commit is contained in:
@@ -1,14 +1,32 @@
|
|||||||
1.9.2 [2022-06-28]
|
# 1.10.0 [2023-06-23]
|
||||||
|
|
||||||
|
* Make support for layered sources public.
|
||||||
|
* Add `zip_source_zip_file` and `zip_source_zip_file_create`, deprecate `zip_source_zip` and `zip_source_zip_create`.
|
||||||
|
* Allow reading changed file data.
|
||||||
|
* Fix handling of files of size 4294967295.
|
||||||
|
* `zipmerge`: copy extra fields.
|
||||||
|
* `zipmerge`: add option to keep files uncompressed.
|
||||||
|
* Switch test framework to use nihtest instead of Perl.
|
||||||
|
* Fix reading/writing compressed data with buffers > 4GiB.
|
||||||
|
* Restore support for torrentzip.
|
||||||
|
* Add warnings when using deprecated functions.
|
||||||
|
* Allow keeping files for empty archives.
|
||||||
|
* Support mbedTLS>=3.3.0.
|
||||||
|
* Support OpenSSL 3.
|
||||||
|
* Use ISO C secure library functions, if available.
|
||||||
|
|
||||||
|
|
||||||
|
# 1.9.2 [2022-06-28]
|
||||||
|
|
||||||
* Fix version number in header file.
|
* Fix version number in header file.
|
||||||
|
|
||||||
1.9.1 [2022-06-28]
|
|
||||||
===================
|
# 1.9.1 [2022-06-28]
|
||||||
|
|
||||||
* Fix `zip_file_is_seekable()`.
|
* Fix `zip_file_is_seekable()`.
|
||||||
|
|
||||||
1.9.0 [2022-06-13]
|
|
||||||
==================
|
# 1.9.0 [2022-06-13]
|
||||||
|
|
||||||
* Add `zip_file_is_seekable()`.
|
* Add `zip_file_is_seekable()`.
|
||||||
* Improve compatibility with WinAES.
|
* Improve compatibility with WinAES.
|
||||||
@@ -16,8 +34,8 @@
|
|||||||
* Add option to `zipcmp` to output summary of changes.
|
* Add option to `zipcmp` to output summary of changes.
|
||||||
* Various bug fixes and documentation improvements.
|
* Various bug fixes and documentation improvements.
|
||||||
|
|
||||||
1.8.0 [2021-06-18]
|
|
||||||
==================
|
# 1.8.0 [2021-06-18]
|
||||||
|
|
||||||
* Add support for zstd (Zstandard) compression.
|
* Add support for zstd (Zstandard) compression.
|
||||||
* Add support for lzma (ID 14) compression.
|
* Add support for lzma (ID 14) compression.
|
||||||
@@ -30,29 +48,29 @@
|
|||||||
* In `zipcmp`, don’t ignore empty directories when comparing directory listing.
|
* In `zipcmp`, don’t ignore empty directories when comparing directory listing.
|
||||||
* Treat empty string as no password given in `zip_file_set_encryption()`, `zip_fopen_encrypted()`, and `zip_set_default_password()`.
|
* Treat empty string as no password given in `zip_file_set_encryption()`, `zip_fopen_encrypted()`, and `zip_set_default_password()`.
|
||||||
|
|
||||||
1.7.3 [2020-07-15]
|
|
||||||
==================
|
# 1.7.3 [2020-07-15]
|
||||||
|
|
||||||
* Support cmake < 3.17 again.
|
* Support cmake < 3.17 again.
|
||||||
* Fix pkgconfig file (regression in 1.7.2).
|
* Fix pkgconfig file (regression in 1.7.2).
|
||||||
|
|
||||||
1.7.2 [2020-07-11]
|
|
||||||
==================
|
# 1.7.2 [2020-07-11]
|
||||||
|
|
||||||
* Fixes for the CMake `find_project()` files.
|
* Fixes for the CMake `find_project()` files.
|
||||||
* libzip moved to the CMake `libzip::` `NAMESPACE`.
|
* libzip moved to the CMake `libzip::` `NAMESPACE`.
|
||||||
* CMake usage best practice cleanups.
|
* CMake usage best practice cleanups.
|
||||||
|
|
||||||
1.7.1 [2020-06-13]
|
|
||||||
==================
|
# 1.7.1 [2020-06-13]
|
||||||
|
|
||||||
* Restore `LIBZIP_VERSION_{MAJOR,MINOR,MICRO}` symbols.
|
* Restore `LIBZIP_VERSION_{MAJOR,MINOR,MICRO}` symbols.
|
||||||
* Fixes warnings reported by PVS-Studio.
|
* Fixes warnings reported by PVS-Studio.
|
||||||
* Add `LIBZIP_DO_INSTALL` build setting to make it easier to use
|
* Add `LIBZIP_DO_INSTALL` build setting to make it easier to use
|
||||||
libzip as subproject.
|
libzip as subproject.
|
||||||
|
|
||||||
1.7.0 [2020-06-05]
|
|
||||||
==================
|
# 1.7.0 [2020-06-05]
|
||||||
|
|
||||||
* Add support for encrypting using traditional PKWare encryption.
|
* Add support for encrypting using traditional PKWare encryption.
|
||||||
* Add `zip_compression_method_supported()`.
|
* Add `zip_compression_method_supported()`.
|
||||||
@@ -61,13 +79,13 @@
|
|||||||
* Refactor stdio file backend.
|
* Refactor stdio file backend.
|
||||||
* Add CMake find_project() support.
|
* Add CMake find_project() support.
|
||||||
|
|
||||||
1.6.1 [2020-02-03]
|
|
||||||
==================
|
# 1.6.1 [2020-02-03]
|
||||||
|
|
||||||
* Bugfix for double-free in `zipcmp(1)` during cleanup.
|
* Bugfix for double-free in `zipcmp(1)` during cleanup.
|
||||||
|
|
||||||
1.6.0 [2020-01-24]
|
|
||||||
==================
|
# 1.6.0 [2020-01-24]
|
||||||
|
|
||||||
* Avoid using `umask()` since it's not thread-safe.
|
* Avoid using `umask()` since it's not thread-safe.
|
||||||
* Set close-on-exec flag when opening files.
|
* Set close-on-exec flag when opening files.
|
||||||
@@ -76,8 +94,8 @@
|
|||||||
* Add support for cancelling while closing zip archives.
|
* Add support for cancelling while closing zip archives.
|
||||||
* Add support for setting the time in the on-disk format.
|
* Add support for setting the time in the on-disk format.
|
||||||
|
|
||||||
1.5.2 [2019-03-12]
|
|
||||||
==================
|
# 1.5.2 [2019-03-12]
|
||||||
|
|
||||||
* Fix bug in AES encryption affecting certain file sizes
|
* Fix bug in AES encryption affecting certain file sizes
|
||||||
* Keep file permissions when modifying zip archives
|
* Keep file permissions when modifying zip archives
|
||||||
@@ -85,8 +103,8 @@
|
|||||||
* Support mbed TLS as crypto backend.
|
* Support mbed TLS as crypto backend.
|
||||||
* Add nullability annotations.
|
* Add nullability annotations.
|
||||||
|
|
||||||
1.5.1 [2018-04-11]
|
|
||||||
==================
|
# 1.5.1 [2018-04-11]
|
||||||
|
|
||||||
* Choose format of installed documentation based on available tools.
|
* Choose format of installed documentation based on available tools.
|
||||||
* Fix visibility of symbols.
|
* Fix visibility of symbols.
|
||||||
@@ -96,16 +114,16 @@
|
|||||||
* Fix build with LibreSSL.
|
* Fix build with LibreSSL.
|
||||||
* Various bugfixes.
|
* Various bugfixes.
|
||||||
|
|
||||||
1.5.0 [2018-03-11]
|
|
||||||
==================
|
# 1.5.0 [2018-03-11]
|
||||||
|
|
||||||
* Use standard cryptographic library instead of custom AES implementation.
|
* Use standard cryptographic library instead of custom AES implementation.
|
||||||
This also simplifies the license.
|
This also simplifies the license.
|
||||||
* Use `clang-format` to format the source code.
|
* Use `clang-format` to format the source code.
|
||||||
* More Windows improvements.
|
* More Windows improvements.
|
||||||
|
|
||||||
1.4.0 [2017-12-29]
|
|
||||||
==================
|
# 1.4.0 [2017-12-29]
|
||||||
|
|
||||||
* Improve build with cmake
|
* Improve build with cmake
|
||||||
* Retire autoconf/automake build system
|
* Retire autoconf/automake build system
|
||||||
@@ -114,20 +132,20 @@
|
|||||||
Supported for buffer sources and on Apple File System.
|
Supported for buffer sources and on Apple File System.
|
||||||
* Add support for Microsoft Universal Windows Platform.
|
* Add support for Microsoft Universal Windows Platform.
|
||||||
|
|
||||||
1.3.2 [2017-11-20]
|
|
||||||
==================
|
# 1.3.2 [2017-11-20]
|
||||||
|
|
||||||
* Fix bug introduced in last: zip_t was erroneously freed if zip_close() failed.
|
* Fix bug introduced in last: zip_t was erroneously freed if zip_close() failed.
|
||||||
|
|
||||||
1.3.1 [2017-11-19]
|
|
||||||
==================
|
# 1.3.1 [2017-11-19]
|
||||||
|
|
||||||
* Install zipconf.h into ${PREFIX}/include
|
* Install zipconf.h into ${PREFIX}/include
|
||||||
* Add zip_libzip_version()
|
* Add zip_libzip_version()
|
||||||
* Fix AES tests on Linux
|
* Fix AES tests on Linux
|
||||||
|
|
||||||
1.3.0 [2017-09-02]
|
|
||||||
==================
|
# 1.3.0 [2017-09-02]
|
||||||
|
|
||||||
* Support bzip2 compressed zip archives
|
* Support bzip2 compressed zip archives
|
||||||
* Improve file progress callback code
|
* Improve file progress callback code
|
||||||
@@ -135,8 +153,8 @@
|
|||||||
* CVE-2017-12858: Fix double free()
|
* CVE-2017-12858: Fix double free()
|
||||||
* CVE-2017-14107: Improve EOCD64 parsing
|
* CVE-2017-14107: Improve EOCD64 parsing
|
||||||
|
|
||||||
1.2.0 [2017-02-19]
|
|
||||||
==================
|
# 1.2.0 [2017-02-19]
|
||||||
|
|
||||||
* Support for AES encryption (Winzip version), both encryption
|
* Support for AES encryption (Winzip version), both encryption
|
||||||
and decryption
|
and decryption
|
||||||
@@ -146,24 +164,24 @@
|
|||||||
* Add zip_ftell() for telling position in uncompressed data
|
* Add zip_ftell() for telling position in uncompressed data
|
||||||
* Add zip_register_progress_callback() for UI updates during zip_close()
|
* Add zip_register_progress_callback() for UI updates during zip_close()
|
||||||
|
|
||||||
1.1.3 [2016-05-28]
|
|
||||||
==================
|
# 1.1.3 [2016-05-28]
|
||||||
|
|
||||||
* Fix build on Windows when using autoconf
|
* Fix build on Windows when using autoconf
|
||||||
|
|
||||||
1.1.2 [2016-02-19]
|
|
||||||
==================
|
# 1.1.2 [2016-02-19]
|
||||||
|
|
||||||
* Improve support for 3MF files
|
* Improve support for 3MF files
|
||||||
|
|
||||||
1.1.1 [2016-02-07]
|
|
||||||
==================
|
# 1.1.1 [2016-02-07]
|
||||||
|
|
||||||
* Build fixes for Linux
|
* Build fixes for Linux
|
||||||
* Fix some warnings reported by PVS-Studio
|
* Fix some warnings reported by PVS-Studio
|
||||||
|
|
||||||
1.1 [2016-01-26]
|
|
||||||
================
|
# 1.1 [2016-01-26]
|
||||||
|
|
||||||
* ziptool(1): command line tool to modify zip archives
|
* ziptool(1): command line tool to modify zip archives
|
||||||
* Speedups for archives with many entries
|
* Speedups for archives with many entries
|
||||||
@@ -174,13 +192,13 @@
|
|||||||
* Portability fixes
|
* Portability fixes
|
||||||
* Documentation improvements
|
* Documentation improvements
|
||||||
|
|
||||||
1.0.1 [2015-05-04]
|
|
||||||
==================
|
# 1.0.1 [2015-05-04]
|
||||||
|
|
||||||
* Build fixes for Windows
|
* Build fixes for Windows
|
||||||
|
|
||||||
1.0 [2015-05-03]
|
|
||||||
================
|
# 1.0 [2015-05-03]
|
||||||
|
|
||||||
* Implemented an I/O abstraction layer
|
* Implemented an I/O abstraction layer
|
||||||
* Added support for native Windows API for files
|
* Added support for native Windows API for files
|
||||||
@@ -191,22 +209,22 @@
|
|||||||
* CVE-2015-2331 was fixed
|
* CVE-2015-2331 was fixed
|
||||||
* Addressed all Coverity CIDs
|
* Addressed all Coverity CIDs
|
||||||
|
|
||||||
0.11.2 [2013-12-19]
|
|
||||||
===================
|
# 0.11.2 [2013-12-19]
|
||||||
|
|
||||||
* Support querying/setting operating system and external attributes
|
* Support querying/setting operating system and external attributes
|
||||||
* For newly added files, set operating system to UNIX, permissions
|
* For newly added files, set operating system to UNIX, permissions
|
||||||
to 0666 (0777 for directories)
|
to 0666 (0777 for directories)
|
||||||
* Fix bug when writing zip archives containing files bigger than 4GB
|
* Fix bug when writing zip archives containing files bigger than 4GB
|
||||||
|
|
||||||
0.11.1 [2013-04-27]
|
|
||||||
===================
|
# 0.11.1 [2013-04-27]
|
||||||
|
|
||||||
* Fix bugs in zip_set_file_compression()
|
* Fix bugs in zip_set_file_compression()
|
||||||
* Include Xcode build infrastructure
|
* Include Xcode build infrastructure
|
||||||
|
|
||||||
0.11 [2013-03-23]
|
|
||||||
=================
|
# 0.11 [2013-03-23]
|
||||||
|
|
||||||
* Added Zip64 support (large file support)
|
* Added Zip64 support (large file support)
|
||||||
* Added UTF-8 support for file names, file comments, and archive comments
|
* Added UTF-8 support for file names, file comments, and archive comments
|
||||||
@@ -220,14 +238,14 @@
|
|||||||
* More changes for Windows support
|
* More changes for Windows support
|
||||||
* Additional test cases
|
* Additional test cases
|
||||||
|
|
||||||
0.10.1 [2012-03-20]
|
|
||||||
===================
|
# 0.10.1 [2012-03-20]
|
||||||
|
|
||||||
* Fixed CVE-2012-1162
|
* Fixed CVE-2012-1162
|
||||||
* Fixed CVE-2012-1163
|
* Fixed CVE-2012-1163
|
||||||
|
|
||||||
0.10 [2010-03-18]
|
|
||||||
=================
|
# 0.10 [2010-03-18]
|
||||||
|
|
||||||
* Added zip_get_num_entries(), deprecated zip_get_num_files()
|
* Added zip_get_num_entries(), deprecated zip_get_num_files()
|
||||||
* Better windows support
|
* Better windows support
|
||||||
@@ -239,27 +257,27 @@
|
|||||||
* Fixed CVE-2011-0421 (no security implications though)
|
* Fixed CVE-2011-0421 (no security implications though)
|
||||||
* More documentation
|
* More documentation
|
||||||
|
|
||||||
0.9.3 [2010-02-01]
|
|
||||||
==================
|
# 0.9.3 [2010-02-01]
|
||||||
|
|
||||||
* Include m4/ directory in distribution; some packagers need it
|
* Include m4/ directory in distribution; some packagers need it
|
||||||
|
|
||||||
0.9.2 [2010-01-31]
|
|
||||||
==================
|
# 0.9.2 [2010-01-31]
|
||||||
|
|
||||||
* Avoid passing uninitialized data to deflate()
|
* Avoid passing uninitialized data to deflate()
|
||||||
* Fix memory leak when closing zip archives
|
* Fix memory leak when closing zip archives
|
||||||
|
|
||||||
0.9.1 [2010-01-24]
|
|
||||||
==================
|
# 0.9.1 [2010-01-24]
|
||||||
|
|
||||||
* Fix infinite loop on reading some broken files
|
* Fix infinite loop on reading some broken files
|
||||||
* Optimization in time conversion (don't call localtime())
|
* Optimization in time conversion (don't call localtime())
|
||||||
* Clear data descriptor flag in central directory, fixing Open Office files
|
* Clear data descriptor flag in central directory, fixing Open Office files
|
||||||
* Allow more than 64k entries
|
* Allow more than 64k entries
|
||||||
|
|
||||||
0.9 [2008-07-25]
|
|
||||||
==================
|
# 0.9 [2008-07-25]
|
||||||
|
|
||||||
* on Windows, explicitly set dllimport/dllexport
|
* on Windows, explicitly set dllimport/dllexport
|
||||||
* remove erroneous references to GPL
|
* remove erroneous references to GPL
|
||||||
@@ -268,8 +286,8 @@
|
|||||||
* zip_source_zip: add flag to force recompression
|
* zip_source_zip: add flag to force recompression
|
||||||
* zip_sorce_file: only keep file open while reading from it
|
* zip_sorce_file: only keep file open while reading from it
|
||||||
|
|
||||||
0.8 [2007-06-06]
|
|
||||||
==================
|
# 0.8 [2007-06-06]
|
||||||
|
|
||||||
* fix for zip archives larger than 2GiB
|
* fix for zip archives larger than 2GiB
|
||||||
* fix zip_error_strerror to include libzip error string
|
* fix zip_error_strerror to include libzip error string
|
||||||
@@ -277,13 +295,13 @@
|
|||||||
* new functions: zip_add_dir, zip_error_clear, zip_file_error_clear
|
* new functions: zip_add_dir, zip_error_clear, zip_file_error_clear
|
||||||
* add basic support for building with CMake (incomplete)
|
* add basic support for building with CMake (incomplete)
|
||||||
|
|
||||||
0.7.1 [2006-05-18]
|
|
||||||
==================
|
# 0.7.1 [2006-05-18]
|
||||||
|
|
||||||
* bugfix for zip_close
|
* bugfix for zip_close
|
||||||
|
|
||||||
0.7 [2006-05-06]
|
|
||||||
================
|
# 0.7 [2006-05-06]
|
||||||
|
|
||||||
* struct zip_stat increased for future encryption support
|
* struct zip_stat increased for future encryption support
|
||||||
* zip_add return value changed (now returns new index of added file)
|
* zip_add return value changed (now returns new index of added file)
|
||||||
@@ -292,13 +310,13 @@
|
|||||||
New functions: zip_get_archive_comment, zip_get_file_comment,
|
New functions: zip_get_archive_comment, zip_get_file_comment,
|
||||||
zip_set_archive_comment, zip_set_file_comment, zip_unchange_archive
|
zip_set_archive_comment, zip_set_file_comment, zip_unchange_archive
|
||||||
|
|
||||||
0.6.1 [2005-07-14]
|
|
||||||
==================
|
# 0.6.1 [2005-07-14]
|
||||||
|
|
||||||
* various bug fixes
|
* various bug fixes
|
||||||
|
|
||||||
0.6 [2005-06-09]
|
|
||||||
================
|
# 0.6 [2005-06-09]
|
||||||
|
|
||||||
* first standalone release
|
* first standalone release
|
||||||
* changed license to three-clause BSD
|
* changed license to three-clause BSD
|
||||||
|
|||||||
@@ -41,6 +41,9 @@
|
|||||||
/* to have *_MAX definitions for all types when compiling with g++ */
|
/* to have *_MAX definitions for all types when compiling with g++ */
|
||||||
#define __STDC_LIMIT_MACROS
|
#define __STDC_LIMIT_MACROS
|
||||||
|
|
||||||
|
/* to have ISO C secure library functions */
|
||||||
|
#define __STDC_WANT_LIB_EXT1__ 1
|
||||||
|
|
||||||
#if defined(_WIN32) && defined(ZIP_DLL) && !defined(ZIP_STATIC)
|
#if defined(_WIN32) && defined(ZIP_DLL) && !defined(ZIP_STATIC)
|
||||||
#ifdef BUILDING_LIBZIP
|
#ifdef BUILDING_LIBZIP
|
||||||
#define ZIP_EXTERN __declspec(dllexport)
|
#define ZIP_EXTERN __declspec(dllexport)
|
||||||
@@ -100,6 +103,9 @@ typedef char bool;
|
|||||||
#if !defined(HAVE_SNPRINTF) && defined(HAVE__SNPRINTF)
|
#if !defined(HAVE_SNPRINTF) && defined(HAVE__SNPRINTF)
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(HAVE__SNWPRINTF_S)
|
||||||
|
#define _snwprintf_s(buf, bufsz, len, fmt, ...) (_snwprintf((buf), (len), (fmt), __VA_ARGS__))
|
||||||
|
#endif
|
||||||
#if defined(HAVE__STRDUP)
|
#if defined(HAVE__STRDUP)
|
||||||
#if !defined(HAVE_STRDUP) || defined(_WIN32)
|
#if !defined(HAVE_STRDUP) || defined(_WIN32)
|
||||||
#undef strdup
|
#undef strdup
|
||||||
@@ -128,6 +134,33 @@ typedef char bool;
|
|||||||
#define ftello(s) ((long)ftell((s)))
|
#define ftello(s) ((long)ftell((s)))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_LOCALTIME_S
|
||||||
|
#ifdef _WIN32
|
||||||
|
/* Windows is incompatible to the C11 standard, hurray! */
|
||||||
|
#define zip_localtime(t, tm) (localtime_s((tm), (t)) == 0 ? tm : NULL)
|
||||||
|
#else
|
||||||
|
#define zip_localtime localtime_s
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_LOCALTIME_R
|
||||||
|
#define zip_localtime localtime_r
|
||||||
|
#else
|
||||||
|
#define zip_localtime(t, tm) (localtime(t))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_MEMCPY_S
|
||||||
|
#define memcpy_s(dest, destsz, src, count) (memcpy((dest), (src), (count)) == NULL)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_SNPRINTF_S
|
||||||
|
#ifdef HAVE__SNPRINTF_S
|
||||||
|
#define snprintf_s(buf, bufsz, fmt, ...) (_snprintf_s((buf), (bufsz), (bufsz), (fmt), __VA_ARGS__))
|
||||||
|
#else
|
||||||
|
#define snprintf_s snprintf
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(HAVE_STRCASECMP)
|
#if !defined(HAVE_STRCASECMP)
|
||||||
#if defined(HAVE__STRICMP)
|
#if defined(HAVE__STRICMP)
|
||||||
#define strcasecmp _stricmp
|
#define strcasecmp _stricmp
|
||||||
@@ -136,6 +169,19 @@ typedef char bool;
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_STRNCPY_S
|
||||||
|
#define strncpy_s(dest, destsz, src, count) (strncpy((dest), (src), (count)), 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_STRERROR_S
|
||||||
|
#define strerrorlen_s(errnum) (strlen(strerror(errnum)))
|
||||||
|
#define strerror_s(buf, bufsz, errnum) ((void)strncpy_s((buf), (bufsz), strerror(errnum), (bufsz)), (buf)[(bufsz)-1] = '\0', strerrorlen_s(errnum) >= (bufsz))
|
||||||
|
#else
|
||||||
|
#ifndef HAVE_STRERRORLEN_S
|
||||||
|
#define strerrorlen_s(errnum) 8192
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if SIZEOF_OFF_T == 8
|
#if SIZEOF_OFF_T == 8
|
||||||
#define ZIP_OFF_MAX ZIP_INT64_MAX
|
#define ZIP_OFF_MAX ZIP_INT64_MAX
|
||||||
#define ZIP_OFF_MIN ZIP_INT64_MIN
|
#define ZIP_OFF_MIN ZIP_INT64_MIN
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "zipconf.h"
|
#include "zipconf.h"
|
||||||
#endif
|
#endif
|
||||||
/* BEGIN DEFINES */
|
/* BEGIN DEFINES */
|
||||||
|
#define ENABLE_FDOPEN
|
||||||
/* #undef HAVE___PROGNAME */
|
/* #undef HAVE___PROGNAME */
|
||||||
#define HAVE__CLOSE
|
#define HAVE__CLOSE
|
||||||
#define HAVE__DUP
|
#define HAVE__DUP
|
||||||
@@ -15,11 +16,12 @@
|
|||||||
#else
|
#else
|
||||||
/* #undef HAVE__SNPRINTF */
|
/* #undef HAVE__SNPRINTF */
|
||||||
#endif
|
#endif
|
||||||
|
#define HAVE__SNPRINTF_S
|
||||||
|
#define HAVE__SNWPRINTF_S
|
||||||
#define HAVE__STRDUP
|
#define HAVE__STRDUP
|
||||||
#define HAVE__STRICMP
|
#define HAVE__STRICMP
|
||||||
#define HAVE__STRTOI64
|
#define HAVE__STRTOI64
|
||||||
#define HAVE__STRTOUI64
|
#define HAVE__STRTOUI64
|
||||||
/* #undef HAVE__UMASK */
|
|
||||||
#define HAVE__UNLINK
|
#define HAVE__UNLINK
|
||||||
/* #undef HAVE_ARC4RANDOM */
|
/* #undef HAVE_ARC4RANDOM */
|
||||||
/* #undef HAVE_CLONEFILE */
|
/* #undef HAVE_CLONEFILE */
|
||||||
@@ -36,6 +38,8 @@
|
|||||||
/* #undef HAVE_LIBLZMA */
|
/* #undef HAVE_LIBLZMA */
|
||||||
/* #undef HAVE_LIBZSTD */
|
/* #undef HAVE_LIBZSTD */
|
||||||
/* #undef HAVE_LOCALTIME_R */
|
/* #undef HAVE_LOCALTIME_R */
|
||||||
|
#define HAVE_LOCALTIME_S
|
||||||
|
#define HAVE_MEMCPY_S
|
||||||
/* #undef HAVE_MBEDTLS */
|
/* #undef HAVE_MBEDTLS */
|
||||||
/* #undef HAVE_MKSTEMP */
|
/* #undef HAVE_MKSTEMP */
|
||||||
/* #undef HAVE_NULLABLE */
|
/* #undef HAVE_NULLABLE */
|
||||||
@@ -46,9 +50,13 @@
|
|||||||
#else
|
#else
|
||||||
#define HAVE_SNPRINTF
|
#define HAVE_SNPRINTF
|
||||||
#endif
|
#endif
|
||||||
|
/* #undef HAVE_SNPRINTF_S */
|
||||||
/* #undef HAVE_STRCASECMP */
|
/* #undef HAVE_STRCASECMP */
|
||||||
#define HAVE_STRDUP
|
#define HAVE_STRDUP
|
||||||
|
#define HAVE_STRERROR_S
|
||||||
|
/* #undef HAVE_STRERRORLEN_S */
|
||||||
#define HAVE_STRICMP
|
#define HAVE_STRICMP
|
||||||
|
#define HAVE_STRNCPY_S
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1800
|
#if defined(_MSC_VER) && _MSC_VER < 1800
|
||||||
/* #undef HAVE_STRTOLL */
|
/* #undef HAVE_STRTOLL */
|
||||||
/* #undef HAVE_STRTOULL */
|
/* #undef HAVE_STRTOULL */
|
||||||
@@ -80,6 +88,6 @@
|
|||||||
#define HAVE_SHARED
|
#define HAVE_SHARED
|
||||||
/* END DEFINES */
|
/* END DEFINES */
|
||||||
#define PACKAGE "libzip"
|
#define PACKAGE "libzip"
|
||||||
#define VERSION "1.9.2"
|
#define VERSION "1.10.0"
|
||||||
|
|
||||||
#endif /* HAD_CONFIG_H */
|
#endif /* HAD_CONFIG_H */
|
||||||
|
|||||||
@@ -62,6 +62,16 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef ZIP_DEPRECATED
|
||||||
|
#if defined(__GNUC__) || defined(__clang__)
|
||||||
|
#define ZIP_DEPRECATED(x) __attribute__((deprecated(x)))
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define ZIP_DEPRECATED(x) __declspec(deprecated(x))
|
||||||
|
#else
|
||||||
|
#define ZIP_DEPRECATED(x)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@@ -81,7 +91,7 @@ extern "C" {
|
|||||||
#define ZIP_FL_NODIR 2u /* ignore directory component */
|
#define ZIP_FL_NODIR 2u /* ignore directory component */
|
||||||
#define ZIP_FL_COMPRESSED 4u /* read compressed data */
|
#define ZIP_FL_COMPRESSED 4u /* read compressed data */
|
||||||
#define ZIP_FL_UNCHANGED 8u /* use original data, ignoring changes */
|
#define ZIP_FL_UNCHANGED 8u /* use original data, ignoring changes */
|
||||||
#define ZIP_FL_RECOMPRESS 16u /* force recompression of data */
|
/* 16u was ZIP_FL_RECOMPRESS, which is deprecated */
|
||||||
#define ZIP_FL_ENCRYPTED 32u /* read encrypted data (implies ZIP_FL_COMPRESSED) */
|
#define ZIP_FL_ENCRYPTED 32u /* read encrypted data (implies ZIP_FL_COMPRESSED) */
|
||||||
#define ZIP_FL_ENC_GUESS 0u /* guess string encoding (is default) */
|
#define ZIP_FL_ENC_GUESS 0u /* guess string encoding (is default) */
|
||||||
#define ZIP_FL_ENC_RAW 64u /* get unmodified string */
|
#define ZIP_FL_ENC_RAW 64u /* get unmodified string */
|
||||||
@@ -95,7 +105,10 @@ extern "C" {
|
|||||||
|
|
||||||
/* archive global flags flags */
|
/* archive global flags flags */
|
||||||
|
|
||||||
#define ZIP_AFL_RDONLY 2u /* read only -- cannot be cleared */
|
#define ZIP_AFL_RDONLY 2u /* read only -- cannot be cleared */
|
||||||
|
#define ZIP_AFL_IS_TORRENTZIP 4u /* current archive is torrentzipped */
|
||||||
|
#define ZIP_AFL_WANT_TORRENTZIP 8u /* write archive in torrentzip format */
|
||||||
|
#define ZIP_AFL_CREATE_OR_KEEP_FILE_FOR_EMPTY_ARCHIVE 16u /* don't remove file if archive is empty */
|
||||||
|
|
||||||
|
|
||||||
/* create a new extra field */
|
/* create a new extra field */
|
||||||
@@ -139,6 +152,8 @@ extern "C" {
|
|||||||
#define ZIP_ER_TELL 30 /* S Tell error */
|
#define ZIP_ER_TELL 30 /* S Tell error */
|
||||||
#define ZIP_ER_COMPRESSED_DATA 31 /* N Compressed data invalid */
|
#define ZIP_ER_COMPRESSED_DATA 31 /* N Compressed data invalid */
|
||||||
#define ZIP_ER_CANCELLED 32 /* N Operation cancelled */
|
#define ZIP_ER_CANCELLED 32 /* N Operation cancelled */
|
||||||
|
#define ZIP_ER_DATA_LENGTH 33 /* N Unexpected length of data */
|
||||||
|
#define ZIP_ER_NOT_ALLOWED 34 /* N Not allowed in torrentzip */
|
||||||
|
|
||||||
/* type of system error value */
|
/* type of system error value */
|
||||||
|
|
||||||
@@ -240,7 +255,8 @@ enum zip_source_cmd {
|
|||||||
ZIP_SOURCE_RESERVED_1, /* previously used internally */
|
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_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_ACCEPT_EMPTY, /* whether empty files are valid archives */
|
||||||
ZIP_SOURCE_GET_FILE_ATTRIBUTES /* get additional file attributes */
|
ZIP_SOURCE_GET_FILE_ATTRIBUTES, /* get additional file attributes */
|
||||||
|
ZIP_SOURCE_SUPPORTS_REOPEN /* allow reading from changed entry */
|
||||||
};
|
};
|
||||||
typedef enum zip_source_cmd zip_source_cmd_t;
|
typedef enum zip_source_cmd zip_source_cmd_t;
|
||||||
|
|
||||||
@@ -351,24 +367,29 @@ typedef struct zip_buffer_fragment zip_buffer_fragment_t;
|
|||||||
typedef zip_uint32_t zip_flags_t;
|
typedef zip_uint32_t zip_flags_t;
|
||||||
|
|
||||||
typedef zip_int64_t (*zip_source_callback)(void *_Nullable, void *_Nullable, zip_uint64_t, zip_source_cmd_t);
|
typedef zip_int64_t (*zip_source_callback)(void *_Nullable, void *_Nullable, zip_uint64_t, zip_source_cmd_t);
|
||||||
|
typedef zip_int64_t (*zip_source_layered_callback)(zip_source_t *_Nonnull, void *_Nullable, void *_Nullable, zip_uint64_t, enum zip_source_cmd);
|
||||||
typedef void (*zip_progress_callback)(zip_t *_Nonnull, double, void *_Nullable);
|
typedef void (*zip_progress_callback)(zip_t *_Nonnull, double, void *_Nullable);
|
||||||
typedef int (*zip_cancel_callback)(zip_t *_Nonnull, void *_Nullable);
|
typedef int (*zip_cancel_callback)(zip_t *_Nonnull, void *_Nullable);
|
||||||
|
|
||||||
#ifndef ZIP_DISABLE_DEPRECATED
|
#ifndef ZIP_DISABLE_DEPRECATED
|
||||||
typedef void (*zip_progress_callback_t)(double);
|
#define ZIP_FL_RECOMPRESS 16u /* force recompression of data */
|
||||||
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 */
|
typedef void (*zip_progress_callback_t)(double);
|
||||||
ZIP_EXTERN zip_int64_t zip_add_dir(zip_t *_Nonnull, const char *_Nonnull); /* use zip_dir_add */
|
ZIP_DEPRECATED("use 'zip_register_progress_callback_with_state' instead") ZIP_EXTERN void zip_register_progress_callback(zip_t *_Nonnull, zip_progress_callback_t _Nullable);
|
||||||
ZIP_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_DEPRECATED("use 'zip_file_add' instead") ZIP_EXTERN zip_int64_t zip_add(zip_t *_Nonnull, const char *_Nonnull, zip_source_t *_Nonnull);
|
||||||
ZIP_EXTERN int zip_rename(zip_t *_Nonnull, zip_uint64_t, const char *_Nonnull); /* use zip_file_rename */
|
ZIP_DEPRECATED("use 'zip_dir_add' instead") ZIP_EXTERN zip_int64_t zip_add_dir(zip_t *_Nonnull, const char *_Nonnull);
|
||||||
ZIP_EXTERN int zip_replace(zip_t *_Nonnull, zip_uint64_t, zip_source_t *_Nonnull); /* use zip_file_replace */
|
ZIP_DEPRECATED("use 'zip_file_get_comment' instead") ZIP_EXTERN const char *_Nullable zip_get_file_comment(zip_t *_Nonnull, zip_uint64_t, int *_Nullable, int);
|
||||||
ZIP_EXTERN int zip_set_file_comment(zip_t *_Nonnull, zip_uint64_t, const char *_Nullable, int); /* use zip_file_set_comment */
|
ZIP_DEPRECATED("use 'zip_get_num_entries' instead") ZIP_EXTERN int zip_get_num_files(zip_t *_Nonnull);
|
||||||
ZIP_EXTERN int zip_error_get_sys_type(int); /* use zip_error_system_type */
|
ZIP_DEPRECATED("use 'zip_file_rename' instead") ZIP_EXTERN int zip_rename(zip_t *_Nonnull, zip_uint64_t, const char *_Nonnull);
|
||||||
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_DEPRECATED("use 'zip_file_replace' instead") ZIP_EXTERN int zip_replace(zip_t *_Nonnull, zip_uint64_t, zip_source_t *_Nonnull);
|
||||||
ZIP_EXTERN int zip_error_to_str(char *_Nonnull, zip_uint64_t, int, int); /* use zip_error_init_with_code / zip_error_strerror */
|
ZIP_DEPRECATED("use 'zip_file_set_comment' instead") ZIP_EXTERN int zip_set_file_comment(zip_t *_Nonnull, zip_uint64_t, const char *_Nullable, int);
|
||||||
ZIP_EXTERN void zip_file_error_get(zip_file_t *_Nonnull, int *_Nullable, int *_Nullable); /* use zip_file_get_error, zip_error_code_zip / zip_error_code_system */
|
ZIP_DEPRECATED("use 'zip_error_init_with_code' and 'zip_error_system_type' instead") ZIP_EXTERN int zip_error_get_sys_type(int);
|
||||||
|
ZIP_DEPRECATED("use 'zip_get_error' instead") ZIP_EXTERN void zip_error_get(zip_t *_Nonnull, int *_Nullable, int *_Nullable);
|
||||||
|
ZIP_DEPRECATED("use 'zip_error_strerror' instead") ZIP_EXTERN int zip_error_to_str(char *_Nonnull, zip_uint64_t, int, int);
|
||||||
|
ZIP_DEPRECATED("use 'zip_file_get_error' instead") ZIP_EXTERN void zip_file_error_get(zip_file_t *_Nonnull, int *_Nullable, int *_Nullable);
|
||||||
|
ZIP_DEPRECATED("use 'zip_source_zip_file' instead") ZIP_EXTERN zip_source_t *_Nullable zip_source_zip(zip_t *_Nonnull, zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_int64_t);
|
||||||
|
ZIP_DEPRECATED("use 'zip_source_zip_file_create' instead") ZIP_EXTERN zip_source_t *_Nullable zip_source_zip_create(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_int64_t, zip_error_t *_Nullable);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ZIP_EXTERN int zip_close(zip_t *_Nonnull);
|
ZIP_EXTERN int zip_close(zip_t *_Nonnull);
|
||||||
@@ -384,6 +405,7 @@ ZIP_EXTERN void zip_error_fini(zip_error_t *_Nonnull);
|
|||||||
ZIP_EXTERN void zip_error_init(zip_error_t *_Nonnull);
|
ZIP_EXTERN void zip_error_init(zip_error_t *_Nonnull);
|
||||||
ZIP_EXTERN void zip_error_init_with_code(zip_error_t *_Nonnull, int);
|
ZIP_EXTERN void zip_error_init_with_code(zip_error_t *_Nonnull, int);
|
||||||
ZIP_EXTERN void zip_error_set(zip_error_t *_Nullable, int, int);
|
ZIP_EXTERN void zip_error_set(zip_error_t *_Nullable, int, int);
|
||||||
|
ZIP_EXTERN void zip_error_set_from_source(zip_error_t *_Nonnull, zip_source_t *_Nullable);
|
||||||
ZIP_EXTERN const char *_Nonnull zip_error_strerror(zip_error_t *_Nonnull);
|
ZIP_EXTERN const char *_Nonnull zip_error_strerror(zip_error_t *_Nonnull);
|
||||||
ZIP_EXTERN int zip_error_system_type(const 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 zip_int64_t zip_error_to_data(const zip_error_t *_Nonnull, void *_Nonnull, zip_uint64_t);
|
||||||
@@ -451,9 +473,13 @@ ZIP_EXTERN zip_source_t *_Nullable zip_source_function(zip_t *_Nonnull, zip_sour
|
|||||||
ZIP_EXTERN zip_source_t *_Nullable zip_source_function_create(zip_source_callback _Nonnull, void *_Nullable, zip_error_t *_Nullable);
|
ZIP_EXTERN 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_get_file_attributes(zip_source_t *_Nonnull, zip_file_attributes_t *_Nonnull);
|
||||||
ZIP_EXTERN int zip_source_is_deleted(zip_source_t *_Nonnull);
|
ZIP_EXTERN int zip_source_is_deleted(zip_source_t *_Nonnull);
|
||||||
|
ZIP_EXTERN int zip_source_is_seekable(zip_source_t *_Nonnull);
|
||||||
ZIP_EXTERN void zip_source_keep(zip_source_t *_Nonnull);
|
ZIP_EXTERN void zip_source_keep(zip_source_t *_Nonnull);
|
||||||
|
ZIP_EXTERN zip_source_t *_Nullable zip_source_layered(zip_t *_Nullable, zip_source_t *_Nonnull, zip_source_layered_callback _Nonnull, void *_Nullable);
|
||||||
|
ZIP_EXTERN zip_source_t *_Nullable zip_source_layered_create(zip_source_t *_Nonnull, zip_source_layered_callback _Nonnull, void *_Nullable, zip_error_t *_Nullable);
|
||||||
ZIP_EXTERN zip_int64_t zip_source_make_command_bitmap(zip_source_cmd_t, ...);
|
ZIP_EXTERN zip_int64_t zip_source_make_command_bitmap(zip_source_cmd_t, ...);
|
||||||
ZIP_EXTERN int zip_source_open(zip_source_t *_Nonnull);
|
ZIP_EXTERN int zip_source_open(zip_source_t *_Nonnull);
|
||||||
|
ZIP_EXTERN zip_int64_t zip_source_pass_to_lower_layer(zip_source_t *_Nonnull, void *_Nullable, zip_uint64_t, zip_source_cmd_t);
|
||||||
ZIP_EXTERN zip_int64_t zip_source_read(zip_source_t *_Nonnull, void *_Nonnull, zip_uint64_t);
|
ZIP_EXTERN 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 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 int zip_source_seek(zip_source_t *_Nonnull, zip_int64_t, int);
|
||||||
@@ -463,17 +489,17 @@ ZIP_EXTERN int zip_source_stat(zip_source_t *_Nonnull, zip_stat_t *_Nonnull);
|
|||||||
ZIP_EXTERN zip_int64_t zip_source_tell(zip_source_t *_Nonnull);
|
ZIP_EXTERN zip_int64_t zip_source_tell(zip_source_t *_Nonnull);
|
||||||
ZIP_EXTERN zip_int64_t zip_source_tell_write(zip_source_t *_Nonnull);
|
ZIP_EXTERN zip_int64_t zip_source_tell_write(zip_source_t *_Nonnull);
|
||||||
#ifdef _WIN32
|
#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 *_Nullable zip_source_win32a(zip_t *_Nonnull, const char *_Nonnull, 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 *_Nullable zip_source_win32a_create(const char *_Nonnull, zip_uint64_t, zip_int64_t, zip_error_t *_Nullable);
|
||||||
ZIP_EXTERN zip_source_t *zip_source_win32handle(zip_t *, void *, zip_uint64_t, zip_int64_t);
|
ZIP_EXTERN zip_source_t *_Nullable zip_source_win32handle(zip_t *_Nonnull, void *_Nonnull, zip_uint64_t, zip_int64_t);
|
||||||
ZIP_EXTERN zip_source_t *zip_source_win32handle_create(void *, zip_uint64_t, zip_int64_t, zip_error_t *);
|
ZIP_EXTERN zip_source_t *_Nullable zip_source_win32handle_create(void *_Nonnull, zip_uint64_t, zip_int64_t, zip_error_t *_Nullable);
|
||||||
ZIP_EXTERN zip_source_t *zip_source_win32w(zip_t *, const wchar_t *, zip_uint64_t, zip_int64_t);
|
ZIP_EXTERN zip_source_t *_Nullable zip_source_win32w(zip_t *_Nonnull, const wchar_t *_Nonnull, zip_uint64_t, zip_int64_t);
|
||||||
ZIP_EXTERN zip_source_t *zip_source_win32w_create(const wchar_t *, zip_uint64_t, zip_int64_t, zip_error_t *);
|
ZIP_EXTERN zip_source_t *_Nullable zip_source_win32w_create(const wchar_t *_Nonnull, zip_uint64_t, zip_int64_t, zip_error_t *_Nullable);
|
||||||
#endif
|
#endif
|
||||||
ZIP_EXTERN zip_source_t *_Nullable zip_source_window_create(zip_source_t *_Nonnull, zip_uint64_t, zip_int64_t, zip_error_t *_Nullable);
|
ZIP_EXTERN zip_source_t *_Nullable zip_source_window_create(zip_source_t *_Nonnull, zip_uint64_t, zip_int64_t, zip_error_t *_Nullable);
|
||||||
ZIP_EXTERN zip_int64_t zip_source_write(zip_source_t *_Nonnull, const void *_Nullable, zip_uint64_t);
|
ZIP_EXTERN zip_int64_t zip_source_write(zip_source_t *_Nonnull, const void *_Nullable, zip_uint64_t);
|
||||||
ZIP_EXTERN zip_source_t *_Nullable zip_source_zip(zip_t *_Nonnull, zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_int64_t);
|
ZIP_EXTERN zip_source_t *_Nullable zip_source_zip_file(zip_t *_Nonnull, zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_int64_t, const char *_Nullable);
|
||||||
ZIP_EXTERN zip_source_t *_Nullable zip_source_zip_create(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_int64_t, zip_error_t *_Nullable);
|
ZIP_EXTERN zip_source_t *_Nullable zip_source_zip_file_create(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_int64_t, const char *_Nullable, zip_error_t *_Nullable);
|
||||||
ZIP_EXTERN int zip_stat(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t, zip_stat_t *_Nonnull);
|
ZIP_EXTERN int zip_stat(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 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 void zip_stat_init(zip_stat_t *_Nonnull);
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ maximum_compressed_size(zip_uint64_t uncompressed_size) {
|
|||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
allocate(bool compress, int compression_flags, zip_error_t *error) {
|
allocate(bool compress, zip_uint32_t compression_flags, zip_error_t *error) {
|
||||||
struct ctx *ctx;
|
struct ctx *ctx;
|
||||||
|
|
||||||
if ((ctx = (struct ctx *)malloc(sizeof(*ctx))) == NULL) {
|
if ((ctx = (struct ctx *)malloc(sizeof(*ctx))) == NULL) {
|
||||||
@@ -67,8 +67,10 @@ allocate(bool compress, int compression_flags, zip_error_t *error) {
|
|||||||
|
|
||||||
ctx->error = error;
|
ctx->error = error;
|
||||||
ctx->compress = compress;
|
ctx->compress = compress;
|
||||||
ctx->compression_flags = compression_flags;
|
if (compression_flags >= 1 && compression_flags <= 9) {
|
||||||
if (ctx->compression_flags < 1 || ctx->compression_flags > 9) {
|
ctx->compression_flags = (int)compression_flags;
|
||||||
|
}
|
||||||
|
else {
|
||||||
ctx->compression_flags = 9;
|
ctx->compression_flags = 9;
|
||||||
}
|
}
|
||||||
ctx->end_of_input = false;
|
ctx->end_of_input = false;
|
||||||
@@ -82,13 +84,15 @@ allocate(bool compress, int compression_flags, zip_error_t *error) {
|
|||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
compress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) {
|
compress_allocate(zip_uint16_t method, zip_uint32_t compression_flags, zip_error_t *error) {
|
||||||
|
(void)method;
|
||||||
return allocate(true, compression_flags, error);
|
return allocate(true, compression_flags, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
decompress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) {
|
decompress_allocate(zip_uint16_t method, zip_uint32_t compression_flags, zip_error_t *error) {
|
||||||
|
(void)method;
|
||||||
return allocate(false, compression_flags, error);
|
return allocate(false, compression_flags, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,6 +107,7 @@ deallocate(void *ud) {
|
|||||||
|
|
||||||
static zip_uint16_t
|
static zip_uint16_t
|
||||||
general_purpose_bit_flags(void *ud) {
|
general_purpose_bit_flags(void *ud) {
|
||||||
|
(void)ud;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,8 +137,6 @@ map_error(int ret) {
|
|||||||
case BZ_IO_ERROR:
|
case BZ_IO_ERROR:
|
||||||
case BZ_OUTBUFF_FULL:
|
case BZ_OUTBUFF_FULL:
|
||||||
case BZ_SEQUENCE_ERROR:
|
case BZ_SEQUENCE_ERROR:
|
||||||
return ZIP_ER_INTERNAL;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return ZIP_ER_INTERNAL;
|
return ZIP_ER_INTERNAL;
|
||||||
}
|
}
|
||||||
@@ -144,6 +147,9 @@ start(void *ud, zip_stat_t *st, zip_file_attributes_t *attributes) {
|
|||||||
struct ctx *ctx = (struct ctx *)ud;
|
struct ctx *ctx = (struct ctx *)ud;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
(void)st;
|
||||||
|
(void)attributes;
|
||||||
|
|
||||||
ctx->zstr.avail_in = 0;
|
ctx->zstr.avail_in = 0;
|
||||||
ctx->zstr.next_in = NULL;
|
ctx->zstr.next_in = NULL;
|
||||||
ctx->zstr.avail_out = 0;
|
ctx->zstr.avail_out = 0;
|
||||||
@@ -213,6 +219,7 @@ end_of_input(void *ud) {
|
|||||||
static zip_compression_status_t
|
static zip_compression_status_t
|
||||||
process(void *ud, zip_uint8_t *data, zip_uint64_t *length) {
|
process(void *ud, zip_uint8_t *data, zip_uint64_t *length) {
|
||||||
struct ctx *ctx = (struct ctx *)ud;
|
struct ctx *ctx = (struct ctx *)ud;
|
||||||
|
unsigned int avail_out;
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@@ -221,7 +228,8 @@ process(void *ud, zip_uint8_t *data, zip_uint64_t *length) {
|
|||||||
return ZIP_COMPRESSION_NEED_DATA;
|
return ZIP_COMPRESSION_NEED_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->zstr.avail_out = (unsigned int)ZIP_MIN(UINT_MAX, *length);
|
avail_out = (unsigned int)ZIP_MIN(UINT_MAX, *length);
|
||||||
|
ctx->zstr.avail_out = avail_out;
|
||||||
ctx->zstr.next_out = (char *)data;
|
ctx->zstr.next_out = (char *)data;
|
||||||
|
|
||||||
if (ctx->compress) {
|
if (ctx->compress) {
|
||||||
@@ -231,7 +239,7 @@ process(void *ud, zip_uint8_t *data, zip_uint64_t *length) {
|
|||||||
ret = BZ2_bzDecompress(&ctx->zstr);
|
ret = BZ2_bzDecompress(&ctx->zstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
*length = *length - ctx->zstr.avail_out;
|
*length = avail_out - ctx->zstr.avail_out;
|
||||||
|
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
case BZ_FINISH_OK: /* compression */
|
case BZ_FINISH_OK: /* compression */
|
||||||
|
|||||||
@@ -40,7 +40,8 @@
|
|||||||
struct ctx {
|
struct ctx {
|
||||||
zip_error_t *error;
|
zip_error_t *error;
|
||||||
bool compress;
|
bool compress;
|
||||||
int compression_flags;
|
int level;
|
||||||
|
int mem_level;
|
||||||
bool end_of_input;
|
bool end_of_input;
|
||||||
z_stream zstr;
|
z_stream zstr;
|
||||||
};
|
};
|
||||||
@@ -60,7 +61,7 @@ maximum_compressed_size(zip_uint64_t uncompressed_size) {
|
|||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
allocate(bool compress, int compression_flags, zip_error_t *error) {
|
allocate(bool compress, zip_uint32_t compression_flags, zip_error_t *error) {
|
||||||
struct ctx *ctx;
|
struct ctx *ctx;
|
||||||
|
|
||||||
if ((ctx = (struct ctx *)malloc(sizeof(*ctx))) == NULL) {
|
if ((ctx = (struct ctx *)malloc(sizeof(*ctx))) == NULL) {
|
||||||
@@ -70,10 +71,13 @@ allocate(bool compress, int compression_flags, zip_error_t *error) {
|
|||||||
|
|
||||||
ctx->error = error;
|
ctx->error = error;
|
||||||
ctx->compress = compress;
|
ctx->compress = compress;
|
||||||
ctx->compression_flags = compression_flags;
|
if (compression_flags >= 1 && compression_flags <= 9) {
|
||||||
if (ctx->compression_flags < 1 || ctx->compression_flags > 9) {
|
ctx->level = (int)compression_flags;
|
||||||
ctx->compression_flags = Z_BEST_COMPRESSION;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
ctx->level = Z_BEST_COMPRESSION;
|
||||||
|
}
|
||||||
|
ctx->mem_level = compression_flags == TORRENTZIP_COMPRESSION_FLAGS ? TORRENTZIP_MEM_LEVEL : MAX_MEM_LEVEL;
|
||||||
ctx->end_of_input = false;
|
ctx->end_of_input = false;
|
||||||
|
|
||||||
ctx->zstr.zalloc = Z_NULL;
|
ctx->zstr.zalloc = Z_NULL;
|
||||||
@@ -85,13 +89,15 @@ allocate(bool compress, int compression_flags, zip_error_t *error) {
|
|||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
compress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) {
|
compress_allocate(zip_uint16_t method, zip_uint32_t compression_flags, zip_error_t *error) {
|
||||||
|
(void)method;
|
||||||
return allocate(true, compression_flags, error);
|
return allocate(true, compression_flags, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
decompress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) {
|
decompress_allocate(zip_uint16_t method, zip_uint32_t compression_flags, zip_error_t *error) {
|
||||||
|
(void)method;
|
||||||
return allocate(false, compression_flags, error);
|
return allocate(false, compression_flags, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,10 +118,10 @@ general_purpose_bit_flags(void *ud) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->compression_flags < 3) {
|
if (ctx->level < 3) {
|
||||||
return 2 << 1;
|
return 2 << 1;
|
||||||
}
|
}
|
||||||
else if (ctx->compression_flags > 7) {
|
else if (ctx->level > 7) {
|
||||||
return 1 << 1;
|
return 1 << 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -127,6 +133,9 @@ start(void *ud, zip_stat_t *st, zip_file_attributes_t *attributes) {
|
|||||||
struct ctx *ctx = (struct ctx *)ud;
|
struct ctx *ctx = (struct ctx *)ud;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
(void)st;
|
||||||
|
(void)attributes;
|
||||||
|
|
||||||
ctx->zstr.avail_in = 0;
|
ctx->zstr.avail_in = 0;
|
||||||
ctx->zstr.next_in = NULL;
|
ctx->zstr.next_in = NULL;
|
||||||
ctx->zstr.avail_out = 0;
|
ctx->zstr.avail_out = 0;
|
||||||
@@ -134,7 +143,7 @@ start(void *ud, zip_stat_t *st, zip_file_attributes_t *attributes) {
|
|||||||
|
|
||||||
if (ctx->compress) {
|
if (ctx->compress) {
|
||||||
/* negative value to tell zlib not to write a header */
|
/* negative value to tell zlib not to write a header */
|
||||||
ret = deflateInit2(&ctx->zstr, ctx->compression_flags, Z_DEFLATED, -MAX_WBITS, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
|
ret = deflateInit2(&ctx->zstr, ctx->level, Z_DEFLATED, -MAX_WBITS, ctx->mem_level, Z_DEFAULT_STRATEGY);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ret = inflateInit2(&ctx->zstr, -MAX_WBITS);
|
ret = inflateInit2(&ctx->zstr, -MAX_WBITS);
|
||||||
@@ -198,10 +207,12 @@ end_of_input(void *ud) {
|
|||||||
static zip_compression_status_t
|
static zip_compression_status_t
|
||||||
process(void *ud, zip_uint8_t *data, zip_uint64_t *length) {
|
process(void *ud, zip_uint8_t *data, zip_uint64_t *length) {
|
||||||
struct ctx *ctx = (struct ctx *)ud;
|
struct ctx *ctx = (struct ctx *)ud;
|
||||||
|
uInt avail_out;
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ctx->zstr.avail_out = (uInt)ZIP_MIN(UINT_MAX, *length);
|
avail_out = (uInt)ZIP_MIN(UINT_MAX, *length);
|
||||||
|
ctx->zstr.avail_out = avail_out;
|
||||||
ctx->zstr.next_out = (Bytef *)data;
|
ctx->zstr.next_out = (Bytef *)data;
|
||||||
|
|
||||||
if (ctx->compress) {
|
if (ctx->compress) {
|
||||||
@@ -211,7 +222,7 @@ process(void *ud, zip_uint8_t *data, zip_uint64_t *length) {
|
|||||||
ret = inflate(&ctx->zstr, Z_SYNC_FLUSH);
|
ret = inflate(&ctx->zstr, Z_SYNC_FLUSH);
|
||||||
}
|
}
|
||||||
|
|
||||||
*length = *length - ctx->zstr.avail_out;
|
*length = avail_out - ctx->zstr.avail_out;
|
||||||
|
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
case Z_OK:
|
case Z_OK:
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ maximum_compressed_size(zip_uint64_t uncompressed_size) {
|
|||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
allocate(bool compress, int compression_flags, zip_error_t *error, zip_uint16_t method) {
|
allocate(bool compress, zip_uint32_t compression_flags, zip_error_t *error, zip_uint16_t method) {
|
||||||
struct ctx *ctx;
|
struct ctx *ctx;
|
||||||
|
|
||||||
if ((ctx = (struct ctx *)malloc(sizeof(*ctx))) == NULL) {
|
if ((ctx = (struct ctx *)malloc(sizeof(*ctx))) == NULL) {
|
||||||
@@ -114,16 +114,16 @@ allocate(bool compress, int compression_flags, zip_error_t *error, zip_uint16_t
|
|||||||
|
|
||||||
ctx->error = error;
|
ctx->error = error;
|
||||||
ctx->compress = compress;
|
ctx->compress = compress;
|
||||||
if (compression_flags < 0 || compression_flags > 9) {
|
if (compression_flags <= 9) {
|
||||||
ctx->compression_flags = 6; /* default value */
|
ctx->compression_flags = compression_flags;
|
||||||
} else {
|
} else {
|
||||||
ctx->compression_flags = (zip_uint32_t)compression_flags;
|
ctx->compression_flags = 6; /* default value */
|
||||||
}
|
}
|
||||||
ctx->compression_flags |= LZMA_PRESET_EXTREME;
|
ctx->compression_flags |= LZMA_PRESET_EXTREME;
|
||||||
ctx->end_of_input = false;
|
ctx->end_of_input = false;
|
||||||
memset(ctx->header, 0, sizeof(ctx->header));
|
memset(ctx->header, 0, sizeof(ctx->header));
|
||||||
ctx->header_bytes_offset = 0;
|
ctx->header_bytes_offset = 0;
|
||||||
if (ZIP_CM_LZMA) {
|
if (method == ZIP_CM_LZMA) {
|
||||||
ctx->header_state = INCOMPLETE;
|
ctx->header_state = INCOMPLETE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -136,13 +136,13 @@ allocate(bool compress, int compression_flags, zip_error_t *error, zip_uint16_t
|
|||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
compress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) {
|
compress_allocate(zip_uint16_t method, zip_uint32_t compression_flags, zip_error_t *error) {
|
||||||
return allocate(true, compression_flags, error, method);
|
return allocate(true, compression_flags, error, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
decompress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) {
|
decompress_allocate(zip_uint16_t method, zip_uint32_t compression_flags, zip_error_t *error) {
|
||||||
return allocate(false, compression_flags, error, method);
|
return allocate(false, compression_flags, error, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,7 +258,7 @@ input(void *ud, zip_uint8_t *data, zip_uint64_t length) {
|
|||||||
if (ctx->method == ZIP_CM_LZMA && !ctx->compress && ctx->header_state == INCOMPLETE) {
|
if (ctx->method == ZIP_CM_LZMA && !ctx->compress && ctx->header_state == INCOMPLETE) {
|
||||||
/* if not, get more of the data */
|
/* if not, get more of the data */
|
||||||
zip_uint8_t got = (zip_uint8_t)ZIP_MIN(HEADER_BYTES_ZIP - ctx->header_bytes_offset, length);
|
zip_uint8_t got = (zip_uint8_t)ZIP_MIN(HEADER_BYTES_ZIP - ctx->header_bytes_offset, length);
|
||||||
memcpy(ctx->header + ctx->header_bytes_offset, data, got);
|
(void)memcpy_s(ctx->header + ctx->header_bytes_offset, sizeof(ctx->header) - ctx->header_bytes_offset, data, got);
|
||||||
ctx->header_bytes_offset += got;
|
ctx->header_bytes_offset += got;
|
||||||
length -= got;
|
length -= got;
|
||||||
data += got;
|
data += got;
|
||||||
@@ -313,6 +313,7 @@ end_of_input(void *ud) {
|
|||||||
static zip_compression_status_t
|
static zip_compression_status_t
|
||||||
process(void *ud, zip_uint8_t *data, zip_uint64_t *length) {
|
process(void *ud, zip_uint8_t *data, zip_uint64_t *length) {
|
||||||
struct ctx *ctx = (struct ctx *)ud;
|
struct ctx *ctx = (struct ctx *)ud;
|
||||||
|
uInt avail_out;
|
||||||
lzma_ret ret;
|
lzma_ret ret;
|
||||||
/* for compression of LZMA1 */
|
/* for compression of LZMA1 */
|
||||||
if (ctx->method == ZIP_CM_LZMA && ctx->compress) {
|
if (ctx->method == ZIP_CM_LZMA && ctx->compress) {
|
||||||
@@ -335,7 +336,7 @@ process(void *ud, zip_uint8_t *data, zip_uint64_t *length) {
|
|||||||
if (ctx->header_state == OUTPUT) {
|
if (ctx->header_state == OUTPUT) {
|
||||||
/* write header */
|
/* write header */
|
||||||
zip_uint8_t write_len = (zip_uint8_t)ZIP_MIN(HEADER_BYTES_ZIP - ctx->header_bytes_offset, *length);
|
zip_uint8_t write_len = (zip_uint8_t)ZIP_MIN(HEADER_BYTES_ZIP - ctx->header_bytes_offset, *length);
|
||||||
memcpy(data, ctx->header + ctx->header_bytes_offset, write_len);
|
(void)memcpy_s(data, *length, ctx->header + ctx->header_bytes_offset, write_len);
|
||||||
ctx->header_bytes_offset += write_len;
|
ctx->header_bytes_offset += write_len;
|
||||||
*length = write_len;
|
*length = write_len;
|
||||||
if (ctx->header_bytes_offset == HEADER_BYTES_ZIP) {
|
if (ctx->header_bytes_offset == HEADER_BYTES_ZIP) {
|
||||||
@@ -345,11 +346,12 @@ process(void *ud, zip_uint8_t *data, zip_uint64_t *length) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->zstr.avail_out = (uInt)ZIP_MIN(UINT_MAX, *length);
|
avail_out = (uInt)ZIP_MIN(UINT_MAX, *length);
|
||||||
|
ctx->zstr.avail_out = avail_out;
|
||||||
ctx->zstr.next_out = (Bytef *)data;
|
ctx->zstr.next_out = (Bytef *)data;
|
||||||
|
|
||||||
ret = lzma_code(&ctx->zstr, ctx->end_of_input ? LZMA_FINISH : LZMA_RUN);
|
ret = lzma_code(&ctx->zstr, ctx->end_of_input ? LZMA_FINISH : LZMA_RUN);
|
||||||
*length = *length - ctx->zstr.avail_out;
|
*length = avail_out - ctx->zstr.avail_out;
|
||||||
|
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
case LZMA_OK:
|
case LZMA_OK:
|
||||||
|
|||||||
@@ -33,7 +33,6 @@
|
|||||||
|
|
||||||
#include "zipint.h"
|
#include "zipint.h"
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <zstd.h>
|
#include <zstd.h>
|
||||||
#include <zstd_errors.h>
|
#include <zstd_errors.h>
|
||||||
@@ -56,21 +55,20 @@ maximum_compressed_size(zip_uint64_t uncompressed_size) {
|
|||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
allocate(bool compress, int compression_flags, zip_error_t *error) {
|
allocate(bool compress, zip_uint32_t compression_flags, zip_error_t *error) {
|
||||||
struct ctx *ctx;
|
struct ctx *ctx;
|
||||||
|
|
||||||
/* 0: let zstd choose */
|
|
||||||
if (compression_flags < ZSTD_minCLevel() || compression_flags > ZSTD_maxCLevel()) {
|
|
||||||
compression_flags = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ctx = (struct ctx *)malloc(sizeof(*ctx))) == NULL) {
|
if ((ctx = (struct ctx *)malloc(sizeof(*ctx))) == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx->compression_flags = (zip_int32_t)compression_flags;
|
||||||
|
if (ctx->compression_flags < ZSTD_minCLevel() || ctx->compression_flags > ZSTD_maxCLevel()) {
|
||||||
|
ctx->compression_flags = 0; /* let zstd choose */
|
||||||
|
}
|
||||||
|
|
||||||
ctx->error = error;
|
ctx->error = error;
|
||||||
ctx->compress = compress;
|
ctx->compress = compress;
|
||||||
ctx->compression_flags = compression_flags;
|
|
||||||
ctx->end_of_input = false;
|
ctx->end_of_input = false;
|
||||||
|
|
||||||
ctx->zdstream = NULL;
|
ctx->zdstream = NULL;
|
||||||
@@ -87,13 +85,15 @@ allocate(bool compress, int compression_flags, zip_error_t *error) {
|
|||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
compress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) {
|
compress_allocate(zip_uint16_t method, zip_uint32_t compression_flags, zip_error_t *error) {
|
||||||
|
(void)method;
|
||||||
return allocate(true, compression_flags, error);
|
return allocate(true, compression_flags, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
decompress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) {
|
decompress_allocate(zip_uint16_t method, zip_uint32_t compression_flags, zip_error_t *error) {
|
||||||
|
(void)method;
|
||||||
return allocate(false, compression_flags, error);
|
return allocate(false, compression_flags, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ deallocate(void *ud) {
|
|||||||
|
|
||||||
static zip_uint16_t
|
static zip_uint16_t
|
||||||
general_purpose_bit_flags(void *ud) {
|
general_purpose_bit_flags(void *ud) {
|
||||||
/* struct ctx *ctx = (struct ctx *)ud; */
|
(void)ud;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,6 +139,10 @@ map_error(size_t ret) {
|
|||||||
static bool
|
static bool
|
||||||
start(void *ud, zip_stat_t *st, zip_file_attributes_t *attributes) {
|
start(void *ud, zip_stat_t *st, zip_file_attributes_t *attributes) {
|
||||||
struct ctx *ctx = (struct ctx *)ud;
|
struct ctx *ctx = (struct ctx *)ud;
|
||||||
|
|
||||||
|
(void)st;
|
||||||
|
(void)attributes;
|
||||||
|
|
||||||
ctx->in.src = NULL;
|
ctx->in.src = NULL;
|
||||||
ctx->in.pos = 0;
|
ctx->in.pos = 0;
|
||||||
ctx->in.size = 0;
|
ctx->in.size = 0;
|
||||||
|
|||||||
@@ -132,13 +132,20 @@ _zip_buffer_left(zip_buffer_t *buffer) {
|
|||||||
|
|
||||||
zip_uint64_t
|
zip_uint64_t
|
||||||
_zip_buffer_read(zip_buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length) {
|
_zip_buffer_read(zip_buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length) {
|
||||||
|
zip_uint64_t copied;
|
||||||
|
|
||||||
if (_zip_buffer_left(buffer) < length) {
|
if (_zip_buffer_left(buffer) < length) {
|
||||||
length = _zip_buffer_left(buffer);
|
length = _zip_buffer_left(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(data, _zip_buffer_get(buffer, length), length);
|
copied = 0;
|
||||||
|
while (copied < length) {
|
||||||
|
size_t n = ZIP_MIN(length - copied, SIZE_MAX);
|
||||||
|
(void)memcpy_s(data + copied, n, _zip_buffer_get(buffer, n), n);
|
||||||
|
copied += n;
|
||||||
|
}
|
||||||
|
|
||||||
return length;
|
return copied;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -147,8 +154,14 @@ _zip_buffer_new(zip_uint8_t *data, zip_uint64_t size) {
|
|||||||
bool free_data = (data == NULL);
|
bool free_data = (data == NULL);
|
||||||
zip_buffer_t *buffer;
|
zip_buffer_t *buffer;
|
||||||
|
|
||||||
|
#if ZIP_UINT64_MAX > SIZE_MAX
|
||||||
|
if (size > SIZE_MAX) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (data == NULL) {
|
if (data == NULL) {
|
||||||
if ((data = (zip_uint8_t *)malloc(size)) == NULL) {
|
if ((data = (zip_uint8_t *)malloc((size_t)size)) == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -221,7 +234,7 @@ _zip_buffer_put(zip_buffer_t *buffer, const void *src, size_t length) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(dst, src, length);
|
(void)memcpy_s(dst, length, src, length);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
static int add_data(zip_t *, zip_source_t *, zip_dirent_t *, zip_uint32_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_data(zip_t *, zip_uint64_t);
|
||||||
static int copy_source(zip_t *, zip_source_t *, zip_int64_t);
|
static int copy_source(zip_t *, zip_source_t *, zip_int64_t);
|
||||||
|
static int torrentzip_compare_names(const void *a, const void *b);
|
||||||
static int write_cdir(zip_t *, const zip_filelist_t *, zip_uint64_t);
|
static int write_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);
|
static int write_data_descriptor(zip_t *za, const zip_dirent_t *dirent, int is_zip64);
|
||||||
|
|
||||||
@@ -61,12 +62,12 @@ zip_close(zip_t *za) {
|
|||||||
|
|
||||||
changed = _zip_changed(za, &survivors);
|
changed = _zip_changed(za, &survivors);
|
||||||
|
|
||||||
/* don't create zip files with no entries */
|
if (survivors == 0 && !(za->ch_flags & ZIP_AFL_CREATE_OR_KEEP_FILE_FOR_EMPTY_ARCHIVE)) {
|
||||||
if (survivors == 0) {
|
/* don't create zip files with no entries */
|
||||||
if ((za->open_flags & ZIP_TRUNCATE) || changed) {
|
if ((za->open_flags & ZIP_TRUNCATE) || changed) {
|
||||||
if (zip_source_remove(za->src) < 0) {
|
if (zip_source_remove(za->src) < 0) {
|
||||||
if (!((zip_error_code_zip(zip_source_error(za->src)) == ZIP_ER_REMOVE) && (zip_error_code_system(zip_source_error(za->src)) == ENOENT))) {
|
if (!((zip_error_code_zip(zip_source_error(za->src)) == ZIP_ER_REMOVE) && (zip_error_code_system(zip_source_error(za->src)) == ENOENT))) {
|
||||||
_zip_error_set_from_source(&za->error, za->src);
|
zip_error_set_from_source(&za->error, za->src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,7 +76,8 @@ zip_close(zip_t *za) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!changed) {
|
/* Always write empty archive if we are told to keep it, otherwise it wouldn't be created if the file doesn't already exist. */
|
||||||
|
if (!changed && survivors > 0) {
|
||||||
zip_discard(za);
|
zip_discard(za);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -105,6 +107,7 @@ zip_close(zip_t *za) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
filelist[j].idx = i;
|
filelist[j].idx = i;
|
||||||
|
filelist[j].name = zip_get_name(za, i, 0);
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
if (j < survivors) {
|
if (j < survivors) {
|
||||||
@@ -113,7 +116,11 @@ zip_close(zip_t *za) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((zip_source_supports(za->src) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE_CLONING)) == 0) {
|
if (ZIP_WANT_TORRENTZIP(za)) {
|
||||||
|
qsort(filelist, (size_t)survivors, sizeof(filelist[0]), torrentzip_compare_names);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ZIP_WANT_TORRENTZIP(za) || (zip_source_supports(za->src) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE_CLONING)) == 0) {
|
||||||
unchanged_offset = 0;
|
unchanged_offset = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -146,7 +153,7 @@ zip_close(zip_t *za) {
|
|||||||
}
|
}
|
||||||
if (unchanged_offset == 0) {
|
if (unchanged_offset == 0) {
|
||||||
if (zip_source_begin_write(za->src) < 0) {
|
if (zip_source_begin_write(za->src) < 0) {
|
||||||
_zip_error_set_from_source(&za->error, za->src);
|
zip_error_set_from_source(&za->error, za->src);
|
||||||
free(filelist);
|
free(filelist);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -178,7 +185,7 @@ zip_close(zip_t *za) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_data = (ZIP_ENTRY_DATA_CHANGED(entry) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_COMP_METHOD) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_ENCRYPTION_METHOD));
|
new_data = (ZIP_ENTRY_DATA_CHANGED(entry) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_COMP_METHOD) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_ENCRYPTION_METHOD)) || (ZIP_WANT_TORRENTZIP(za) && !ZIP_IS_TORRENTZIP(za));
|
||||||
|
|
||||||
/* create new local directory entry */
|
/* create new local directory entry */
|
||||||
if (entry->changes == NULL) {
|
if (entry->changes == NULL) {
|
||||||
@@ -195,8 +202,12 @@ zip_close(zip_t *za) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ZIP_WANT_TORRENTZIP(za)) {
|
||||||
|
zip_dirent_torrentzip_normalize(entry->changes);
|
||||||
|
}
|
||||||
|
|
||||||
if ((off = zip_source_tell_write(za->src)) < 0) {
|
if ((off = zip_source_tell_write(za->src)) < 0) {
|
||||||
_zip_error_set_from_source(&za->error, za->src);
|
zip_error_set_from_source(&za->error, za->src);
|
||||||
error = 1;
|
error = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -207,7 +218,7 @@ zip_close(zip_t *za) {
|
|||||||
|
|
||||||
zs = NULL;
|
zs = NULL;
|
||||||
if (!ZIP_ENTRY_DATA_CHANGED(entry)) {
|
if (!ZIP_ENTRY_DATA_CHANGED(entry)) {
|
||||||
if ((zs = _zip_source_zip_new(za, i, ZIP_FL_UNCHANGED, 0, 0, NULL, &za->error)) == NULL) {
|
if ((zs = zip_source_zip_file_create(za, i, ZIP_FL_UNCHANGED, 0, -1, NULL, &za->error)) == NULL) {
|
||||||
error = 1;
|
error = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -240,7 +251,7 @@ zip_close(zip_t *za) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) {
|
if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) {
|
||||||
_zip_error_set_from_source(&za->error, za->src);
|
zip_error_set_from_source(&za->error, za->src);
|
||||||
error = 1;
|
error = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -267,7 +278,7 @@ zip_close(zip_t *za) {
|
|||||||
|
|
||||||
if (!error) {
|
if (!error) {
|
||||||
if (zip_source_commit_write(za->src) != 0) {
|
if (zip_source_commit_write(za->src) != 0) {
|
||||||
_zip_error_set_from_source(&za->error, za->src);
|
zip_error_set_from_source(&za->error, za->src);
|
||||||
error = 1;
|
error = 1;
|
||||||
}
|
}
|
||||||
_zip_progress_end(za->progress);
|
_zip_progress_end(za->progress);
|
||||||
@@ -296,7 +307,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
|
|||||||
bool needs_recompress, needs_decompress, needs_crc, needs_compress, needs_reencrypt, needs_decrypt, needs_encrypt;
|
bool needs_recompress, needs_decompress, needs_crc, needs_compress, needs_reencrypt, needs_decrypt, needs_encrypt;
|
||||||
|
|
||||||
if (zip_source_stat(src, &st) < 0) {
|
if (zip_source_stat(src, &st) < 0) {
|
||||||
_zip_error_set_from_source(&za->error, src);
|
zip_error_set_from_source(&za->error, src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,6 +335,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
|
|||||||
flags = ZIP_EF_LOCAL;
|
flags = ZIP_EF_LOCAL;
|
||||||
|
|
||||||
if ((st.valid & ZIP_STAT_SIZE) == 0) {
|
if ((st.valid & ZIP_STAT_SIZE) == 0) {
|
||||||
|
/* TODO: not valid for torrentzip */
|
||||||
flags |= ZIP_FL_FORCE_ZIP64;
|
flags |= ZIP_FL_FORCE_ZIP64;
|
||||||
data_length = -1;
|
data_length = -1;
|
||||||
}
|
}
|
||||||
@@ -350,6 +362,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (max_compressed_size > 0xffffffffu) {
|
if (max_compressed_size > 0xffffffffu) {
|
||||||
|
/* TODO: not valid for torrentzip */
|
||||||
flags |= ZIP_FL_FORCE_ZIP64;
|
flags |= ZIP_FL_FORCE_ZIP64;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -360,7 +373,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((offstart = zip_source_tell_write(za->src)) < 0) {
|
if ((offstart = zip_source_tell_write(za->src)) < 0) {
|
||||||
_zip_error_set_from_source(&za->error, za->src);
|
zip_error_set_from_source(&za->error, za->src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,7 +383,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
needs_recompress = st.comp_method != ZIP_CM_ACTUAL(de->comp_method);
|
needs_recompress = ZIP_WANT_TORRENTZIP(za) || st.comp_method != ZIP_CM_ACTUAL(de->comp_method);
|
||||||
needs_decompress = needs_recompress && (st.comp_method != ZIP_CM_STORE);
|
needs_decompress = needs_recompress && (st.comp_method != ZIP_CM_STORE);
|
||||||
/* in these cases we can compute the CRC ourselves, so we do */
|
/* in these cases we can compute the CRC ourselves, so we do */
|
||||||
needs_crc = (st.comp_method == ZIP_CM_STORE) || needs_decompress;
|
needs_crc = (st.comp_method == ZIP_CM_STORE) || needs_decompress;
|
||||||
@@ -397,7 +410,6 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
zip_source_free(src_final);
|
|
||||||
src_final = src_tmp;
|
src_final = src_tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -407,7 +419,6 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
zip_source_free(src_final);
|
|
||||||
src_final = src_tmp;
|
src_final = src_tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -417,7 +428,6 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
zip_source_free(src_final);
|
|
||||||
src_final = src_tmp;
|
src_final = src_tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,7 +437,6 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
zip_source_free(src_final);
|
|
||||||
src_final = src_tmp;
|
src_final = src_tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -458,11 +467,10 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
|
|||||||
zip_stat_init(&st_mtime);
|
zip_stat_init(&st_mtime);
|
||||||
st_mtime.valid = ZIP_STAT_MTIME;
|
st_mtime.valid = ZIP_STAT_MTIME;
|
||||||
st_mtime.mtime = de->last_mod;
|
st_mtime.mtime = de->last_mod;
|
||||||
if ((src_tmp = _zip_source_window_new(src_final, 0, -1, &st_mtime, NULL, NULL, 0, &za->error)) == NULL) {
|
if ((src_tmp = _zip_source_window_new(src_final, 0, -1, &st_mtime, 0, NULL, NULL, 0, true, &za->error)) == NULL) {
|
||||||
zip_source_free(src_final);
|
zip_source_free(src_final);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
zip_source_free(src_final);
|
|
||||||
src_final = src_tmp;
|
src_final = src_tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -473,25 +481,24 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
zip_source_free(src_final);
|
|
||||||
src_final = src_tmp;
|
src_final = src_tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ((offdata = zip_source_tell_write(za->src)) < 0) {
|
if ((offdata = zip_source_tell_write(za->src)) < 0) {
|
||||||
_zip_error_set_from_source(&za->error, za->src);
|
zip_error_set_from_source(&za->error, za->src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = copy_source(za, src_final, data_length);
|
ret = copy_source(za, src_final, data_length);
|
||||||
|
|
||||||
if (zip_source_stat(src_final, &st) < 0) {
|
if (zip_source_stat(src_final, &st) < 0) {
|
||||||
_zip_error_set_from_source(&za->error, src_final);
|
zip_error_set_from_source(&za->error, src_final);
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zip_source_get_file_attributes(src_final, &attributes) != 0) {
|
if (zip_source_get_file_attributes(src_final, &attributes) != 0) {
|
||||||
_zip_error_set_from_source(&za->error, src_final);
|
zip_error_set_from_source(&za->error, src_final);
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -502,12 +509,12 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((offend = zip_source_tell_write(za->src)) < 0) {
|
if ((offend = zip_source_tell_write(za->src)) < 0) {
|
||||||
_zip_error_set_from_source(&za->error, za->src);
|
zip_error_set_from_source(&za->error, za->src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zip_source_seek_write(za->src, offstart, SEEK_SET) < 0) {
|
if (zip_source_seek_write(za->src, offstart, SEEK_SET) < 0) {
|
||||||
_zip_error_set_from_source(&za->error, za->src);
|
zip_error_set_from_source(&za->error, za->src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -528,6 +535,10 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
|
|||||||
de->comp_size = (zip_uint64_t)(offend - offdata);
|
de->comp_size = (zip_uint64_t)(offend - offdata);
|
||||||
_zip_dirent_apply_attributes(de, &attributes, (flags & ZIP_FL_FORCE_ZIP64) != 0, changed);
|
_zip_dirent_apply_attributes(de, &attributes, (flags & ZIP_FL_FORCE_ZIP64) != 0, changed);
|
||||||
|
|
||||||
|
if (ZIP_WANT_TORRENTZIP(za)) {
|
||||||
|
zip_dirent_torrentzip_normalize(de);
|
||||||
|
}
|
||||||
|
|
||||||
if ((ret = _zip_dirent_write(za, de, flags)) < 0)
|
if ((ret = _zip_dirent_write(za, de, flags)) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@@ -538,7 +549,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (zip_source_seek_write(za->src, offend, SEEK_SET) < 0) {
|
if (zip_source_seek_write(za->src, offend, SEEK_SET) < 0) {
|
||||||
_zip_error_set_from_source(&za->error, za->src);
|
zip_error_set_from_source(&za->error, za->src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -555,7 +566,6 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
|
|||||||
static int
|
static int
|
||||||
copy_data(zip_t *za, zip_uint64_t len) {
|
copy_data(zip_t *za, zip_uint64_t len) {
|
||||||
DEFINE_BYTE_ARRAY(buf, BUFSIZE);
|
DEFINE_BYTE_ARRAY(buf, BUFSIZE);
|
||||||
size_t n;
|
|
||||||
double total = (double)len;
|
double total = (double)len;
|
||||||
|
|
||||||
if (!byte_array_init(buf, BUFSIZE)) {
|
if (!byte_array_init(buf, BUFSIZE)) {
|
||||||
@@ -564,7 +574,8 @@ copy_data(zip_t *za, zip_uint64_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
n = len > BUFSIZE ? BUFSIZE : len;
|
zip_uint64_t n = ZIP_MIN(len, BUFSIZE);
|
||||||
|
|
||||||
if (_zip_read(za->src, buf, n, &za->error) < 0) {
|
if (_zip_read(za->src, buf, n, &za->error) < 0) {
|
||||||
byte_array_fini(buf);
|
byte_array_fini(buf);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -595,7 +606,7 @@ copy_source(zip_t *za, zip_source_t *src, zip_int64_t data_length) {
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (zip_source_open(src) < 0) {
|
if (zip_source_open(src) < 0) {
|
||||||
_zip_error_set_from_source(&za->error, src);
|
zip_error_set_from_source(&za->error, src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -622,7 +633,7 @@ copy_source(zip_t *za, zip_source_t *src, zip_int64_t data_length) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
_zip_error_set_from_source(&za->error, src);
|
zip_error_set_from_source(&za->error, src);
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -659,7 +670,7 @@ _zip_changed(const zip_t *za, zip_uint64_t *survivorsp) {
|
|||||||
changed = 0;
|
changed = 0;
|
||||||
survivors = 0;
|
survivors = 0;
|
||||||
|
|
||||||
if (za->comment_changed || za->ch_flags != za->flags) {
|
if (za->comment_changed || (ZIP_WANT_TORRENTZIP(za) && !ZIP_IS_TORRENTZIP(za))) {
|
||||||
changed = 1;
|
changed = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -712,3 +723,18 @@ write_data_descriptor(zip_t *za, const zip_dirent_t *de, int is_zip64) {
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int torrentzip_compare_names(const void *a, const void *b) {
|
||||||
|
const char *aname = ((const zip_filelist_t *)a)->name;
|
||||||
|
const char *bname = ((const zip_filelist_t *)b)->name;
|
||||||
|
|
||||||
|
if (aname == NULL) {
|
||||||
|
return (bname != NULL) * -1;
|
||||||
|
}
|
||||||
|
else if (bname == NULL) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return strcasecmp(aname, bname);
|
||||||
|
}
|
||||||
@@ -117,6 +117,8 @@ _zip_crypto_pbkdf2(const zip_uint8_t *key, zip_uint64_t key_length, const zip_ui
|
|||||||
mbedtls_md_context_t sha1_ctx;
|
mbedtls_md_context_t sha1_ctx;
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
|
|
||||||
|
#if MBEDTLS_VERSION_NUMBER < 0x03030000
|
||||||
|
|
||||||
mbedtls_md_init(&sha1_ctx);
|
mbedtls_md_init(&sha1_ctx);
|
||||||
|
|
||||||
if (mbedtls_md_setup(&sha1_ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), 1) != 0) {
|
if (mbedtls_md_setup(&sha1_ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), 1) != 0) {
|
||||||
@@ -128,6 +130,13 @@ _zip_crypto_pbkdf2(const zip_uint8_t *key, zip_uint64_t key_length, const zip_ui
|
|||||||
}
|
}
|
||||||
|
|
||||||
mbedtls_md_free(&sha1_ctx);
|
mbedtls_md_free(&sha1_ctx);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
ok = mbedtls_pkcs5_pbkdf2_hmac_ext(MBEDTLS_MD_SHA1, (const unsigned char *)key, (size_t)key_length, (const unsigned char *)salt, (size_t)salt_length, (unsigned int)iterations, (uint32_t)output_length, (unsigned char *)output) == 0;
|
||||||
|
|
||||||
|
#endif // !defined(MBEDTLS_DEPRECATED_REMOVED) || MBEDTLS_VERSION_NUMBER < 0x03030000
|
||||||
|
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,11 +40,28 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x1010000fL || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x02070000fL)
|
#ifdef USE_OPENSSL_3_API
|
||||||
#define USE_OPENSSL_1_0_API
|
static _zip_crypto_hmac_t* hmac_new() {
|
||||||
|
_zip_crypto_hmac_t *hmac = (_zip_crypto_hmac_t*)malloc(sizeof(*hmac));
|
||||||
|
if (hmac != NULL) {
|
||||||
|
hmac->mac = NULL;
|
||||||
|
hmac->ctx = NULL;
|
||||||
|
}
|
||||||
|
return hmac;
|
||||||
|
}
|
||||||
|
static void hmac_free(_zip_crypto_hmac_t* hmac) {
|
||||||
|
if (hmac != NULL) {
|
||||||
|
if (hmac->ctx != NULL) {
|
||||||
|
EVP_MAC_CTX_free(hmac->ctx);
|
||||||
|
}
|
||||||
|
if (hmac->mac != NULL) {
|
||||||
|
EVP_MAC_free(hmac->mac);
|
||||||
|
}
|
||||||
|
free(hmac);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
_zip_crypto_aes_t *
|
_zip_crypto_aes_t *
|
||||||
_zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t *error) {
|
_zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t *error) {
|
||||||
_zip_crypto_aes_t *aes;
|
_zip_crypto_aes_t *aes;
|
||||||
@@ -126,13 +143,34 @@ _zip_crypto_hmac_new(const zip_uint8_t *secret, zip_uint64_t secret_length, zip_
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_OPENSSL_3_API
|
||||||
|
if ((hmac = hmac_new()) == NULL
|
||||||
|
|| (hmac->mac = EVP_MAC_fetch(NULL, "HMAC", "provider=default")) == NULL
|
||||||
|
|| (hmac->ctx = EVP_MAC_CTX_new(hmac->mac)) == NULL) {
|
||||||
|
hmac_free(hmac);
|
||||||
|
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
OSSL_PARAM params[2];
|
||||||
|
params[0] = OSSL_PARAM_construct_utf8_string("digest", "SHA1", 0);
|
||||||
|
params[1] = OSSL_PARAM_construct_end();
|
||||||
|
|
||||||
|
if (!EVP_MAC_init(hmac->ctx, (const unsigned char *)secret, secret_length, params)) {
|
||||||
|
zip_error_set(error, ZIP_ER_INTERNAL, 0);
|
||||||
|
hmac_free(hmac);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
#ifdef USE_OPENSSL_1_0_API
|
#ifdef USE_OPENSSL_1_0_API
|
||||||
if ((hmac = (_zip_crypto_hmac_t *)malloc(sizeof(*hmac))) == NULL) {
|
if ((hmac = (_zip_crypto_hmac_t *)malloc(sizeof(*hmac))) == NULL) {
|
||||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
HMAC_CTX_init(hmac);
|
HMAC_CTX_init(hmac);
|
||||||
#else
|
#else
|
||||||
if ((hmac = HMAC_CTX_new()) == NULL) {
|
if ((hmac = HMAC_CTX_new()) == NULL) {
|
||||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||||
@@ -149,6 +187,7 @@ _zip_crypto_hmac_new(const zip_uint8_t *secret, zip_uint64_t secret_length, zip_
|
|||||||
#endif
|
#endif
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return hmac;
|
return hmac;
|
||||||
}
|
}
|
||||||
@@ -160,7 +199,9 @@ _zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_OPENSSL_1_0_API
|
#if defined(USE_OPENSSL_3_API)
|
||||||
|
hmac_free(hmac);
|
||||||
|
#elif defined(USE_OPENSSL_1_0_API)
|
||||||
HMAC_CTX_cleanup(hmac);
|
HMAC_CTX_cleanup(hmac);
|
||||||
_zip_crypto_clear(hmac, sizeof(*hmac));
|
_zip_crypto_clear(hmac, sizeof(*hmac));
|
||||||
free(hmac);
|
free(hmac);
|
||||||
@@ -172,9 +213,13 @@ _zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac) {
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
_zip_crypto_hmac_output(_zip_crypto_hmac_t *hmac, zip_uint8_t *data) {
|
_zip_crypto_hmac_output(_zip_crypto_hmac_t *hmac, zip_uint8_t *data) {
|
||||||
|
#ifdef USE_OPENSSL_3_API
|
||||||
|
size_t length;
|
||||||
|
return EVP_MAC_final(hmac->ctx, data, &length, ZIP_CRYPTO_SHA1_LENGTH) == 1 && length == ZIP_CRYPTO_SHA1_LENGTH;
|
||||||
|
#else
|
||||||
unsigned int length;
|
unsigned int length;
|
||||||
|
|
||||||
return HMAC_Final(hmac, data, &length) == 1;
|
return HMAC_Final(hmac, data, &length) == 1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -39,14 +39,31 @@
|
|||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/hmac.h>
|
#include <openssl/hmac.h>
|
||||||
|
|
||||||
|
#if OPENSSL_VERSION_NUMBER < 0x1010000fL || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x02070000fL)
|
||||||
|
#define USE_OPENSSL_1_0_API
|
||||||
|
#elif OPENSSL_VERSION_NUMBER < 0x3000000fL
|
||||||
|
#define USE_OPENSSL_1_1_API
|
||||||
|
#else
|
||||||
|
#define USE_OPENSSL_3_API
|
||||||
|
#endif
|
||||||
|
|
||||||
#define _zip_crypto_aes_t EVP_CIPHER_CTX
|
#define _zip_crypto_aes_t EVP_CIPHER_CTX
|
||||||
|
#ifdef USE_OPENSSL_3_API
|
||||||
|
struct _zip_crypto_hmac_t {
|
||||||
|
EVP_MAC *mac;
|
||||||
|
EVP_MAC_CTX *ctx;
|
||||||
|
};
|
||||||
|
typedef struct _zip_crypto_hmac_t _zip_crypto_hmac_t;
|
||||||
|
#define _zip_crypto_hmac(hmac, data, length) (EVP_MAC_update((hmac->ctx), (data), (length)) == 1)
|
||||||
|
#else
|
||||||
#define _zip_crypto_hmac_t HMAC_CTX
|
#define _zip_crypto_hmac_t HMAC_CTX
|
||||||
|
#define _zip_crypto_hmac(hmac, data, length) (HMAC_Update((hmac), (data), (length)) == 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
void _zip_crypto_aes_free(_zip_crypto_aes_t *aes);
|
void _zip_crypto_aes_free(_zip_crypto_aes_t *aes);
|
||||||
bool _zip_crypto_aes_encrypt_block(_zip_crypto_aes_t *aes, const zip_uint8_t *in, zip_uint8_t *out);
|
bool _zip_crypto_aes_encrypt_block(_zip_crypto_aes_t *aes, const zip_uint8_t *in, zip_uint8_t *out);
|
||||||
_zip_crypto_aes_t *_zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t *error);
|
_zip_crypto_aes_t *_zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t *error);
|
||||||
|
|
||||||
#define _zip_crypto_hmac(hmac, data, length) (HMAC_Update((hmac), (data), (length)) == 1)
|
|
||||||
void _zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac);
|
void _zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac);
|
||||||
_zip_crypto_hmac_t *_zip_crypto_hmac_new(const zip_uint8_t *secret, zip_uint64_t secret_length, zip_error_t *error);
|
_zip_crypto_hmac_t *_zip_crypto_hmac_new(const zip_uint8_t *secret, zip_uint64_t secret_length, zip_error_t *error);
|
||||||
bool _zip_crypto_hmac_output(_zip_crypto_hmac_t *hmac, zip_uint8_t *data);
|
bool _zip_crypto_hmac_output(_zip_crypto_hmac_t *hmac, zip_uint8_t *data);
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ pbkdf2(PUCHAR pbPassword, ULONG cbPassword, PUCHAR pbSalt, ULONG cbSalt, DWORD c
|
|||||||
for (j = 0; j < cIterations; j++) {
|
for (j = 0; j < cIterations; j++) {
|
||||||
if (j == 0) {
|
if (j == 0) {
|
||||||
/* construct first input for PRF */
|
/* construct first input for PRF */
|
||||||
memcpy(U, pbSalt, cbSalt);
|
(void)memcpy_s(U, cbSalt, pbSalt, cbSalt);
|
||||||
U[cbSalt] = (BYTE)((i & 0xFF000000) >> 24);
|
U[cbSalt] = (BYTE)((i & 0xFF000000) >> 24);
|
||||||
U[cbSalt + 1] = (BYTE)((i & 0x00FF0000) >> 16);
|
U[cbSalt + 1] = (BYTE)((i & 0x00FF0000) >> 16);
|
||||||
U[cbSalt + 2] = (BYTE)((i & 0x0000FF00) >> 8);
|
U[cbSalt + 2] = (BYTE)((i & 0x0000FF00) >> 8);
|
||||||
@@ -262,7 +262,7 @@ pbkdf2(PUCHAR pbPassword, ULONG cbPassword, PUCHAR pbSalt, ULONG cbSalt, DWORD c
|
|||||||
dwULen = cbSalt + 4;
|
dwULen = cbSalt + 4;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
memcpy(U, V, DIGEST_SIZE);
|
(void)memcpy_s(U, DIGEST_SIZE, V, DIGEST_SIZE);
|
||||||
dwULen = DIGEST_SIZE;
|
dwULen = DIGEST_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,11 +274,11 @@ pbkdf2(PUCHAR pbPassword, ULONG cbPassword, PUCHAR pbSalt, ULONG cbSalt, DWORD c
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (i != l) {
|
if (i != l) {
|
||||||
memcpy(&pbDerivedKey[(i - 1) * DIGEST_SIZE], Ti, DIGEST_SIZE);
|
(void)memcpy_s(&pbDerivedKey[(i - 1) * DIGEST_SIZE], cbDerivedKey - (i - 1) * DIGEST_SIZE, Ti, DIGEST_SIZE);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Take only the first r bytes */
|
/* Take only the first r bytes */
|
||||||
memcpy(&pbDerivedKey[(i - 1) * DIGEST_SIZE], Ti, r);
|
(void)memcpy_s(&pbDerivedKey[(i - 1) * DIGEST_SIZE], cbDerivedKey - (i - 1) * DIGEST_SIZE, Ti, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,11 +61,11 @@ zip_dir_add(zip_t *za, const char *name, zip_flags_t flags) {
|
|||||||
len = strlen(name);
|
len = strlen(name);
|
||||||
|
|
||||||
if (name[len - 1] != '/') {
|
if (name[len - 1] != '/') {
|
||||||
if ((s = (char *)malloc(len + 2)) == NULL) {
|
if (len > SIZE_MAX - 2 || (s = (char *)malloc(len + 2)) == NULL) {
|
||||||
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
strcpy(s, name);
|
(void)strncpy_s(s, len + 2, name, len);
|
||||||
s[len] = '/';
|
s[len] = '/';
|
||||||
s[len + 1] = '\0';
|
s[len + 1] = '\0';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
#include "zipint.h"
|
#include "zipint.h"
|
||||||
|
|
||||||
@@ -127,15 +128,21 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor
|
|||||||
zip_uint64_t i;
|
zip_uint64_t i;
|
||||||
bool is_zip64;
|
bool is_zip64;
|
||||||
int ret;
|
int ret;
|
||||||
|
zip_uint32_t cdir_crc;
|
||||||
|
|
||||||
if ((off = zip_source_tell_write(za->src)) < 0) {
|
if ((off = zip_source_tell_write(za->src)) < 0) {
|
||||||
_zip_error_set_from_source(&za->error, za->src);
|
zip_error_set_from_source(&za->error, za->src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
offset = (zip_uint64_t)off;
|
offset = (zip_uint64_t)off;
|
||||||
|
|
||||||
is_zip64 = false;
|
is_zip64 = false;
|
||||||
|
|
||||||
|
if (ZIP_WANT_TORRENTZIP(za)) {
|
||||||
|
cdir_crc = (zip_uint32_t)crc32(0, NULL, 0);
|
||||||
|
za->write_crc = &cdir_crc;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < survivors; i++) {
|
for (i = 0; i < survivors; i++) {
|
||||||
zip_entry_t *entry = za->entry + filelist[i].idx;
|
zip_entry_t *entry = za->entry + filelist[i].idx;
|
||||||
|
|
||||||
@@ -145,15 +152,17 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor
|
|||||||
is_zip64 = true;
|
is_zip64 = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
za->write_crc = NULL;
|
||||||
|
|
||||||
if ((off = zip_source_tell_write(za->src)) < 0) {
|
if ((off = zip_source_tell_write(za->src)) < 0) {
|
||||||
_zip_error_set_from_source(&za->error, za->src);
|
zip_error_set_from_source(&za->error, za->src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
size = (zip_uint64_t)off - offset;
|
size = (zip_uint64_t)off - offset;
|
||||||
|
|
||||||
if (offset > ZIP_UINT32_MAX || survivors > ZIP_UINT16_MAX)
|
if (offset > ZIP_UINT32_MAX || survivors > ZIP_UINT16_MAX) {
|
||||||
is_zip64 = true;
|
is_zip64 = true;
|
||||||
|
}
|
||||||
|
|
||||||
if ((buffer = _zip_buffer_new(buf, sizeof(buf))) == NULL) {
|
if ((buffer = _zip_buffer_new(buf, sizeof(buf))) == NULL) {
|
||||||
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||||
@@ -186,7 +195,13 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor
|
|||||||
|
|
||||||
comment = za->comment_changed ? za->comment_changes : za->comment_orig;
|
comment = za->comment_changed ? za->comment_changes : za->comment_orig;
|
||||||
|
|
||||||
_zip_buffer_put_16(buffer, (zip_uint16_t)(comment ? comment->length : 0));
|
if (ZIP_WANT_TORRENTZIP(za)) {
|
||||||
|
_zip_buffer_put_16(buffer, TORRENTZIP_SIGNATURE_LENGTH + TORRENTZIP_CRC_LENGTH);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_zip_buffer_put_16(buffer, (zip_uint16_t)(comment ? comment->length : 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!_zip_buffer_ok(buffer)) {
|
if (!_zip_buffer_ok(buffer)) {
|
||||||
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
|
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
|
||||||
@@ -201,7 +216,15 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor
|
|||||||
|
|
||||||
_zip_buffer_free(buffer);
|
_zip_buffer_free(buffer);
|
||||||
|
|
||||||
if (comment) {
|
if (ZIP_WANT_TORRENTZIP(za)) {
|
||||||
|
char torrentzip_comment[TORRENTZIP_SIGNATURE_LENGTH + TORRENTZIP_CRC_LENGTH + 1];
|
||||||
|
snprintf(torrentzip_comment, sizeof(torrentzip_comment), TORRENTZIP_SIGNATURE "%08X", cdir_crc);
|
||||||
|
|
||||||
|
if (_zip_write(za, torrentzip_comment, strlen(torrentzip_comment)) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (comment != NULL) {
|
||||||
if (_zip_write(za, comment->raw, comment->length) < 0) {
|
if (_zip_write(za, comment->raw, comment->length) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -219,7 +242,7 @@ _zip_dirent_clone(const zip_dirent_t *sde) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (sde)
|
if (sde)
|
||||||
memcpy(tde, sde, sizeof(*sde));
|
(void)memcpy_s(tde, sizeof(*tde), sde, sizeof(*sde));
|
||||||
else
|
else
|
||||||
_zip_dirent_init(tde);
|
_zip_dirent_init(tde);
|
||||||
|
|
||||||
@@ -503,76 +526,18 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
|
|||||||
|
|
||||||
if (zde->uncomp_size == ZIP_UINT32_MAX || zde->comp_size == ZIP_UINT32_MAX || zde->offset == ZIP_UINT32_MAX) {
|
if (zde->uncomp_size == ZIP_UINT32_MAX || zde->comp_size == ZIP_UINT32_MAX || zde->offset == ZIP_UINT32_MAX) {
|
||||||
zip_uint16_t got_len;
|
zip_uint16_t got_len;
|
||||||
zip_buffer_t *ef_buffer;
|
|
||||||
const zip_uint8_t *ef = _zip_ef_get_by_id(zde->extra_fields, &got_len, ZIP_EF_ZIP64, 0, local ? ZIP_EF_LOCAL : ZIP_EF_CENTRAL, error);
|
const zip_uint8_t *ef = _zip_ef_get_by_id(zde->extra_fields, &got_len, ZIP_EF_ZIP64, 0, local ? ZIP_EF_LOCAL : ZIP_EF_CENTRAL, error);
|
||||||
/* TODO: if got_len == 0 && !ZIP64_EOCD: no error, 0xffffffff is valid value */
|
if (ef != NULL) {
|
||||||
if (ef == NULL) {
|
if (!zip_dirent_process_ef_zip64(zde, ef, got_len, local, error)) {
|
||||||
if (!from_buffer) {
|
|
||||||
_zip_buffer_free(buffer);
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ef_buffer = _zip_buffer_new((zip_uint8_t *)ef, got_len)) == NULL) {
|
|
||||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
|
||||||
if (!from_buffer) {
|
|
||||||
_zip_buffer_free(buffer);
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (zde->uncomp_size == ZIP_UINT32_MAX) {
|
|
||||||
zde->uncomp_size = _zip_buffer_get_64(ef_buffer);
|
|
||||||
}
|
|
||||||
else if (local) {
|
|
||||||
/* From appnote.txt: This entry in the Local header MUST
|
|
||||||
include BOTH original and compressed file size fields. */
|
|
||||||
(void)_zip_buffer_skip(ef_buffer, 8); /* error is caught by _zip_buffer_eof() call */
|
|
||||||
}
|
|
||||||
if (zde->comp_size == ZIP_UINT32_MAX) {
|
|
||||||
zde->comp_size = _zip_buffer_get_64(ef_buffer);
|
|
||||||
}
|
|
||||||
if (!local) {
|
|
||||||
if (zde->offset == ZIP_UINT32_MAX) {
|
|
||||||
zde->offset = _zip_buffer_get_64(ef_buffer);
|
|
||||||
}
|
|
||||||
if (zde->disk_number == ZIP_UINT16_MAX) {
|
|
||||||
zde->disk_number = _zip_buffer_get_32(ef_buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_zip_buffer_eof(ef_buffer)) {
|
|
||||||
/* accept additional fields if values match */
|
|
||||||
bool ok = true;
|
|
||||||
switch (got_len) {
|
|
||||||
case 28:
|
|
||||||
_zip_buffer_set_offset(ef_buffer, 24);
|
|
||||||
if (zde->disk_number != _zip_buffer_get_32(ef_buffer)) {
|
|
||||||
ok = false;
|
|
||||||
}
|
|
||||||
/* fallthrough */
|
|
||||||
case 24:
|
|
||||||
_zip_buffer_set_offset(ef_buffer, 0);
|
|
||||||
if ((zde->uncomp_size != _zip_buffer_get_64(ef_buffer)) || (zde->comp_size != _zip_buffer_get_64(ef_buffer)) || (zde->offset != _zip_buffer_get_64(ef_buffer))) {
|
|
||||||
ok = false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
ok = false;
|
|
||||||
}
|
|
||||||
if (!ok) {
|
|
||||||
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_INVALID_ZIP64_EF);
|
|
||||||
_zip_buffer_free(ef_buffer);
|
|
||||||
if (!from_buffer) {
|
if (!from_buffer) {
|
||||||
_zip_buffer_free(buffer);
|
_zip_buffer_free(buffer);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_zip_buffer_free(ef_buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!_zip_buffer_ok(buffer)) {
|
if (!_zip_buffer_ok(buffer)) {
|
||||||
zip_error_set(error, ZIP_ER_INTERNAL, 0);
|
zip_error_set(error, ZIP_ER_INTERNAL, 0);
|
||||||
if (!from_buffer) {
|
if (!from_buffer) {
|
||||||
@@ -599,6 +564,65 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
|
|||||||
return (zip_int64_t)size + (zip_int64_t)variable_size;
|
return (zip_int64_t)size + (zip_int64_t)variable_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool zip_dirent_process_ef_zip64(zip_dirent_t* zde, const zip_uint8_t* ef, zip_uint64_t got_len, bool local, zip_error_t* error) {
|
||||||
|
zip_buffer_t *ef_buffer;
|
||||||
|
|
||||||
|
if ((ef_buffer = _zip_buffer_new((zip_uint8_t *)ef, got_len)) == NULL) {
|
||||||
|
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zde->uncomp_size == ZIP_UINT32_MAX) {
|
||||||
|
zde->uncomp_size = _zip_buffer_get_64(ef_buffer);
|
||||||
|
}
|
||||||
|
else if (local) {
|
||||||
|
/* From appnote.txt: This entry in the Local header MUST
|
||||||
|
include BOTH original and compressed file size fields. */
|
||||||
|
(void)_zip_buffer_skip(ef_buffer, 8); /* error is caught by _zip_buffer_eof() call */
|
||||||
|
}
|
||||||
|
if (zde->comp_size == ZIP_UINT32_MAX) {
|
||||||
|
zde->comp_size = _zip_buffer_get_64(ef_buffer);
|
||||||
|
}
|
||||||
|
if (!local) {
|
||||||
|
if (zde->offset == ZIP_UINT32_MAX) {
|
||||||
|
zde->offset = _zip_buffer_get_64(ef_buffer);
|
||||||
|
}
|
||||||
|
if (zde->disk_number == ZIP_UINT16_MAX) {
|
||||||
|
zde->disk_number = _zip_buffer_get_32(ef_buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_zip_buffer_eof(ef_buffer)) {
|
||||||
|
/* accept additional fields if values match */
|
||||||
|
bool ok = true;
|
||||||
|
switch (got_len) {
|
||||||
|
case 28:
|
||||||
|
_zip_buffer_set_offset(ef_buffer, 24);
|
||||||
|
if (zde->disk_number != _zip_buffer_get_32(ef_buffer)) {
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
/* fallthrough */
|
||||||
|
case 24:
|
||||||
|
_zip_buffer_set_offset(ef_buffer, 0);
|
||||||
|
if ((zde->uncomp_size != _zip_buffer_get_64(ef_buffer)) || (zde->comp_size != _zip_buffer_get_64(ef_buffer)) || (zde->offset != _zip_buffer_get_64(ef_buffer))) {
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
if (!ok) {
|
||||||
|
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_INVALID_ZIP64_EF);
|
||||||
|
_zip_buffer_free(ef_buffer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_zip_buffer_free(ef_buffer);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static zip_string_t *
|
static zip_string_t *
|
||||||
_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str) {
|
_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str) {
|
||||||
@@ -728,7 +752,7 @@ _zip_dirent_size(zip_source_t *src, zip_uint16_t flags, zip_error_t *error) {
|
|||||||
size = local ? LENTRYSIZE : CDENTRYSIZE;
|
size = local ? LENTRYSIZE : CDENTRYSIZE;
|
||||||
|
|
||||||
if (zip_source_seek(src, local ? 26 : 28, SEEK_CUR) < 0) {
|
if (zip_source_seek(src, local ? 26 : 28, SEEK_CUR) < 0) {
|
||||||
_zip_error_set_from_source(error, src);
|
zip_error_set_from_source(error, src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -901,7 +925,13 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) {
|
|||||||
_zip_buffer_put_16(buffer, (zip_uint16_t)de->comp_method);
|
_zip_buffer_put_16(buffer, (zip_uint16_t)de->comp_method);
|
||||||
}
|
}
|
||||||
|
|
||||||
_zip_u2d_time(de->last_mod, &dostime, &dosdate);
|
if (ZIP_WANT_TORRENTZIP(za)) {
|
||||||
|
dostime = 0xbc00;
|
||||||
|
dosdate = 0x2198;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_zip_u2d_time(de->last_mod, &dostime, &dosdate);
|
||||||
|
}
|
||||||
_zip_buffer_put_16(buffer, dostime);
|
_zip_buffer_put_16(buffer, dostime);
|
||||||
_zip_buffer_put_16(buffer, dosdate);
|
_zip_buffer_put_16(buffer, dosdate);
|
||||||
|
|
||||||
@@ -937,12 +967,15 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_zip_buffer_put_16(buffer, _zip_string_length(de->filename));
|
_zip_buffer_put_16(buffer, _zip_string_length(de->filename));
|
||||||
/* TODO: check for overflow */
|
ef_total_size = (zip_uint32_t)_zip_ef_size(ef, ZIP_EF_BOTH);
|
||||||
ef_total_size = (zip_uint32_t)_zip_ef_size(de->extra_fields, flags) + (zip_uint32_t)_zip_ef_size(ef, ZIP_EF_BOTH);
|
if (!ZIP_WANT_TORRENTZIP(za)) {
|
||||||
|
/* TODO: check for overflow */
|
||||||
|
ef_total_size += (zip_uint32_t)_zip_ef_size(de->extra_fields, flags);
|
||||||
|
}
|
||||||
_zip_buffer_put_16(buffer, (zip_uint16_t)ef_total_size);
|
_zip_buffer_put_16(buffer, (zip_uint16_t)ef_total_size);
|
||||||
|
|
||||||
if ((flags & ZIP_FL_LOCAL) == 0) {
|
if ((flags & ZIP_FL_LOCAL) == 0) {
|
||||||
_zip_buffer_put_16(buffer, _zip_string_length(de->comment));
|
_zip_buffer_put_16(buffer, ZIP_WANT_TORRENTZIP(za) ? 0 : _zip_string_length(de->comment));
|
||||||
_zip_buffer_put_16(buffer, (zip_uint16_t)de->disk_number);
|
_zip_buffer_put_16(buffer, (zip_uint16_t)de->disk_number);
|
||||||
_zip_buffer_put_16(buffer, de->int_attrib);
|
_zip_buffer_put_16(buffer, de->int_attrib);
|
||||||
_zip_buffer_put_32(buffer, de->ext_attrib);
|
_zip_buffer_put_32(buffer, de->ext_attrib);
|
||||||
@@ -981,13 +1014,13 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_zip_ef_free(ef);
|
_zip_ef_free(ef);
|
||||||
if (de->extra_fields) {
|
if (de->extra_fields && !ZIP_WANT_TORRENTZIP(za)) {
|
||||||
if (_zip_ef_write(za, de->extra_fields, flags) < 0) {
|
if (_zip_ef_write(za, de->extra_fields, flags) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & ZIP_FL_LOCAL) == 0) {
|
if ((flags & ZIP_FL_LOCAL) == 0 && !ZIP_WANT_TORRENTZIP(za)) {
|
||||||
if (de->comment) {
|
if (de->comment) {
|
||||||
if (_zip_string_write(za, de->comment) < 0) {
|
if (_zip_string_write(za, de->comment) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1089,15 +1122,10 @@ _zip_get_dirent(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_error_t *err
|
|||||||
void
|
void
|
||||||
_zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate) {
|
_zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate) {
|
||||||
struct tm *tpm;
|
struct tm *tpm;
|
||||||
|
|
||||||
#ifdef HAVE_LOCALTIME_R
|
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
tpm = localtime_r(&intime, &tm);
|
tpm = zip_localtime(&intime, &tm);
|
||||||
#else
|
|
||||||
tpm = localtime(&intime);
|
|
||||||
#endif
|
|
||||||
if (tpm == NULL) {
|
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;
|
*ddate = (1 << 5) + 1;
|
||||||
*dtime = 0;
|
*dtime = 0;
|
||||||
return;
|
return;
|
||||||
@@ -1108,8 +1136,6 @@ _zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate) {
|
|||||||
|
|
||||||
*ddate = (zip_uint16_t)(((tpm->tm_year + 1900 - 1980) << 9) + ((tpm->tm_mon + 1) << 5) + tpm->tm_mday);
|
*ddate = (zip_uint16_t)(((tpm->tm_year + 1900 - 1980) << 9) + ((tpm->tm_mon + 1) << 5) + tpm->tm_mday);
|
||||||
*dtime = (zip_uint16_t)(((tpm->tm_hour) << 11) + ((tpm->tm_min) << 5) + ((tpm->tm_sec) >> 1));
|
*dtime = (zip_uint16_t)(((tpm->tm_hour) << 11) + ((tpm->tm_min) << 5) + ((tpm->tm_sec) >> 1));
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1160,3 +1186,22 @@ _zip_dirent_apply_attributes(zip_dirent_t *de, zip_file_attributes_t *attributes
|
|||||||
de->version_madeby = (de->version_madeby & 0xff) | (zip_uint16_t)(attributes->host_system << 8);
|
de->version_madeby = (de->version_madeby & 0xff) | (zip_uint16_t)(attributes->host_system << 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* _zip_dirent_torrent_normalize(de);
|
||||||
|
Set values suitable for torrentzip.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void zip_dirent_torrentzip_normalize(zip_dirent_t *de) {
|
||||||
|
de->version_madeby = 0;
|
||||||
|
de->version_needed = 20; /* 2.0 */
|
||||||
|
de->bitflags = 2; /* maximum compression */
|
||||||
|
de->comp_method = ZIP_CM_DEFLATE;
|
||||||
|
de->compression_level = TORRENTZIP_COMPRESSION_FLAGS;
|
||||||
|
de->disk_number = 0;
|
||||||
|
de->int_attrib = 0;
|
||||||
|
de->ext_attrib = 0;
|
||||||
|
|
||||||
|
/* last_mod, extra_fields, and comment are normalized in zip_dirent_write() directly */
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -47,6 +47,8 @@ const struct _zip_err_info _zip_err_str[] = {
|
|||||||
{ S, "Tell error" },
|
{ S, "Tell error" },
|
||||||
{ N, "Compressed data invalid" },
|
{ N, "Compressed data invalid" },
|
||||||
{ N, "Operation cancelled" },
|
{ N, "Operation cancelled" },
|
||||||
|
{ N, "Unexpected length of data" },
|
||||||
|
{ N, "Not allowed in torrentzip" },
|
||||||
};
|
};
|
||||||
|
|
||||||
const int _zip_err_str_count = sizeof(_zip_err_str)/sizeof(_zip_err_str[0]);
|
const int _zip_err_str_count = sizeof(_zip_err_str)/sizeof(_zip_err_str[0]);
|
||||||
|
|||||||
@@ -132,7 +132,12 @@ zip_error_set(zip_error_t *err, int ze, int se) {
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_zip_error_set_from_source(zip_error_t *err, zip_source_t *src) {
|
zip_error_set_from_source(zip_error_t *err, zip_source_t *src) {
|
||||||
|
if (src == NULL) {
|
||||||
|
zip_error_set(err, ZIP_ER_INVAL, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_zip_error_copy(err, zip_source_error(src));
|
_zip_error_copy(err, zip_source_error(src));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,23 +42,29 @@
|
|||||||
ZIP_EXTERN const char *
|
ZIP_EXTERN const char *
|
||||||
zip_error_strerror(zip_error_t *err) {
|
zip_error_strerror(zip_error_t *err) {
|
||||||
const char *zip_error_string, *system_error_string;
|
const char *zip_error_string, *system_error_string;
|
||||||
char buf[128], *s;
|
char *s;
|
||||||
|
char *system_error_buffer = NULL;
|
||||||
|
|
||||||
zip_error_fini(err);
|
zip_error_fini(err);
|
||||||
|
|
||||||
if (err->zip_err < 0 || err->zip_err >= _zip_err_str_count) {
|
if (err->zip_err < 0 || err->zip_err >= _zip_err_str_count) {
|
||||||
snprintf(buf, sizeof(buf), "Unknown error %d", err->zip_err);
|
system_error_buffer = (char *)malloc(128);
|
||||||
buf[sizeof(buf) - 1] = '\0'; /* make sure string is NUL-terminated */
|
snprintf_s(system_error_buffer, 128, "Unknown error %d", err->zip_err);
|
||||||
|
system_error_buffer[128 - 1] = '\0'; /* make sure string is NUL-terminated */
|
||||||
zip_error_string = NULL;
|
zip_error_string = NULL;
|
||||||
system_error_string = buf;
|
system_error_string = system_error_buffer;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
zip_error_string = _zip_err_str[err->zip_err].description;
|
zip_error_string = _zip_err_str[err->zip_err].description;
|
||||||
|
|
||||||
switch (_zip_err_str[err->zip_err].type) {
|
switch (_zip_err_str[err->zip_err].type) {
|
||||||
case ZIP_ET_SYS:
|
case ZIP_ET_SYS: {
|
||||||
system_error_string = strerror(err->sys_err);
|
size_t len = strerrorlen_s(err->sys_err) + 1;
|
||||||
|
system_error_buffer = malloc(len);
|
||||||
|
strerror_s(system_error_buffer, len, err->sys_err);
|
||||||
|
system_error_string = system_error_buffer;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ZIP_ET_ZLIB:
|
case ZIP_ET_ZLIB:
|
||||||
system_error_string = zError(err->sys_err);
|
system_error_string = zError(err->sys_err);
|
||||||
@@ -72,14 +78,16 @@ zip_error_strerror(zip_error_t *err) {
|
|||||||
system_error_string = NULL;
|
system_error_string = NULL;
|
||||||
}
|
}
|
||||||
else if (error >= _zip_err_details_count) {
|
else if (error >= _zip_err_details_count) {
|
||||||
snprintf(buf, sizeof(buf), "invalid detail error %u", error);
|
system_error_buffer = (char *)malloc(128);
|
||||||
buf[sizeof(buf) - 1] = '\0'; /* make sure string is NUL-terminated */
|
snprintf_s(system_error_buffer, 128, "invalid detail error %u", error);
|
||||||
system_error_string = buf;
|
system_error_buffer[128 - 1] = '\0'; /* make sure string is NUL-terminated */
|
||||||
|
system_error_string = system_error_buffer;
|
||||||
}
|
}
|
||||||
else if (_zip_err_details[error].type == ZIP_DETAIL_ET_ENTRY && index < MAX_DETAIL_INDEX) {
|
else if (_zip_err_details[error].type == ZIP_DETAIL_ET_ENTRY && index < MAX_DETAIL_INDEX) {
|
||||||
snprintf(buf, sizeof(buf), "entry %d: %s", index, _zip_err_details[error].description);
|
system_error_buffer = (char *)malloc(128);
|
||||||
buf[sizeof(buf) - 1] = '\0'; /* make sure string is NUL-terminated */
|
snprintf_s(system_error_buffer, 128, "entry %d: %s", index, _zip_err_details[error].description);
|
||||||
system_error_string = buf;
|
system_error_buffer[128 - 1] = '\0'; /* make sure string is NUL-terminated */
|
||||||
|
system_error_string = system_error_buffer;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
system_error_string = _zip_err_details[error].description;
|
system_error_string = _zip_err_details[error].description;
|
||||||
@@ -93,16 +101,28 @@ zip_error_strerror(zip_error_t *err) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (system_error_string == NULL) {
|
if (system_error_string == NULL) {
|
||||||
|
free(system_error_buffer);
|
||||||
return zip_error_string;
|
return zip_error_string;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ((s = (char *)malloc(strlen(system_error_string) + (zip_error_string ? strlen(zip_error_string) + 2 : 0) + 1)) == NULL) {
|
size_t length = strlen(system_error_string);
|
||||||
|
if (zip_error_string) {
|
||||||
|
size_t length_error = strlen(zip_error_string);
|
||||||
|
if (length + length_error + 2 < length) {
|
||||||
|
free(system_error_buffer);
|
||||||
|
return _zip_err_str[ZIP_ER_MEMORY].description;
|
||||||
|
}
|
||||||
|
length += length_error + 2;
|
||||||
|
}
|
||||||
|
if (length == SIZE_MAX || (s = (char *)malloc(length + 1)) == NULL) {
|
||||||
|
free(system_error_buffer);
|
||||||
return _zip_err_str[ZIP_ER_MEMORY].description;
|
return _zip_err_str[ZIP_ER_MEMORY].description;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(s, "%s%s%s", (zip_error_string ? zip_error_string : ""), (zip_error_string ? ": " : ""), system_error_string);
|
snprintf_s(s, length + 1, "%s%s%s", (zip_error_string ? zip_error_string : ""), (zip_error_string ? ": " : ""), system_error_string);
|
||||||
err->str = s;
|
err->str = s;
|
||||||
|
|
||||||
|
free(system_error_buffer);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,6 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <zlib.h>
|
|
||||||
|
|
||||||
#define _ZIP_COMPILING_DEPRECATED
|
#define _ZIP_COMPILING_DEPRECATED
|
||||||
#include "zipint.h"
|
#include "zipint.h"
|
||||||
@@ -42,26 +41,18 @@
|
|||||||
|
|
||||||
ZIP_EXTERN int
|
ZIP_EXTERN int
|
||||||
zip_error_to_str(char *buf, zip_uint64_t len, int ze, int se) {
|
zip_error_to_str(char *buf, zip_uint64_t len, int ze, int se) {
|
||||||
const char *zs, *ss;
|
zip_error_t error;
|
||||||
|
const char *error_string;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (ze < 0 || ze >= _zip_err_str_count) {
|
zip_error_init(&error);
|
||||||
return snprintf(buf, len, "Unknown error %d", ze);
|
zip_error_set(&error, ze, se);
|
||||||
}
|
|
||||||
|
|
||||||
zs = _zip_err_str[ze].description;
|
error_string = zip_error_strerror(&error);
|
||||||
|
|
||||||
switch (_zip_err_str[ze].type) {
|
ret = snprintf_s(buf, ZIP_MIN(len, SIZE_MAX), error_string, strlen(error_string));
|
||||||
case ZIP_ET_SYS:
|
|
||||||
ss = strerror(se);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ZIP_ET_ZLIB:
|
zip_error_fini(&error);
|
||||||
ss = zError(se);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
return ret;
|
||||||
ss = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return snprintf(buf, len, "%s%s%s", zs, (ss ? ": " : ""), (ss ? ss : ""));
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -243,10 +243,11 @@ _zip_ef_parse(const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags, zip_
|
|||||||
if (!_zip_buffer_eof(buffer)) {
|
if (!_zip_buffer_eof(buffer)) {
|
||||||
/* Android APK files align stored file data with padding in extra fields; ignore. */
|
/* Android APK files align stored file data with padding in extra fields; ignore. */
|
||||||
/* see https://android.googlesource.com/platform/build/+/master/tools/zipalign/ZipAlign.cpp */
|
/* see https://android.googlesource.com/platform/build/+/master/tools/zipalign/ZipAlign.cpp */
|
||||||
|
/* buffer is at most 64k long, so this can't overflow. */
|
||||||
size_t glen = _zip_buffer_left(buffer);
|
size_t glen = _zip_buffer_left(buffer);
|
||||||
zip_uint8_t *garbage;
|
zip_uint8_t *garbage;
|
||||||
garbage = _zip_buffer_get(buffer, glen);
|
garbage = _zip_buffer_get(buffer, glen);
|
||||||
if (glen >= 4 || garbage == NULL || memcmp(garbage, "\0\0\0", glen) != 0) {
|
if (glen >= 4 || garbage == NULL || memcmp(garbage, "\0\0\0", (size_t)glen) != 0) {
|
||||||
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EF_TRAILING_GARBAGE);
|
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EF_TRAILING_GARBAGE);
|
||||||
_zip_buffer_free(buffer);
|
_zip_buffer_free(buffer);
|
||||||
_zip_ef_free(ef_head);
|
_zip_ef_free(ef_head);
|
||||||
@@ -370,7 +371,7 @@ _zip_read_local_ef(zip_t *za, zip_uint64_t idx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (zip_source_seek(za->src, (zip_int64_t)(e->orig->offset + 26), SEEK_SET) < 0) {
|
if (zip_source_seek(za->src, (zip_int64_t)(e->orig->offset + 26), SEEK_SET) < 0) {
|
||||||
_zip_error_set_from_source(&za->error, za->src);
|
zip_error_set_from_source(&za->error, za->src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,10 @@ zip_file_extra_field_delete(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_idx, zi
|
|||||||
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (ZIP_WANT_TORRENTZIP(za)) {
|
||||||
|
zip_error_set(&za->error, ZIP_ER_NOT_ALLOWED, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (_zip_file_extra_field_prepare_for_change(za, idx) < 0)
|
if (_zip_file_extra_field_prepare_for_change(za, idx) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -88,6 +92,10 @@ zip_file_extra_field_delete_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_i
|
|||||||
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (ZIP_WANT_TORRENTZIP(za)) {
|
||||||
|
zip_error_set(&za->error, ZIP_ER_NOT_ALLOWED, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (_zip_file_extra_field_prepare_for_change(za, idx) < 0)
|
if (_zip_file_extra_field_prepare_for_change(za, idx) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -236,6 +244,10 @@ zip_file_extra_field_set(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_ui
|
|||||||
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (ZIP_WANT_TORRENTZIP(za)) {
|
||||||
|
zip_error_set(&za->error, ZIP_ER_NOT_ALLOWED, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (ZIP_EF_IS_INTERNAL(ef_id)) {
|
if (ZIP_EF_IS_INTERNAL(ef_id)) {
|
||||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||||
|
|||||||
@@ -51,6 +51,10 @@ zip_fdopen(int fd_orig, int _flags, int *zep) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef ENABLE_FDOPEN
|
||||||
|
_zip_set_open_error(zep, NULL, ZIP_ER_OPNOTSUPP);
|
||||||
|
return NULL;
|
||||||
|
#else
|
||||||
/* We dup() here to avoid messing with the passed in fd.
|
/* We dup() here to avoid messing with the passed in fd.
|
||||||
We could not restore it to the original state in case of error. */
|
We could not restore it to the original state in case of error. */
|
||||||
|
|
||||||
@@ -83,4 +87,5 @@ zip_fdopen(int fd_orig, int _flags, int *zep) {
|
|||||||
zip_error_fini(&error);
|
zip_error_fini(&error);
|
||||||
close(fd_orig);
|
close(fd_orig);
|
||||||
return za;
|
return za;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ _zip_file_get_offset(const zip_t *za, zip_uint64_t idx, zip_error_t *error) {
|
|||||||
offset = za->entry[idx].orig->offset;
|
offset = za->entry[idx].orig->offset;
|
||||||
|
|
||||||
if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) {
|
if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) {
|
||||||
_zip_error_set_from_source(error, za->src);
|
zip_error_set_from_source(error, za->src);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,11 +93,11 @@ _zip_file_get_end(const zip_t *za, zip_uint64_t index, zip_error_t *error) {
|
|||||||
if (entry->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) {
|
if (entry->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) {
|
||||||
zip_uint8_t buf[4];
|
zip_uint8_t buf[4];
|
||||||
if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) {
|
if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) {
|
||||||
_zip_error_set_from_source(error, za->src);
|
zip_error_set_from_source(error, za->src);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (zip_source_read(za->src, buf, 4) != 4) {
|
if (zip_source_read(za->src, buf, 4) != 4) {
|
||||||
_zip_error_set_from_source(error, za->src);
|
zip_error_set_from_source(error, za->src);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (memcmp(buf, DATADES_MAGIC, 4) == 0) {
|
if (memcmp(buf, DATADES_MAGIC, 4) == 0) {
|
||||||
|
|||||||
@@ -50,6 +50,10 @@ zip_file_set_comment(zip_t *za, zip_uint64_t idx, const char *comment, zip_uint1
|
|||||||
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (ZIP_WANT_TORRENTZIP(za)) {
|
||||||
|
zip_error_set(&za->error, ZIP_ER_NOT_ALLOWED, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (len > 0 && comment == NULL) {
|
if (len > 0 && comment == NULL) {
|
||||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||||
|
|||||||
@@ -51,6 +51,10 @@ zip_file_set_encryption(zip_t *za, zip_uint64_t idx, zip_uint16_t method, const
|
|||||||
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (ZIP_WANT_TORRENTZIP(za)) {
|
||||||
|
zip_error_set(&za->error, ZIP_ER_NOT_ALLOWED, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (method != ZIP_EM_NONE && _zip_get_encryption_implementation(method, ZIP_CODEC_ENCODE) == NULL) {
|
if (method != ZIP_EM_NONE && _zip_get_encryption_implementation(method, ZIP_CODEC_ENCODE) == NULL) {
|
||||||
zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
|
zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
|
||||||
|
|||||||
@@ -47,6 +47,10 @@ zip_file_set_external_attributes(zip_t *za, zip_uint64_t idx, zip_flags_t flags,
|
|||||||
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (ZIP_WANT_TORRENTZIP(za)) {
|
||||||
|
zip_error_set(&za->error, ZIP_ER_NOT_ALLOWED, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
e = za->entry + idx;
|
e = za->entry + idx;
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,10 @@ zip_file_set_mtime(zip_t *za, zip_uint64_t idx, time_t mtime, zip_flags_t flags)
|
|||||||
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (ZIP_WANT_TORRENTZIP(za)) {
|
||||||
|
zip_error_set(&za->error, ZIP_ER_NOT_ALLOWED, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
e = za->entry + idx;
|
e = za->entry + idx;
|
||||||
|
|
||||||
|
|||||||
@@ -49,11 +49,11 @@ zip_fopen_index_encrypted(zip_t *za, zip_uint64_t index, zip_flags_t flags, cons
|
|||||||
password = NULL;
|
password = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((src = _zip_source_zip_new(za, index, flags, 0, 0, password, &za->error)) == NULL)
|
if ((src = zip_source_zip_file_create(za, index, flags, 0, -1, password, &za->error)) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (zip_source_open(src) < 0) {
|
if (zip_source_open(src) < 0) {
|
||||||
_zip_error_set_from_source(&za->error, src);
|
zip_error_set_from_source(&za->error, src);
|
||||||
zip_source_free(src);
|
zip_source_free(src);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -78,9 +78,7 @@ _zip_file_new(zip_t *za) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
zf->za = za;
|
|
||||||
zip_error_init(&zf->error);
|
zip_error_init(&zf->error);
|
||||||
zf->eof = 0;
|
|
||||||
zf->src = NULL;
|
zf->src = NULL;
|
||||||
|
|
||||||
return zf;
|
return zf;
|
||||||
|
|||||||
@@ -50,11 +50,12 @@ zip_fread(zip_file_t *zf, void *outbuf, zip_uint64_t toread) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((zf->eof) || (toread == 0))
|
if (toread == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if ((n = zip_source_read(zf->src, outbuf, toread)) < 0) {
|
if ((n = zip_source_read(zf->src, outbuf, toread)) < 0) {
|
||||||
_zip_error_set_from_source(&zf->error, zf->src);
|
zip_error_set_from_source(&zf->error, zf->src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ zip_fseek(zip_file_t *zf, zip_int64_t offset, int whence) {
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (zip_source_seek(zf->src, offset, whence) < 0) {
|
if (zip_source_seek(zf->src, offset, whence) < 0) {
|
||||||
_zip_error_set_from_source(&zf->error, zf->src);
|
zip_error_set_from_source(&zf->error, zf->src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,5 +57,5 @@ zip_file_is_seekable(zip_file_t *zfile) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ZIP_SOURCE_CHECK_SUPPORTED(zip_source_supports(zfile->src), ZIP_SOURCE_SEEK);
|
return zip_source_is_seekable(zfile->src);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ zip_ftell(zip_file_t *zf) {
|
|||||||
|
|
||||||
res = zip_source_tell(zf->src);
|
res = zip_source_tell(zf->src);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
_zip_error_set_from_source(&zf->error, zf->src);
|
zip_error_set_from_source(&zf->error, zf->src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,8 +31,10 @@
|
|||||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
#include "zipint.h"
|
#include "zipint.h"
|
||||||
|
|
||||||
@@ -46,7 +48,7 @@ _zip_read(zip_source_t *src, zip_uint8_t *b, zip_uint64_t length, zip_error_t *e
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((n = zip_source_read(src, b, length)) < 0) {
|
if ((n = zip_source_read(src, b, length)) < 0) {
|
||||||
_zip_error_set_from_source(error, src);
|
zip_error_set_from_source(error, src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,7 +83,7 @@ _zip_read_data(zip_buffer_t *buffer, zip_source_t *src, size_t length, bool nulp
|
|||||||
free(r);
|
free(r);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
memcpy(r, data, length);
|
(void)memcpy_s(r, length, data, length);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (_zip_read(src, r, length, error) < 0) {
|
if (_zip_read(src, r, length, error) < 0) {
|
||||||
@@ -122,7 +124,7 @@ _zip_write(zip_t *za, const void *data, zip_uint64_t length) {
|
|||||||
zip_int64_t n;
|
zip_int64_t n;
|
||||||
|
|
||||||
if ((n = zip_source_write(za->src, data, length)) < 0) {
|
if ((n = zip_source_write(za->src, data, length)) < 0) {
|
||||||
_zip_error_set_from_source(&za->error, za->src);
|
zip_error_set_from_source(&za->error, za->src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if ((zip_uint64_t)n != length) {
|
if ((zip_uint64_t)n != length) {
|
||||||
@@ -130,5 +132,15 @@ _zip_write(zip_t *za, const void *data, zip_uint64_t length) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (za->write_crc != NULL) {
|
||||||
|
zip_uint64_t position = 0;
|
||||||
|
while (position < length) {
|
||||||
|
zip_uint64_t nn = ZIP_MIN(UINT_MAX, length - position);
|
||||||
|
|
||||||
|
*za->write_crc = (zip_uint32_t)crc32(*za->write_crc, (const Bytef *)data + position, (uInt)nn);
|
||||||
|
position += nn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ _zip_memdup(const void *mem, size_t len, zip_error_t *error) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(ret, mem, len);
|
(void)memcpy_s(ret, len, mem, len);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,20 +49,29 @@ zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags) {
|
|||||||
zip_int64_t
|
zip_int64_t
|
||||||
_zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags, zip_error_t *error) {
|
_zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags, zip_error_t *error) {
|
||||||
int (*cmp)(const char *, const char *);
|
int (*cmp)(const char *, const char *);
|
||||||
|
size_t fname_length;
|
||||||
zip_string_t *str = NULL;
|
zip_string_t *str = NULL;
|
||||||
const char *fn, *p;
|
const char *fn, *p;
|
||||||
zip_uint64_t i;
|
zip_uint64_t i;
|
||||||
|
|
||||||
if (za == NULL)
|
if (za == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (fname == NULL) {
|
if (fname == NULL) {
|
||||||
zip_error_set(error, ZIP_ER_INVAL, 0);
|
zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fname_length = strlen(fname);
|
||||||
|
|
||||||
|
if (fname_length > ZIP_UINT16_MAX) {
|
||||||
|
zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if ((flags & (ZIP_FL_ENC_UTF_8 | ZIP_FL_ENC_RAW)) == 0 && fname[0] != '\0') {
|
if ((flags & (ZIP_FL_ENC_UTF_8 | ZIP_FL_ENC_RAW)) == 0 && fname[0] != '\0') {
|
||||||
if ((str = _zip_string_new((const zip_uint8_t *)fname, strlen(fname), flags, error)) == NULL) {
|
if ((str = _zip_string_new((const zip_uint8_t *)fname, (zip_uint16_t)strlen(fname), flags, error)) == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if ((fname = (const char *)_zip_string_get(str, NULL, 0, error)) == NULL) {
|
if ((fname = (const char *)_zip_string_get(str, NULL, 0, error)) == NULL) {
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -41,10 +42,11 @@
|
|||||||
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_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_int64_t _zip_checkcons(zip_t *za, zip_cdir_t *cdir, zip_error_t *error);
|
||||||
|
static void zip_check_torrentzip(zip_t *za, const zip_cdir_t *cdir);
|
||||||
static zip_cdir_t *_zip_find_central_dir(zip_t *za, zip_uint64_t len);
|
static zip_cdir_t *_zip_find_central_dir(zip_t *za, zip_uint64_t len);
|
||||||
static exists_t _zip_file_exists(zip_source_t *src, zip_error_t *error);
|
static exists_t _zip_file_exists(zip_source_t *src, zip_error_t *error);
|
||||||
static int _zip_headercomp(const zip_dirent_t *, const zip_dirent_t *);
|
static int _zip_headercomp(const zip_dirent_t *, const zip_dirent_t *);
|
||||||
static unsigned char *_zip_memmem(const unsigned char *, size_t, const unsigned char *, size_t);
|
static const unsigned char *_zip_memmem(const unsigned char *, size_t, const unsigned char *, size_t);
|
||||||
static zip_cdir_t *_zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_error_t *error);
|
static zip_cdir_t *_zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_error_t *error);
|
||||||
static zip_cdir_t *_zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error);
|
static zip_cdir_t *_zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error);
|
||||||
static zip_cdir_t *_zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error);
|
static zip_cdir_t *_zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error);
|
||||||
@@ -120,7 +122,7 @@ zip_open_from_source(zip_source_t *src, int _flags, zip_error_t *error) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (zip_source_open(src) < 0) {
|
if (zip_source_open(src) < 0) {
|
||||||
_zip_error_set_from_source(error, src);
|
zip_error_set_from_source(error, src);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,7 +153,7 @@ _zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error) {
|
|||||||
|
|
||||||
zip_stat_init(&st);
|
zip_stat_init(&st);
|
||||||
if (zip_source_stat(src, &st) < 0) {
|
if (zip_source_stat(src, &st) < 0) {
|
||||||
_zip_error_set_from_source(error, src);
|
zip_error_set_from_source(error, src);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if ((st.valid & ZIP_STAT_SIZE) == 0) {
|
if ((st.valid & ZIP_STAT_SIZE) == 0) {
|
||||||
@@ -181,7 +183,16 @@ _zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error) {
|
|||||||
za->entry = cdir->entry;
|
za->entry = cdir->entry;
|
||||||
za->nentry = cdir->nentry;
|
za->nentry = cdir->nentry;
|
||||||
za->nentry_alloc = cdir->nentry_alloc;
|
za->nentry_alloc = cdir->nentry_alloc;
|
||||||
za->comment_orig = cdir->comment;
|
|
||||||
|
zip_check_torrentzip(za, cdir);
|
||||||
|
|
||||||
|
if (ZIP_IS_TORRENTZIP(za)) {
|
||||||
|
/* Torrentzip uses the archive comment to detect changes by tools that are not torrentzip aware. */
|
||||||
|
_zip_string_free(cdir->comment);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
za->comment_orig = cdir->comment;
|
||||||
|
}
|
||||||
|
|
||||||
free(cdir);
|
free(cdir);
|
||||||
|
|
||||||
@@ -321,7 +332,7 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
|
|||||||
cd_buffer = NULL;
|
cd_buffer = NULL;
|
||||||
|
|
||||||
if (zip_source_seek(za->src, (zip_int64_t)cd->offset, SEEK_SET) < 0) {
|
if (zip_source_seek(za->src, (zip_int64_t)cd->offset, SEEK_SET) < 0) {
|
||||||
_zip_error_set_from_source(error, za->src);
|
zip_error_set_from_source(error, za->src);
|
||||||
_zip_cdir_free(cd);
|
_zip_cdir_free(cd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -388,7 +399,7 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
|
|||||||
zip_int64_t offset = zip_source_tell(za->src);
|
zip_int64_t offset = zip_source_tell(za->src);
|
||||||
|
|
||||||
if (offset < 0) {
|
if (offset < 0) {
|
||||||
_zip_error_set_from_source(error, za->src);
|
zip_error_set_from_source(error, za->src);
|
||||||
_zip_cdir_free(cd);
|
_zip_cdir_free(cd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -445,7 +456,7 @@ _zip_checkcons(zip_t *za, zip_cdir_t *cd, zip_error_t *error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (zip_source_seek(za->src, (zip_int64_t)cd->entry[i].orig->offset, SEEK_SET) < 0) {
|
if (zip_source_seek(za->src, (zip_int64_t)cd->entry[i].orig->offset, SEEK_SET) < 0) {
|
||||||
_zip_error_set_from_source(error, za->src);
|
zip_error_set_from_source(error, za->src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -491,9 +502,20 @@ _zip_headercomp(const zip_dirent_t *central, const zip_dirent_t *local) {
|
|||||||
|
|
||||||
if ((central->crc != local->crc) || (central->comp_size != local->comp_size) || (central->uncomp_size != local->uncomp_size)) {
|
if ((central->crc != local->crc) || (central->comp_size != local->comp_size) || (central->uncomp_size != local->uncomp_size)) {
|
||||||
/* InfoZip stores valid values in local header even when data descriptor is used.
|
/* InfoZip stores valid values in local header even when data descriptor is used.
|
||||||
This is in violation of the appnote. */
|
This is in violation of the appnote.
|
||||||
if (((local->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0 || local->crc != 0 || local->comp_size != 0 || local->uncomp_size != 0))
|
macOS Archive sets the compressed size even when data descriptor is used ( but not the others),
|
||||||
|
also in violation of the appnote.
|
||||||
|
*/
|
||||||
|
/* if data descriptor is not used, the values must match */
|
||||||
|
if ((local->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
/* when using a data descriptor, the local header value must be zero or match */
|
||||||
|
if ((local->crc != 0 && central->crc != local->crc) ||
|
||||||
|
(local->comp_size != 0 && central->comp_size != local->comp_size) ||
|
||||||
|
(local->uncomp_size != 0 && central->uncomp_size != local->uncomp_size)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -510,10 +532,15 @@ _zip_allocate_new(zip_source_t *src, unsigned int flags, zip_error_t *error) {
|
|||||||
|
|
||||||
za->src = src;
|
za->src = src;
|
||||||
za->open_flags = flags;
|
za->open_flags = flags;
|
||||||
|
za->flags = 0;
|
||||||
|
za->ch_flags = 0;
|
||||||
|
za->write_crc = NULL;
|
||||||
|
|
||||||
if (flags & ZIP_RDONLY) {
|
if (flags & ZIP_RDONLY) {
|
||||||
za->flags |= ZIP_AFL_RDONLY;
|
za->flags |= ZIP_AFL_RDONLY;
|
||||||
za->ch_flags |= ZIP_AFL_RDONLY;
|
za->ch_flags |= ZIP_AFL_RDONLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
return za;
|
return za;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -542,7 +569,7 @@ _zip_file_exists(zip_source_t *src, zip_error_t *error) {
|
|||||||
static zip_cdir_t *
|
static zip_cdir_t *
|
||||||
_zip_find_central_dir(zip_t *za, zip_uint64_t len) {
|
_zip_find_central_dir(zip_t *za, zip_uint64_t len) {
|
||||||
zip_cdir_t *cdir, *cdirnew;
|
zip_cdir_t *cdir, *cdirnew;
|
||||||
zip_uint8_t *match;
|
const zip_uint8_t *match;
|
||||||
zip_int64_t buf_offset;
|
zip_int64_t buf_offset;
|
||||||
zip_uint64_t buflen;
|
zip_uint64_t buflen;
|
||||||
zip_int64_t a;
|
zip_int64_t a;
|
||||||
@@ -565,7 +592,7 @@ _zip_find_central_dir(zip_t *za, zip_uint64_t len) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((buf_offset = zip_source_tell(za->src)) < 0) {
|
if ((buf_offset = zip_source_tell(za->src)) < 0) {
|
||||||
_zip_error_set_from_source(&za->error, za->src);
|
zip_error_set_from_source(&za->error, za->src);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -582,7 +609,8 @@ _zip_find_central_dir(zip_t *za, zip_uint64_t len) {
|
|||||||
zip_error_set(&error, ZIP_ER_NOZIP, 0);
|
zip_error_set(&error, ZIP_ER_NOZIP, 0);
|
||||||
|
|
||||||
match = _zip_buffer_get(buffer, 0);
|
match = _zip_buffer_get(buffer, 0);
|
||||||
while ((match = _zip_memmem(match, _zip_buffer_left(buffer) - (EOCDLEN - 4), (const unsigned char *)EOCD_MAGIC, 4)) != NULL) {
|
/* The size of buffer never greater than CDBUFSIZE. */
|
||||||
|
while (_zip_buffer_left(buffer) >= EOCDLEN && (match = _zip_memmem(match, (size_t)_zip_buffer_left(buffer) - (EOCDLEN - 4), (const unsigned char *)EOCD_MAGIC, 4)) != NULL) {
|
||||||
_zip_buffer_set_offset(buffer, (zip_uint64_t)(match - _zip_buffer_data(buffer)));
|
_zip_buffer_set_offset(buffer, (zip_uint64_t)(match - _zip_buffer_data(buffer)));
|
||||||
if ((cdirnew = _zip_read_cdir(za, buffer, (zip_uint64_t)buf_offset, &error)) != NULL) {
|
if ((cdirnew = _zip_read_cdir(za, buffer, (zip_uint64_t)buf_offset, &error)) != NULL) {
|
||||||
if (cdir) {
|
if (cdir) {
|
||||||
@@ -627,19 +655,28 @@ _zip_find_central_dir(zip_t *za, zip_uint64_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static unsigned char *
|
static const unsigned char *_zip_memmem(const unsigned char *big, size_t biglen, const unsigned char *little, size_t littlelen) {
|
||||||
_zip_memmem(const unsigned char *big, size_t biglen, const unsigned char *little, size_t littlelen) {
|
|
||||||
const unsigned char *p;
|
const unsigned char *p;
|
||||||
|
|
||||||
if ((biglen < littlelen) || (littlelen == 0))
|
if (littlelen == 0) {
|
||||||
return NULL;
|
return big;
|
||||||
p = big - 1;
|
|
||||||
while ((p = (const unsigned char *)memchr(p + 1, little[0], (size_t)(big - (p + 1)) + (size_t)(biglen - littlelen) + 1)) != NULL) {
|
|
||||||
if (memcmp(p + 1, little + 1, littlelen - 1) == 0)
|
|
||||||
return (unsigned char *)p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
if (biglen < littlelen) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = big;
|
||||||
|
while (true) {
|
||||||
|
p = (const unsigned char *)memchr(p, little[0], biglen - (littlelen - 1) - (size_t)(p - big));
|
||||||
|
if (p == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (memcmp(p + 1, little + 1, littlelen - 1) == 0) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
p += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -739,7 +776,7 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (zip_source_seek(src, (zip_int64_t)eocd_offset, SEEK_SET) < 0) {
|
if (zip_source_seek(src, (zip_int64_t)eocd_offset, SEEK_SET) < 0) {
|
||||||
_zip_error_set_from_source(error, src);
|
zip_error_set_from_source(error, src);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if ((buffer = _zip_buffer_new_from_source(src, EOCD64LEN, eocd, error)) == NULL) {
|
if ((buffer = _zip_buffer_new_from_source(src, EOCD64LEN, eocd, error)) == NULL) {
|
||||||
@@ -852,3 +889,79 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse
|
|||||||
|
|
||||||
return cd;
|
return cd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int decode_hex(char c) {
|
||||||
|
if (c >= '0' && c <= '9') {
|
||||||
|
return c - '0';
|
||||||
|
}
|
||||||
|
else if (c >= 'A' && c <= 'F') {
|
||||||
|
return c - 'A' + 10;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* _zip_check_torrentzip:
|
||||||
|
check whether ZA has a valid TORRENTZIP comment, i.e. is torrentzipped */
|
||||||
|
|
||||||
|
static void zip_check_torrentzip(zip_t *za, const zip_cdir_t *cdir) {
|
||||||
|
zip_uint32_t crc_should;
|
||||||
|
char buf[8+1];
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (cdir == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_zip_string_length(cdir->comment) != TORRENTZIP_SIGNATURE_LENGTH + TORRENTZIP_CRC_LENGTH
|
||||||
|
|| strncmp((const char *)cdir->comment->raw, TORRENTZIP_SIGNATURE, TORRENTZIP_SIGNATURE_LENGTH) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
memcpy(buf, cdir->comment->raw + TORRENTZIP_SIGNATURE_LENGTH, TORRENTZIP_CRC_LENGTH);
|
||||||
|
buf[TORRENTZIP_CRC_LENGTH] = '\0';
|
||||||
|
crc_should = 0;
|
||||||
|
for (i = 0; i < TORRENTZIP_CRC_LENGTH; i += 2) {
|
||||||
|
int low, high;
|
||||||
|
high = decode_hex((buf[i]));
|
||||||
|
low = decode_hex(buf[i + 1]);
|
||||||
|
if (high < 0 || low < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
crc_should = (crc_should << 8) + (high << 4) + low;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
zip_stat_t st;
|
||||||
|
zip_source_t* src_window;
|
||||||
|
zip_source_t* src_crc;
|
||||||
|
zip_uint8_t buffer[512];
|
||||||
|
zip_int64_t ret;
|
||||||
|
|
||||||
|
zip_stat_init(&st);
|
||||||
|
st.valid |= ZIP_STAT_SIZE | ZIP_STAT_CRC;
|
||||||
|
st.size = cdir->size;
|
||||||
|
st.crc = crc_should;
|
||||||
|
if ((src_window = _zip_source_window_new(za->src, cdir->offset, cdir->size, &st, 0, NULL, NULL, 0, false, NULL)) == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((src_crc = zip_source_crc_create(src_window, 1, NULL)) == NULL) {
|
||||||
|
zip_source_free(src_window);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (zip_source_open(src_crc) != 0) {
|
||||||
|
zip_source_free(src_crc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while ((ret = zip_source_read(src_crc, buffer, sizeof(buffer))) > 0) {
|
||||||
|
}
|
||||||
|
zip_source_free(src_crc);
|
||||||
|
if (ret < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: if check consistency, check cdir entries for valid values */
|
||||||
|
za->flags |= ZIP_AFL_IS_TORRENTZIP;
|
||||||
|
}
|
||||||
|
|||||||
@@ -45,6 +45,10 @@ zip_set_archive_comment(zip_t *za, const char *comment, zip_uint16_t len) {
|
|||||||
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (ZIP_WANT_TORRENTZIP(za)) {
|
||||||
|
zip_error_set(&za->error, ZIP_ER_NOT_ALLOWED, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (len > 0 && comment == NULL) {
|
if (len > 0 && comment == NULL) {
|
||||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||||
|
|||||||
@@ -39,13 +39,23 @@ ZIP_EXTERN int
|
|||||||
zip_set_archive_flag(zip_t *za, zip_flags_t flag, int value) {
|
zip_set_archive_flag(zip_t *za, zip_flags_t flag, int value) {
|
||||||
unsigned int new_flags;
|
unsigned int new_flags;
|
||||||
|
|
||||||
if (value)
|
if (flag == ZIP_AFL_IS_TORRENTZIP) {
|
||||||
new_flags = za->ch_flags | flag;
|
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||||
else
|
return -1;
|
||||||
new_flags = za->ch_flags & ~flag;
|
}
|
||||||
|
|
||||||
if (new_flags == za->ch_flags)
|
/* TODO: when setting ZIP_AFL_WANT_TORRENTZIP, we should error out if any changes have been made that are not allowed for torrentzip. */
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
new_flags = za->ch_flags | flag;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
new_flags = za->ch_flags & ~flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (new_flags == za->ch_flags) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (ZIP_IS_RDONLY(za)) {
|
if (ZIP_IS_RDONLY(za)) {
|
||||||
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||||
|
|||||||
@@ -49,6 +49,10 @@ zip_set_file_compression(zip_t *za, zip_uint64_t idx, zip_int32_t method, zip_ui
|
|||||||
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (ZIP_WANT_TORRENTZIP(za)) {
|
||||||
|
zip_error_set(&za->error, ZIP_ER_NOT_ALLOWED, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (!zip_compression_method_supported(method, true)) {
|
if (!zip_compression_method_supported(method, true)) {
|
||||||
zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
|
zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
zip_source_accept_empty(zip_source_t *src) {
|
zip_source_accept_empty(zip_source_t *src) {
|
||||||
int ret;
|
zip_int64_t ret;
|
||||||
|
|
||||||
if ((zip_source_supports(src) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ACCEPT_EMPTY)) == 0) {
|
if ((zip_source_supports(src) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ACCEPT_EMPTY)) == 0) {
|
||||||
if (ZIP_SOURCE_IS_LAYERED(src)) {
|
if (ZIP_SOURCE_IS_LAYERED(src)) {
|
||||||
@@ -46,7 +46,7 @@ zip_source_accept_empty(zip_source_t *src) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = (int)_zip_source_call(src, NULL, 0, ZIP_SOURCE_ACCEPT_EMPTY);
|
ret = _zip_source_call(src, NULL, 0, ZIP_SOURCE_ACCEPT_EMPTY);
|
||||||
|
|
||||||
return ret != 0;
|
return ret != 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,11 @@
|
|||||||
|
|
||||||
ZIP_EXTERN int
|
ZIP_EXTERN int
|
||||||
zip_source_begin_write(zip_source_t *src) {
|
zip_source_begin_write(zip_source_t *src) {
|
||||||
|
if (ZIP_SOURCE_IS_LAYERED(src)) {
|
||||||
|
zip_error_set(&src->error, ZIP_ER_OPNOTSUPP, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (ZIP_SOURCE_IS_OPEN_WRITING(src)) {
|
if (ZIP_SOURCE_IS_OPEN_WRITING(src)) {
|
||||||
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
|
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -37,6 +37,11 @@
|
|||||||
|
|
||||||
ZIP_EXTERN int
|
ZIP_EXTERN int
|
||||||
zip_source_begin_write_cloning(zip_source_t *src, zip_uint64_t offset) {
|
zip_source_begin_write_cloning(zip_source_t *src, zip_uint64_t offset) {
|
||||||
|
if (ZIP_SOURCE_IS_LAYERED(src)) {
|
||||||
|
zip_error_set(&src->error, ZIP_ER_OPNOTSUPP, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (ZIP_SOURCE_IS_OPEN_WRITING(src)) {
|
if (ZIP_SOURCE_IS_OPEN_WRITING(src)) {
|
||||||
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
|
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -50,8 +50,8 @@ struct buffer {
|
|||||||
|
|
||||||
zip_uint64_t shared_fragments; /* number of shared fragments */
|
zip_uint64_t shared_fragments; /* number of shared fragments */
|
||||||
struct buffer *shared_buffer; /* buffer fragments are shared with */
|
struct buffer *shared_buffer; /* buffer fragments are shared with */
|
||||||
zip_uint64_t size; /* size of buffer */
|
|
||||||
|
|
||||||
|
zip_uint64_t size; /* size of buffer */
|
||||||
zip_uint64_t offset; /* current offset in buffer */
|
zip_uint64_t offset; /* current offset in buffer */
|
||||||
zip_uint64_t current_fragment; /* fragment current offset is in */
|
zip_uint64_t current_fragment; /* fragment current offset is in */
|
||||||
};
|
};
|
||||||
@@ -159,7 +159,7 @@ zip_source_buffer_fragment_with_attributes_create(const zip_buffer_fragment_t *f
|
|||||||
ctx->out = NULL;
|
ctx->out = NULL;
|
||||||
ctx->mtime = time(NULL);
|
ctx->mtime = time(NULL);
|
||||||
if (attributes) {
|
if (attributes) {
|
||||||
memcpy(&ctx->attributes, attributes, sizeof(ctx->attributes));
|
(void)memcpy_s(&ctx->attributes, sizeof(ctx->attributes), attributes, sizeof(ctx->attributes));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
zip_file_attributes_init(&ctx->attributes);
|
zip_file_attributes_init(&ctx->attributes);
|
||||||
@@ -226,7 +226,7 @@ read_data(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(data, &ctx->attributes, sizeof(ctx->attributes));
|
(void)memcpy_s(data, sizeof(ctx->attributes), &ctx->attributes, sizeof(ctx->attributes));
|
||||||
|
|
||||||
return sizeof(ctx->attributes);
|
return sizeof(ctx->attributes);
|
||||||
}
|
}
|
||||||
@@ -287,7 +287,7 @@ read_data(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case ZIP_SOURCE_SUPPORTS:
|
case ZIP_SOURCE_SUPPORTS:
|
||||||
return zip_source_make_command_bitmap(ZIP_SOURCE_GET_FILE_ATTRIBUTES, ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, ZIP_SOURCE_SEEK, ZIP_SOURCE_TELL, ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_BEGIN_WRITE_CLONING, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_REMOVE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_WRITE, -1);
|
return zip_source_make_command_bitmap(ZIP_SOURCE_GET_FILE_ATTRIBUTES, ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, ZIP_SOURCE_SEEK, ZIP_SOURCE_TELL, ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_BEGIN_WRITE_CLONING, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_REMOVE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_WRITE, ZIP_SOURCE_SUPPORTS_REOPEN, -1);
|
||||||
|
|
||||||
case ZIP_SOURCE_TELL:
|
case ZIP_SOURCE_TELL:
|
||||||
if (ctx->in->offset > ZIP_INT64_MAX) {
|
if (ctx->in->offset > ZIP_INT64_MAX) {
|
||||||
@@ -344,6 +344,7 @@ buffer_clone(buffer_t *buffer, zip_uint64_t offset, zip_error_t *error) {
|
|||||||
fragment_offset = buffer->fragments[fragment].length;
|
fragment_offset = buffer->fragments[fragment].length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: This should also consider the length of the fully shared fragments */
|
||||||
waste = buffer->fragments[fragment].length - fragment_offset;
|
waste = buffer->fragments[fragment].length - fragment_offset;
|
||||||
if (waste > offset) {
|
if (waste > offset) {
|
||||||
zip_error_set(error, ZIP_ER_OPNOTSUPP, 0);
|
zip_error_set(error, ZIP_ER_OPNOTSUPP, 0);
|
||||||
@@ -356,7 +357,7 @@ buffer_clone(buffer_t *buffer, zip_uint64_t offset, zip_error_t *error) {
|
|||||||
|
|
||||||
#ifndef __clang_analyzer__
|
#ifndef __clang_analyzer__
|
||||||
/* clone->fragments can't be null, since it was created with at least one fragment */
|
/* clone->fragments can't be null, since it was created with at least one fragment */
|
||||||
clone->fragments[clone->nfragments - 1].length = fragment_offset;
|
clone->fragments[fragment].length = fragment_offset;
|
||||||
#endif
|
#endif
|
||||||
clone->fragment_offsets[clone->nfragments] = offset;
|
clone->fragment_offsets[clone->nfragments] = offset;
|
||||||
clone->size = offset;
|
clone->size = offset;
|
||||||
@@ -365,7 +366,7 @@ buffer_clone(buffer_t *buffer, zip_uint64_t offset, zip_error_t *error) {
|
|||||||
|
|
||||||
buffer->shared_buffer = clone;
|
buffer->shared_buffer = clone;
|
||||||
clone->shared_buffer = buffer;
|
clone->shared_buffer = buffer;
|
||||||
buffer->shared_fragments = clone->nfragments;
|
buffer->shared_fragments = fragment + 1;
|
||||||
clone->shared_fragments = fragment + 1;
|
clone->shared_fragments = fragment + 1;
|
||||||
|
|
||||||
return clone;
|
return clone;
|
||||||
@@ -428,17 +429,27 @@ static bool
|
|||||||
buffer_grow_fragments(buffer_t *buffer, zip_uint64_t capacity, zip_error_t *error) {
|
buffer_grow_fragments(buffer_t *buffer, zip_uint64_t capacity, zip_error_t *error) {
|
||||||
zip_buffer_fragment_t *fragments;
|
zip_buffer_fragment_t *fragments;
|
||||||
zip_uint64_t *offsets;
|
zip_uint64_t *offsets;
|
||||||
|
zip_uint64_t fragments_size;
|
||||||
|
zip_uint64_t offsets_size;
|
||||||
|
|
||||||
if (capacity < buffer->fragments_capacity) {
|
if (capacity < buffer->fragments_capacity) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((fragments = realloc(buffer->fragments, sizeof(buffer->fragments[0]) * capacity)) == NULL) {
|
fragments_size = sizeof(buffer->fragments[0]) * capacity;
|
||||||
|
offsets_size = sizeof(buffer->fragment_offsets[0]) * (capacity + 1);
|
||||||
|
|
||||||
|
if (capacity == ZIP_UINT64_MAX || fragments_size < capacity || fragments_size > SIZE_MAX|| offsets_size < capacity || offsets_size > SIZE_MAX) {
|
||||||
|
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((fragments = realloc(buffer->fragments, (size_t)fragments_size)) == NULL) {
|
||||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
buffer->fragments = fragments;
|
buffer->fragments = fragments;
|
||||||
if ((offsets = realloc(buffer->fragment_offsets, sizeof(buffer->fragment_offsets[0]) * (capacity + 1))) == NULL) {
|
if ((offsets = realloc(buffer->fragment_offsets, (size_t)offsets_size)) == NULL) {
|
||||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -497,6 +508,7 @@ buffer_new(const zip_buffer_fragment_t *fragments, zip_uint64_t nfragments, int
|
|||||||
buffer->fragments[j].data = fragments[i].data;
|
buffer->fragments[j].data = fragments[i].data;
|
||||||
buffer->fragments[j].length = fragments[i].length;
|
buffer->fragments[j].length = fragments[i].length;
|
||||||
buffer->fragment_offsets[i] = offset;
|
buffer->fragment_offsets[i] = offset;
|
||||||
|
/* TODO: overflow */
|
||||||
offset += fragments[i].length;
|
offset += fragments[i].length;
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
@@ -527,8 +539,11 @@ buffer_read(buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length) {
|
|||||||
n = 0;
|
n = 0;
|
||||||
while (n < length) {
|
while (n < length) {
|
||||||
zip_uint64_t left = ZIP_MIN(length - n, buffer->fragments[i].length - fragment_offset);
|
zip_uint64_t left = ZIP_MIN(length - n, buffer->fragments[i].length - fragment_offset);
|
||||||
|
#if ZIP_UINT64_MAX > SIZE_MAX
|
||||||
|
left = ZIP_MIN(left, SIZE_MAX);
|
||||||
|
#endif
|
||||||
|
|
||||||
memcpy(data + n, buffer->fragments[i].data + fragment_offset, left);
|
(void)memcpy_s(data + n, (size_t)left, buffer->fragments[i].data + fragment_offset, (size_t)left);
|
||||||
|
|
||||||
if (left == buffer->fragments[i].length - fragment_offset) {
|
if (left == buffer->fragments[i].length - fragment_offset) {
|
||||||
i++;
|
i++;
|
||||||
@@ -559,7 +574,7 @@ buffer_seek(buffer_t *buffer, void *data, zip_uint64_t len, zip_error_t *error)
|
|||||||
|
|
||||||
static zip_int64_t
|
static zip_int64_t
|
||||||
buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_uint64_t length, zip_error_t *error) {
|
buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_uint64_t length, zip_error_t *error) {
|
||||||
zip_uint64_t n, i, fragment_offset, capacity;
|
zip_uint64_t copied, i, fragment_offset, capacity;
|
||||||
|
|
||||||
if (buffer->offset + length + WRITE_FRAGMENT_SIZE - 1 < length) {
|
if (buffer->offset + length + WRITE_FRAGMENT_SIZE - 1 < length) {
|
||||||
zip_error_set(error, ZIP_ER_INVAL, 0);
|
zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||||
@@ -601,24 +616,30 @@ buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_uint64_t length, zip
|
|||||||
|
|
||||||
i = buffer->current_fragment;
|
i = buffer->current_fragment;
|
||||||
fragment_offset = buffer->offset - buffer->fragment_offsets[i];
|
fragment_offset = buffer->offset - buffer->fragment_offsets[i];
|
||||||
n = 0;
|
copied = 0;
|
||||||
while (n < length) {
|
while (copied < length) {
|
||||||
zip_uint64_t left = ZIP_MIN(length - n, buffer->fragments[i].length - fragment_offset);
|
zip_uint64_t n = ZIP_MIN(ZIP_MIN(length - copied, buffer->fragments[i].length - fragment_offset), SIZE_MAX);
|
||||||
|
#if ZIP_UINT64_MAX > SIZE_MAX
|
||||||
|
n = ZIP_MIN(n, SIZE_MAX);
|
||||||
|
#endif
|
||||||
|
|
||||||
memcpy(buffer->fragments[i].data + fragment_offset, data + n, left);
|
(void)memcpy_s(buffer->fragments[i].data + fragment_offset, (size_t)n, data + copied, (size_t)n);
|
||||||
|
|
||||||
if (left == buffer->fragments[i].length - fragment_offset) {
|
if (n == buffer->fragments[i].length - fragment_offset) {
|
||||||
i++;
|
i++;
|
||||||
|
fragment_offset = 0;
|
||||||
}
|
}
|
||||||
n += left;
|
else {
|
||||||
fragment_offset = 0;
|
fragment_offset += n;
|
||||||
|
}
|
||||||
|
copied += n;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer->offset += n;
|
buffer->offset += copied;
|
||||||
buffer->current_fragment = i;
|
buffer->current_fragment = i;
|
||||||
if (buffer->offset > buffer->size) {
|
if (buffer->offset > buffer->size) {
|
||||||
buffer->size = buffer->offset;
|
buffer->size = buffer->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (zip_int64_t)n;
|
return (zip_int64_t)copied;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,11 @@
|
|||||||
|
|
||||||
ZIP_EXTERN int
|
ZIP_EXTERN int
|
||||||
zip_source_commit_write(zip_source_t *src) {
|
zip_source_commit_write(zip_source_t *src) {
|
||||||
|
if (ZIP_SOURCE_IS_LAYERED(src)) {
|
||||||
|
zip_error_set(&src->error, ZIP_ER_OPNOTSUPP, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ZIP_SOURCE_IS_OPEN_WRITING(src)) {
|
if (!ZIP_SOURCE_IS_OPEN_WRITING(src)) {
|
||||||
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
|
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -83,10 +83,10 @@ static struct implementation implementations[] = {
|
|||||||
|
|
||||||
static size_t implementations_size = sizeof(implementations) / sizeof(implementations[0]);
|
static size_t implementations_size = sizeof(implementations) / sizeof(implementations[0]);
|
||||||
|
|
||||||
static zip_source_t *compression_source_new(zip_t *za, zip_source_t *src, zip_int32_t method, bool compress, int compression_flags);
|
static zip_source_t *compression_source_new(zip_t *za, zip_source_t *src, zip_int32_t method, bool compress, zip_uint32_t compression_flags);
|
||||||
static zip_int64_t compress_callback(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
|
static zip_int64_t compress_callback(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
|
||||||
static void context_free(struct context *ctx);
|
static void context_free(struct context *ctx);
|
||||||
static struct context *context_new(zip_int32_t method, bool compress, int compression_flags, zip_compression_algorithm_t *algorithm);
|
static struct context *context_new(zip_int32_t method, bool compress, zip_uint32_t compression_flags, zip_compression_algorithm_t *algorithm);
|
||||||
static zip_int64_t compress_read(zip_source_t *, struct context *, void *, zip_uint64_t);
|
static zip_int64_t compress_read(zip_source_t *, struct context *, void *, zip_uint64_t);
|
||||||
|
|
||||||
zip_compression_algorithm_t *
|
zip_compression_algorithm_t *
|
||||||
@@ -117,7 +117,7 @@ zip_compression_method_supported(zip_int32_t method, int compress) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
zip_source_t *
|
zip_source_t *
|
||||||
zip_source_compress(zip_t *za, zip_source_t *src, zip_int32_t method, int compression_flags) {
|
zip_source_compress(zip_t *za, zip_source_t *src, zip_int32_t method, zip_uint32_t compression_flags) {
|
||||||
return compression_source_new(za, src, method, true, compression_flags);
|
return compression_source_new(za, src, method, true, compression_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +128,7 @@ zip_source_decompress(zip_t *za, zip_source_t *src, zip_int32_t method) {
|
|||||||
|
|
||||||
|
|
||||||
static zip_source_t *
|
static zip_source_t *
|
||||||
compression_source_new(zip_t *za, zip_source_t *src, zip_int32_t method, bool compress, int compression_flags) {
|
compression_source_new(zip_t *za, zip_source_t *src, zip_int32_t method, bool compress, zip_uint32_t compression_flags) {
|
||||||
struct context *ctx;
|
struct context *ctx;
|
||||||
zip_source_t *s2;
|
zip_source_t *s2;
|
||||||
zip_compression_algorithm_t *algorithm = NULL;
|
zip_compression_algorithm_t *algorithm = NULL;
|
||||||
@@ -158,7 +158,7 @@ compression_source_new(zip_t *za, zip_source_t *src, zip_int32_t method, bool co
|
|||||||
|
|
||||||
|
|
||||||
static struct context *
|
static struct context *
|
||||||
context_new(zip_int32_t method, bool compress, int compression_flags, zip_compression_algorithm_t *algorithm) {
|
context_new(zip_int32_t method, bool compress, zip_uint32_t compression_flags, zip_compression_algorithm_t *algorithm) {
|
||||||
struct context *ctx;
|
struct context *ctx;
|
||||||
|
|
||||||
if ((ctx = (struct context *)malloc(sizeof(*ctx))) == NULL) {
|
if ((ctx = (struct context *)malloc(sizeof(*ctx))) == NULL) {
|
||||||
@@ -240,7 +240,7 @@ compress_read(zip_source_t *src, struct context *ctx, void *data, zip_uint64_t l
|
|||||||
if (ctx->can_store && (zip_uint64_t)ctx->first_read <= out_offset) {
|
if (ctx->can_store && (zip_uint64_t)ctx->first_read <= out_offset) {
|
||||||
ctx->is_stored = true;
|
ctx->is_stored = true;
|
||||||
ctx->size = (zip_uint64_t)ctx->first_read;
|
ctx->size = (zip_uint64_t)ctx->first_read;
|
||||||
memcpy(data, ctx->buffer, ctx->size);
|
(void)memcpy_s(data, ctx->size, ctx->buffer, ctx->size);
|
||||||
return (zip_int64_t)ctx->size;
|
return (zip_int64_t)ctx->size;
|
||||||
}
|
}
|
||||||
end = true;
|
end = true;
|
||||||
@@ -257,7 +257,7 @@ compress_read(zip_source_t *src, struct context *ctx, void *data, zip_uint64_t l
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((n = zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) {
|
if ((n = zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) {
|
||||||
_zip_error_set_from_source(&ctx->error, src);
|
zip_error_set_from_source(&ctx->error, src);
|
||||||
end = true;
|
end = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -319,7 +319,7 @@ compress_callback(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip
|
|||||||
ctx->first_read = -1;
|
ctx->first_read = -1;
|
||||||
|
|
||||||
if (zip_source_stat(src, &st) < 0 || zip_source_get_file_attributes(src, &attributes) < 0) {
|
if (zip_source_stat(src, &st) < 0 || zip_source_get_file_attributes(src, &attributes) < 0) {
|
||||||
_zip_error_set_from_source(&ctx->error, src);
|
zip_error_set_from_source(&ctx->error, src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,6 +357,7 @@ compress_callback(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip
|
|||||||
else {
|
else {
|
||||||
st->comp_method = ZIP_CM_STORE;
|
st->comp_method = ZIP_CM_STORE;
|
||||||
st->valid |= ZIP_STAT_COMP_METHOD;
|
st->valid |= ZIP_STAT_COMP_METHOD;
|
||||||
|
st->valid &= ~ZIP_STAT_COMP_SIZE;
|
||||||
if (ctx->end_of_stream) {
|
if (ctx->end_of_stream) {
|
||||||
st->size = ctx->size;
|
st->size = ctx->size;
|
||||||
st->valid |= ZIP_STAT_SIZE;
|
st->valid |= ZIP_STAT_SIZE;
|
||||||
@@ -389,10 +390,9 @@ compress_callback(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip
|
|||||||
}
|
}
|
||||||
|
|
||||||
case ZIP_SOURCE_SUPPORTS:
|
case ZIP_SOURCE_SUPPORTS:
|
||||||
return ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_GET_FILE_ATTRIBUTES, -1);
|
return ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_GET_FILE_ATTRIBUTES, ZIP_SOURCE_SUPPORTS_REOPEN, -1);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0);
|
return zip_source_pass_to_lower_layer(src, data, len, cmd);
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ crc_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source
|
|||||||
|
|
||||||
case ZIP_SOURCE_READ:
|
case ZIP_SOURCE_READ:
|
||||||
if ((n = zip_source_read(src, data, len)) < 0) {
|
if ((n = zip_source_read(src, data, len)) < 0) {
|
||||||
_zip_error_set_from_source(&ctx->error, src);
|
zip_error_set_from_source(&ctx->error, src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ crc_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source
|
|||||||
struct zip_stat st;
|
struct zip_stat st;
|
||||||
|
|
||||||
if (zip_source_stat(src, &st) < 0) {
|
if (zip_source_stat(src, &st) < 0) {
|
||||||
_zip_error_set_from_source(&ctx->error, src);
|
zip_error_set_from_source(&ctx->error, src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,6 +141,10 @@ crc_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source
|
|||||||
st = (zip_stat_t *)data;
|
st = (zip_stat_t *)data;
|
||||||
|
|
||||||
if (ctx->crc_complete) {
|
if (ctx->crc_complete) {
|
||||||
|
if ((st->valid & ZIP_STAT_SIZE) && st->size != ctx->size) {
|
||||||
|
zip_error_set(&ctx->error, ZIP_ER_DATA_LENGTH, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
/* TODO: Set comp_size, comp_method, encryption_method?
|
/* TODO: Set comp_size, comp_method, encryption_method?
|
||||||
After all, this only works for uncompressed data. */
|
After all, this only works for uncompressed data. */
|
||||||
st->size = ctx->size;
|
st->size = ctx->size;
|
||||||
@@ -164,11 +168,13 @@ crc_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source
|
|||||||
zip_int64_t mask = zip_source_supports(src);
|
zip_int64_t mask = zip_source_supports(src);
|
||||||
|
|
||||||
if (mask < 0) {
|
if (mask < 0) {
|
||||||
_zip_error_set_from_source(&ctx->error, src);
|
zip_error_set_from_source(&ctx->error, src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mask & ~zip_source_make_command_bitmap(ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_REMOVE, ZIP_SOURCE_GET_FILE_ATTRIBUTES, -1);
|
mask &= ~zip_source_make_command_bitmap(ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_REMOVE, ZIP_SOURCE_GET_FILE_ATTRIBUTES, -1);
|
||||||
|
mask |= zip_source_make_command_bitmap(ZIP_SOURCE_FREE, -1);
|
||||||
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ZIP_SOURCE_SEEK: {
|
case ZIP_SOURCE_SEEK: {
|
||||||
@@ -179,7 +185,7 @@ crc_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (zip_source_seek(src, args->offset, args->whence) < 0 || (new_position = zip_source_tell(src)) < 0) {
|
if (zip_source_seek(src, args->offset, args->whence) < 0 || (new_position = zip_source_tell(src)) < 0) {
|
||||||
_zip_error_set_from_source(&ctx->error, src);
|
zip_error_set_from_source(&ctx->error, src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,7 +198,6 @@ crc_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source
|
|||||||
return (zip_int64_t)ctx->position;
|
return (zip_int64_t)ctx->position;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
|
return zip_source_pass_to_lower_layer(src, data, len, cmd);
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ zip_source_file_common_new(const char *fname, void *file, zip_uint64_t start, zi
|
|||||||
ctx->start = start;
|
ctx->start = start;
|
||||||
ctx->len = (zip_uint64_t)len;
|
ctx->len = (zip_uint64_t)len;
|
||||||
if (st) {
|
if (st) {
|
||||||
memcpy(&ctx->st, st, sizeof(ctx->st));
|
(void)memcpy_s(&ctx->st, sizeof(ctx->st), st, sizeof(*st));
|
||||||
ctx->st.name = NULL;
|
ctx->st.name = NULL;
|
||||||
ctx->st.valid &= ~ZIP_STAT_NAME;
|
ctx->st.valid &= ~ZIP_STAT_NAME;
|
||||||
}
|
}
|
||||||
@@ -130,7 +130,7 @@ zip_source_file_common_new(const char *fname, void *file, zip_uint64_t start, zi
|
|||||||
zip_error_init(&ctx->error);
|
zip_error_init(&ctx->error);
|
||||||
zip_file_attributes_init(&ctx->attributes);
|
zip_file_attributes_init(&ctx->attributes);
|
||||||
|
|
||||||
ctx->supports = ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1);
|
ctx->supports = ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, ZIP_SOURCE_SUPPORTS_REOPEN, -1);
|
||||||
|
|
||||||
zip_source_file_stat_init(&sb);
|
zip_source_file_stat_init(&sb);
|
||||||
if (!ops->stat(ctx, &sb)) {
|
if (!ops->stat(ctx, &sb)) {
|
||||||
@@ -262,7 +262,7 @@ read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) {
|
|||||||
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
|
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
memcpy(data, &ctx->attributes, sizeof(ctx->attributes));
|
(void)memcpy_s(data, sizeof(ctx->attributes), &ctx->attributes, sizeof(ctx->attributes));
|
||||||
return sizeof(ctx->attributes);
|
return sizeof(ctx->attributes);
|
||||||
|
|
||||||
case ZIP_SOURCE_OPEN:
|
case ZIP_SOURCE_OPEN:
|
||||||
@@ -272,7 +272,7 @@ read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->start > 0) { // TODO: rewind on re-open
|
if (ctx->start > 0) { /* TODO: rewind on re-open */
|
||||||
if (ctx->ops->seek(ctx, ctx->f, (zip_int64_t)ctx->start, SEEK_SET) == false) {
|
if (ctx->ops->seek(ctx, ctx->f, (zip_int64_t)ctx->start, SEEK_SET) == false) {
|
||||||
/* TODO: skip by reading */
|
/* TODO: skip by reading */
|
||||||
return -1;
|
return -1;
|
||||||
@@ -355,7 +355,7 @@ read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(data, &ctx->st, sizeof(ctx->st));
|
(void)memcpy_s(data, sizeof(ctx->st), &ctx->st, sizeof(ctx->st));
|
||||||
return sizeof(ctx->st);
|
return sizeof(ctx->st);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -176,33 +176,3 @@ _zip_stdio_op_tell(zip_source_file_context_t *ctx, void *f) {
|
|||||||
|
|
||||||
return offset;
|
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;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -42,6 +42,4 @@ bool _zip_stdio_op_seek(zip_source_file_context_t *ctx, void *f, zip_int64_t off
|
|||||||
bool _zip_stdio_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st);
|
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);
|
zip_int64_t _zip_stdio_op_tell(zip_source_file_context_t *ctx, void *f);
|
||||||
|
|
||||||
FILE *_zip_fopen_close_on_exec(const char *name, bool writeable);
|
|
||||||
|
|
||||||
#endif /* _HAD_ZIP_SOURCE_FILE_STDIO_H */
|
#endif /* _HAD_ZIP_SOURCE_FILE_STDIO_H */
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ static zip_int64_t _zip_stdio_op_remove(zip_source_file_context_t *ctx);
|
|||||||
static void _zip_stdio_op_rollback_write(zip_source_file_context_t *ctx);
|
static 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 char *_zip_stdio_op_strdup(zip_source_file_context_t *ctx, const char *string);
|
||||||
static zip_int64_t _zip_stdio_op_write(zip_source_file_context_t *ctx, const void *data, zip_uint64_t len);
|
static zip_int64_t _zip_stdio_op_write(zip_source_file_context_t *ctx, const void *data, zip_uint64_t len);
|
||||||
|
static FILE *_zip_fopen_close_on_exec(const char *name, bool writeable);
|
||||||
|
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
static zip_source_file_operations_t ops_stdio_named = {
|
static zip_source_file_operations_t ops_stdio_named = {
|
||||||
@@ -300,11 +301,12 @@ static int create_temp_file(zip_source_file_context_t *ctx, bool create_file) {
|
|||||||
mode = -1;
|
mode = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((temp = (char *)malloc(strlen(ctx->fname) + 13)) == NULL) {
|
size_t temp_size = strlen(ctx->fname) + 13;
|
||||||
|
if ((temp = (char *)malloc(temp_size)) == NULL) {
|
||||||
zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
|
zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
sprintf(temp, "%s.XXXXXX.part", ctx->fname);
|
snprintf_s(temp, temp_size, "%s.XXXXXX.part", ctx->fname);
|
||||||
end = temp + strlen(temp) - 5;
|
end = temp + strlen(temp) - 5;
|
||||||
start = end - 6;
|
start = end - 6;
|
||||||
|
|
||||||
@@ -359,3 +361,32 @@ static int create_temp_file(zip_source_file_context_t *ctx, bool create_file) {
|
|||||||
|
|
||||||
return create_file ? fd : 0;
|
return create_file ? fd : 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_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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -73,4 +73,12 @@ zip_int64_t _zip_win32_op_tell(zip_source_file_context_t *ctx, void *f);
|
|||||||
bool _zip_filetime_to_time_t(FILETIME ft, time_t *t);
|
bool _zip_filetime_to_time_t(FILETIME ft, time_t *t);
|
||||||
int _zip_win32_error_to_errno(DWORD win32err);
|
int _zip_win32_error_to_errno(DWORD win32err);
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
#define DONT_WARN_INCOMPATIBLE_FN_PTR_BEGIN _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wincompatible-function-pointer-types\"")
|
||||||
|
#define DONT_WARN_INCOMPATIBLE_FN_PTR_END _Pragma("GCC diagnostic pop")
|
||||||
|
#else
|
||||||
|
#define DONT_WARN_INCOMPATIBLE_FN_PTR_BEGIN
|
||||||
|
#define DONT_WARN_INCOMPATIBLE_FN_PTR_END
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* _HAD_ZIP_SOURCE_FILE_WIN32_H */
|
#endif /* _HAD_ZIP_SOURCE_FILE_WIN32_H */
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ static char *ansi_allocate_tempname(const char *name, size_t extra_chars, size_t
|
|||||||
static void ansi_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i);
|
static void ansi_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i);
|
||||||
|
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
DONT_WARN_INCOMPATIBLE_FN_PTR_BEGIN
|
||||||
|
|
||||||
zip_win32_file_operations_t ops_ansi = {
|
zip_win32_file_operations_t ops_ansi = {
|
||||||
ansi_allocate_tempname,
|
ansi_allocate_tempname,
|
||||||
@@ -50,6 +51,7 @@ zip_win32_file_operations_t ops_ansi = {
|
|||||||
strdup
|
strdup
|
||||||
};
|
};
|
||||||
|
|
||||||
|
DONT_WARN_INCOMPATIBLE_FN_PTR_END
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
|
|
||||||
ZIP_EXTERN zip_source_t *
|
ZIP_EXTERN zip_source_t *
|
||||||
@@ -81,5 +83,5 @@ ansi_allocate_tempname(const char *name, size_t extra_chars, size_t *lengthp) {
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
ansi_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i) {
|
ansi_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i) {
|
||||||
snprintf(buf, len, "%s.%08x", name, i);
|
snprintf_s(buf, len, "%s.%08x", name, i);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,7 +99,6 @@ _zip_win32_named_op_create_temp_output(zip_source_file_context_t *ctx) {
|
|||||||
|
|
||||||
zip_uint32_t value, i;
|
zip_uint32_t value, i;
|
||||||
HANDLE th = INVALID_HANDLE_VALUE;
|
HANDLE th = INVALID_HANDLE_VALUE;
|
||||||
void *temp = NULL;
|
|
||||||
PSECURITY_DESCRIPTOR psd = NULL;
|
PSECURITY_DESCRIPTOR psd = NULL;
|
||||||
PSECURITY_ATTRIBUTES psa = NULL;
|
PSECURITY_ATTRIBUTES psa = NULL;
|
||||||
SECURITY_ATTRIBUTES sa;
|
SECURITY_ATTRIBUTES sa;
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ static void utf16_make_tempname(char *buf, size_t len, const char *name, zip_uin
|
|||||||
static char *utf16_strdup(const char *string);
|
static char *utf16_strdup(const char *string);
|
||||||
|
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
DONT_WARN_INCOMPATIBLE_FN_PTR_BEGIN
|
||||||
|
|
||||||
zip_win32_file_operations_t ops_utf16 = {
|
zip_win32_file_operations_t ops_utf16 = {
|
||||||
utf16_allocate_tempname,
|
utf16_allocate_tempname,
|
||||||
@@ -52,6 +53,7 @@ zip_win32_file_operations_t ops_utf16 = {
|
|||||||
utf16_strdup
|
utf16_strdup
|
||||||
};
|
};
|
||||||
|
|
||||||
|
DONT_WARN_INCOMPATIBLE_FN_PTR_END
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
|
|
||||||
ZIP_EXTERN zip_source_t *
|
ZIP_EXTERN zip_source_t *
|
||||||
@@ -101,7 +103,7 @@ static HANDLE __stdcall utf16_create_file(const char *name, DWORD access, DWORD
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
utf16_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i) {
|
utf16_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i) {
|
||||||
_snwprintf((wchar_t *)buf, len, L"%s.%08x", (const wchar_t *)name, i);
|
_snwprintf_s((wchar_t *)buf, len, len, L"%s.%08x", (const wchar_t *)name, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -57,10 +57,11 @@ zip_source_function_create(zip_source_callback zcb, void *ud, zip_error_t *error
|
|||||||
zs->cb.f = zcb;
|
zs->cb.f = zcb;
|
||||||
zs->ud = ud;
|
zs->ud = ud;
|
||||||
|
|
||||||
zs->supports = zcb(ud, NULL, 0, ZIP_SOURCE_SUPPORTS) | zip_source_make_command_bitmap(ZIP_SOURCE_SUPPORTS, -1);
|
zs->supports = zcb(ud, NULL, 0, ZIP_SOURCE_SUPPORTS);
|
||||||
if (zs->supports < 0) {
|
if (zs->supports < 0) {
|
||||||
zs->supports = ZIP_SOURCE_SUPPORTS_READABLE;
|
zs->supports = ZIP_SOURCE_SUPPORTS_READABLE;
|
||||||
}
|
}
|
||||||
|
zs->supports |= zip_source_make_command_bitmap(ZIP_SOURCE_SUPPORTS, -1);
|
||||||
|
|
||||||
return zs;
|
return zs;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,8 +60,10 @@ zip_source_get_file_attributes(zip_source_t *src, zip_file_attributes_t *attribu
|
|||||||
if (ZIP_SOURCE_IS_LAYERED(src)) {
|
if (ZIP_SOURCE_IS_LAYERED(src)) {
|
||||||
zip_file_attributes_t lower_attributes;
|
zip_file_attributes_t lower_attributes;
|
||||||
|
|
||||||
|
zip_file_attributes_init(&lower_attributes);
|
||||||
|
|
||||||
if (zip_source_get_file_attributes(src->src, &lower_attributes) < 0) {
|
if (zip_source_get_file_attributes(src->src, &lower_attributes) < 0) {
|
||||||
_zip_error_set_from_source(&src->error, src->src);
|
zip_error_set_from_source(&src->error, src->src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,19 +49,27 @@ zip_source_layered(zip_t *za, zip_source_t *src, zip_source_layered_callback cb,
|
|||||||
zip_source_t *
|
zip_source_t *
|
||||||
zip_source_layered_create(zip_source_t *src, zip_source_layered_callback cb, void *ud, zip_error_t *error) {
|
zip_source_layered_create(zip_source_t *src, zip_source_layered_callback cb, void *ud, zip_error_t *error) {
|
||||||
zip_source_t *zs;
|
zip_source_t *zs;
|
||||||
|
zip_int64_t lower_supports, supports;
|
||||||
|
|
||||||
if ((zs = _zip_source_new(error)) == NULL)
|
lower_supports = zip_source_supports(src);
|
||||||
|
supports = cb(src, ud, &lower_supports, sizeof(lower_supports), ZIP_SOURCE_SUPPORTS);
|
||||||
|
if (supports < 0) {
|
||||||
|
zip_error_set(error,ZIP_ER_INVAL, 0); /* Initialize in case cb doesn't return valid error. */
|
||||||
|
cb(src, ud, error, sizeof(*error), ZIP_SOURCE_ERROR);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((zs = _zip_source_new(error)) == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
zip_source_keep(src);
|
|
||||||
zs->src = src;
|
zs->src = src;
|
||||||
zs->cb.l = cb;
|
zs->cb.l = cb;
|
||||||
zs->ud = ud;
|
zs->ud = ud;
|
||||||
|
zs->supports = supports;
|
||||||
|
|
||||||
zs->supports = cb(src, ud, NULL, 0, ZIP_SOURCE_SUPPORTS);
|
/* Layered sources can't support writing, since we currently have no use case. If we want to revisit this, we have to define how the two sources interact. */
|
||||||
if (zs->supports < 0) {
|
zs->supports &= ~(ZIP_SOURCE_SUPPORTS_WRITABLE & ~ZIP_SOURCE_SUPPORTS_SEEKABLE);
|
||||||
zs->supports = ZIP_SOURCE_SUPPORTS_READABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return zs;
|
return zs;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ zip_source_open(zip_source_t *src) {
|
|||||||
else {
|
else {
|
||||||
if (ZIP_SOURCE_IS_LAYERED(src)) {
|
if (ZIP_SOURCE_IS_LAYERED(src)) {
|
||||||
if (zip_source_open(src->src) < 0) {
|
if (zip_source_open(src->src) < 0) {
|
||||||
_zip_error_set_from_source(&src->error, src->src);
|
zip_error_set_from_source(&src->error, src->src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
78
src/Common/libzip/zip_source_pass_to_lower_layer.c
Normal file
78
src/Common/libzip/zip_source_pass_to_lower_layer.c
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
zip_source_pass_to_lower_layer.c -- pass command to lower layer
|
||||||
|
Copyright (C) 2022 Dieter Baron and Thomas Klausner
|
||||||
|
|
||||||
|
This file is part of libzip, a library to manipulate ZIP archives.
|
||||||
|
The authors can be contacted at <info@libzip.org>
|
||||||
|
|
||||||
|
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_int64_t zip_source_pass_to_lower_layer(zip_source_t *src, void *data, zip_uint64_t length, zip_source_cmd_t command) {
|
||||||
|
switch (command) {
|
||||||
|
case ZIP_SOURCE_OPEN:
|
||||||
|
case ZIP_SOURCE_CLOSE:
|
||||||
|
case ZIP_SOURCE_FREE:
|
||||||
|
case ZIP_SOURCE_GET_FILE_ATTRIBUTES:
|
||||||
|
case ZIP_SOURCE_SUPPORTS_REOPEN:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case ZIP_SOURCE_STAT:
|
||||||
|
return sizeof(zip_stat_t);
|
||||||
|
|
||||||
|
case ZIP_SOURCE_ACCEPT_EMPTY:
|
||||||
|
case ZIP_SOURCE_ERROR:
|
||||||
|
case ZIP_SOURCE_READ:
|
||||||
|
case ZIP_SOURCE_SEEK:
|
||||||
|
case ZIP_SOURCE_TELL:
|
||||||
|
return _zip_source_call(src, data, length, command);
|
||||||
|
|
||||||
|
|
||||||
|
case ZIP_SOURCE_BEGIN_WRITE:
|
||||||
|
case ZIP_SOURCE_BEGIN_WRITE_CLONING:
|
||||||
|
case ZIP_SOURCE_COMMIT_WRITE:
|
||||||
|
case ZIP_SOURCE_REMOVE:
|
||||||
|
case ZIP_SOURCE_ROLLBACK_WRITE:
|
||||||
|
case ZIP_SOURCE_SEEK_WRITE:
|
||||||
|
case ZIP_SOURCE_TELL_WRITE:
|
||||||
|
case ZIP_SOURCE_WRITE:
|
||||||
|
zip_error_set(&src->error, ZIP_ER_OPNOTSUPP, 0);
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
case ZIP_SOURCE_SUPPORTS:
|
||||||
|
if (length < sizeof(zip_int64_t)) {
|
||||||
|
zip_error_set(&src->error, ZIP_ER_INTERNAL, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return *(zip_int64_t *)data;
|
||||||
|
|
||||||
|
default:
|
||||||
|
zip_error_set(&src->error, ZIP_ER_OPNOTSUPP, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -85,7 +85,7 @@ decrypt_header(zip_source_t *src, struct trad_pkware *ctx) {
|
|||||||
bool ok = false;
|
bool ok = false;
|
||||||
|
|
||||||
if ((n = zip_source_read(src, header, ZIP_CRYPTO_PKWARE_HEADERLEN)) < 0) {
|
if ((n = zip_source_read(src, header, ZIP_CRYPTO_PKWARE_HEADERLEN)) < 0) {
|
||||||
_zip_error_set_from_source(&ctx->error, src);
|
zip_error_set_from_source(&ctx->error, src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,7 +147,7 @@ pkware_decrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_so
|
|||||||
|
|
||||||
case ZIP_SOURCE_READ:
|
case ZIP_SOURCE_READ:
|
||||||
if ((n = zip_source_read(src, data, len)) < 0) {
|
if ((n = zip_source_read(src, data, len)) < 0) {
|
||||||
_zip_error_set_from_source(&ctx->error, src);
|
zip_error_set_from_source(&ctx->error, src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,7 +172,7 @@ pkware_decrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_so
|
|||||||
}
|
}
|
||||||
|
|
||||||
case ZIP_SOURCE_SUPPORTS:
|
case ZIP_SOURCE_SUPPORTS:
|
||||||
return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, -1);
|
return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, ZIP_SOURCE_SUPPORTS_REOPEN, -1);
|
||||||
|
|
||||||
case ZIP_SOURCE_ERROR:
|
case ZIP_SOURCE_ERROR:
|
||||||
return zip_error_to_data(&ctx->error, data, len);
|
return zip_error_to_data(&ctx->error, data, len);
|
||||||
@@ -182,8 +182,7 @@ pkware_decrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_so
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
|
return zip_source_pass_to_lower_layer(src, data, len, cmd);
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ encrypt_header(zip_source_t *src, struct trad_pkware *ctx) {
|
|||||||
zip_uint8_t *header;
|
zip_uint8_t *header;
|
||||||
|
|
||||||
if (zip_source_stat(src, &st) != 0) {
|
if (zip_source_stat(src, &st) != 0) {
|
||||||
_zip_error_set_from_source(&ctx->error, src);
|
zip_error_set_from_source(&ctx->error, src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,7 +156,7 @@ pkware_encrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t length, zip
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((n = zip_source_read(src, data, length)) < 0) {
|
if ((n = zip_source_read(src, data, length)) < 0) {
|
||||||
_zip_error_set_from_source(&ctx->error, src);
|
zip_error_set_from_source(&ctx->error, src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,8 +209,7 @@ pkware_encrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t length, zip
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
|
return zip_source_pass_to_lower_layer(src, data, length, cmd);
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,11 @@
|
|||||||
|
|
||||||
int
|
int
|
||||||
zip_source_remove(zip_source_t *src) {
|
zip_source_remove(zip_source_t *src) {
|
||||||
|
if (ZIP_SOURCE_IS_LAYERED(src)) {
|
||||||
|
zip_error_set(&src->error, ZIP_ER_OPNOTSUPP, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (src->write_state == ZIP_SOURCE_WRITE_REMOVED) {
|
if (src->write_state == ZIP_SOURCE_WRITE_REMOVED) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,10 @@
|
|||||||
|
|
||||||
ZIP_EXTERN void
|
ZIP_EXTERN void
|
||||||
zip_source_rollback_write(zip_source_t *src) {
|
zip_source_rollback_write(zip_source_t *src) {
|
||||||
|
if (ZIP_SOURCE_IS_LAYERED(src)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (src->write_state != ZIP_SOURCE_WRITE_OPEN && src->write_state != ZIP_SOURCE_WRITE_FAILED) {
|
if (src->write_state != ZIP_SOURCE_WRITE_OPEN && src->write_state != ZIP_SOURCE_WRITE_FAILED) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,11 @@ ZIP_EXTERN int
|
|||||||
zip_source_seek_write(zip_source_t *src, zip_int64_t offset, int whence) {
|
zip_source_seek_write(zip_source_t *src, zip_int64_t offset, int whence) {
|
||||||
zip_source_args_seek_t args;
|
zip_source_args_seek_t args;
|
||||||
|
|
||||||
|
if (ZIP_SOURCE_IS_LAYERED(src)) {
|
||||||
|
zip_error_set(&src->error, ZIP_ER_OPNOTSUPP, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ZIP_SOURCE_IS_OPEN_WRITING(src) || (whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END)) {
|
if (!ZIP_SOURCE_IS_OPEN_WRITING(src) || (whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END)) {
|
||||||
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
|
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -45,11 +45,15 @@ zip_source_stat(zip_source_t *src, zip_stat_t *st) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (src->write_state == ZIP_SOURCE_WRITE_REMOVED) {
|
||||||
|
zip_error_set(&src->error, ZIP_ER_READ, ENOENT);
|
||||||
|
}
|
||||||
|
|
||||||
zip_stat_init(st);
|
zip_stat_init(st);
|
||||||
|
|
||||||
if (ZIP_SOURCE_IS_LAYERED(src)) {
|
if (ZIP_SOURCE_IS_LAYERED(src)) {
|
||||||
if (zip_source_stat(src->src, st) < 0) {
|
if (zip_source_stat(src->src, st) < 0) {
|
||||||
_zip_error_set_from_source(&src->error, src->src);
|
zip_error_set_from_source(&src->error, src->src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,10 @@ zip_source_supports(zip_source_t *src) {
|
|||||||
return src->supports;
|
return src->supports;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
zip_source_supports_reopen(zip_source_t *src) {
|
||||||
|
return (zip_source_supports(src) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SUPPORTS_REOPEN)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
ZIP_EXTERN zip_int64_t
|
ZIP_EXTERN zip_int64_t
|
||||||
zip_source_make_command_bitmap(zip_source_cmd_t cmd0, ...) {
|
zip_source_make_command_bitmap(zip_source_cmd_t cmd0, ...) {
|
||||||
@@ -63,3 +67,8 @@ zip_source_make_command_bitmap(zip_source_cmd_t cmd0, ...) {
|
|||||||
|
|
||||||
return bitmap;
|
return bitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ZIP_EXTERN int zip_source_is_seekable(zip_source_t *src) {
|
||||||
|
return ZIP_SOURCE_CHECK_SUPPORTED(zip_source_supports(src->src), ZIP_SOURCE_SEEK);
|
||||||
|
}
|
||||||
|
|||||||
@@ -37,6 +37,11 @@
|
|||||||
|
|
||||||
ZIP_EXTERN zip_int64_t
|
ZIP_EXTERN zip_int64_t
|
||||||
zip_source_tell_write(zip_source_t *src) {
|
zip_source_tell_write(zip_source_t *src) {
|
||||||
|
if (ZIP_SOURCE_IS_LAYERED(src)) {
|
||||||
|
zip_error_set(&src->error, ZIP_ER_OPNOTSUPP, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ZIP_SOURCE_IS_OPEN_WRITING(src)) {
|
if (!ZIP_SOURCE_IS_OPEN_WRITING(src)) {
|
||||||
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
|
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ struct window {
|
|||||||
zip_uint64_t offset; /* offset in src for next read */
|
zip_uint64_t offset; /* offset in src for next read */
|
||||||
|
|
||||||
zip_stat_t stat;
|
zip_stat_t stat;
|
||||||
|
zip_uint64_t stat_invalid;
|
||||||
zip_file_attributes_t attributes;
|
zip_file_attributes_t attributes;
|
||||||
zip_error_t error;
|
zip_error_t error;
|
||||||
zip_int64_t supports;
|
zip_int64_t supports;
|
||||||
@@ -60,12 +61,13 @@ static zip_int64_t window_read(zip_source_t *, void *, void *, zip_uint64_t, zip
|
|||||||
|
|
||||||
ZIP_EXTERN zip_source_t *
|
ZIP_EXTERN zip_source_t *
|
||||||
zip_source_window_create(zip_source_t *src, zip_uint64_t start, zip_int64_t len, zip_error_t *error) {
|
zip_source_window_create(zip_source_t *src, zip_uint64_t start, zip_int64_t len, zip_error_t *error) {
|
||||||
return _zip_source_window_new(src, start, len, NULL, 0, NULL, 0, error);
|
return _zip_source_window_new(src, start, len, NULL, 0, NULL, NULL, 0, false, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
zip_source_t *
|
zip_source_t *
|
||||||
_zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_int64_t length, zip_stat_t *st, zip_file_attributes_t *attributes, zip_t *source_archive, zip_uint64_t source_index, zip_error_t *error) {
|
_zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_int64_t length, zip_stat_t *st, zip_uint64_t st_invalid, zip_file_attributes_t *attributes, zip_t *source_archive, zip_uint64_t source_index, bool take_ownership, zip_error_t *error) {
|
||||||
|
zip_source_t* window_source;
|
||||||
struct window *ctx;
|
struct window *ctx;
|
||||||
|
|
||||||
if (src == NULL || length < -1 || (source_archive == NULL && source_index != 0)) {
|
if (src == NULL || length < -1 || (source_archive == NULL && source_index != 0)) {
|
||||||
@@ -94,8 +96,9 @@ _zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_int64_t length
|
|||||||
ctx->end_valid = true;
|
ctx->end_valid = true;
|
||||||
}
|
}
|
||||||
zip_stat_init(&ctx->stat);
|
zip_stat_init(&ctx->stat);
|
||||||
|
ctx->stat_invalid = st_invalid;
|
||||||
if (attributes != NULL) {
|
if (attributes != NULL) {
|
||||||
memcpy(&ctx->attributes, attributes, sizeof(ctx->attributes));
|
(void)memcpy_s(&ctx->attributes, sizeof(ctx->attributes), attributes, sizeof(ctx->attributes));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
zip_file_attributes_init(&ctx->attributes);
|
zip_file_attributes_init(&ctx->attributes);
|
||||||
@@ -103,7 +106,7 @@ _zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_int64_t length
|
|||||||
ctx->source_archive = source_archive;
|
ctx->source_archive = source_archive;
|
||||||
ctx->source_index = source_index;
|
ctx->source_index = source_index;
|
||||||
zip_error_init(&ctx->error);
|
zip_error_init(&ctx->error);
|
||||||
ctx->supports = (zip_source_supports(src) & ZIP_SOURCE_SUPPORTS_SEEKABLE) | (zip_source_make_command_bitmap(ZIP_SOURCE_GET_FILE_ATTRIBUTES, ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1));
|
ctx->supports = (zip_source_supports(src) & (ZIP_SOURCE_SUPPORTS_SEEKABLE | ZIP_SOURCE_SUPPORTS_REOPEN)) | (zip_source_make_command_bitmap(ZIP_SOURCE_GET_FILE_ATTRIBUTES, ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, ZIP_SOURCE_FREE, -1));
|
||||||
ctx->needs_seek = (ctx->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK)) ? true : false;
|
ctx->needs_seek = (ctx->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK)) ? true : false;
|
||||||
|
|
||||||
if (st) {
|
if (st) {
|
||||||
@@ -113,7 +116,11 @@ _zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_int64_t length
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return zip_source_layered_create(src, window_read, ctx, error);
|
window_source = zip_source_layered_create(src, window_read, ctx, error);
|
||||||
|
if (window_source != NULL && !take_ownership) {
|
||||||
|
zip_source_keep(src);
|
||||||
|
}
|
||||||
|
return window_source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -182,7 +189,7 @@ window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_sou
|
|||||||
for (n = 0; n < ctx->start; n += (zip_uint64_t)ret) {
|
for (n = 0; n < ctx->start; n += (zip_uint64_t)ret) {
|
||||||
i = (ctx->start - n > BUFSIZE ? BUFSIZE : ctx->start - n);
|
i = (ctx->start - n > BUFSIZE ? BUFSIZE : ctx->start - n);
|
||||||
if ((ret = zip_source_read(src, b, i)) < 0) {
|
if ((ret = zip_source_read(src, b, i)) < 0) {
|
||||||
_zip_error_set_from_source(&ctx->error, src);
|
zip_error_set_from_source(&ctx->error, src);
|
||||||
byte_array_fini(b);
|
byte_array_fini(b);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -210,7 +217,7 @@ window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_sou
|
|||||||
|
|
||||||
if (ctx->needs_seek) {
|
if (ctx->needs_seek) {
|
||||||
if (zip_source_seek(src, (zip_int64_t)ctx->offset, SEEK_SET) < 0) {
|
if (zip_source_seek(src, (zip_int64_t)ctx->offset, SEEK_SET) < 0) {
|
||||||
_zip_error_set_from_source(&ctx->error, src);
|
zip_error_set_from_source(&ctx->error, src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -241,12 +248,12 @@ window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_sou
|
|||||||
}
|
}
|
||||||
if (args->whence == SEEK_END) {
|
if (args->whence == SEEK_END) {
|
||||||
if (zip_source_seek(src, args->offset, args->whence) < 0) {
|
if (zip_source_seek(src, args->offset, args->whence) < 0) {
|
||||||
_zip_error_set_from_source(&ctx->error, src);
|
zip_error_set_from_source(&ctx->error, src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
new_offset = zip_source_tell(src);
|
new_offset = zip_source_tell(src);
|
||||||
if (new_offset < 0) {
|
if (new_offset < 0) {
|
||||||
_zip_error_set_from_source(&ctx->error, src);
|
zip_error_set_from_source(&ctx->error, src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if ((zip_uint64_t)new_offset < ctx->start) {
|
if ((zip_uint64_t)new_offset < ctx->start) {
|
||||||
@@ -277,6 +284,19 @@ window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_sou
|
|||||||
if (_zip_stat_merge(st, &ctx->stat, &ctx->error) < 0) {
|
if (_zip_stat_merge(st, &ctx->stat, &ctx->error) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(ctx->stat.valid & ZIP_STAT_SIZE)) {
|
||||||
|
if (ctx->end_valid) {
|
||||||
|
st->valid |= ZIP_STAT_SIZE;
|
||||||
|
st->size = ctx->end - ctx->start;
|
||||||
|
}
|
||||||
|
else if (st->valid & ZIP_STAT_SIZE) {
|
||||||
|
st->size -= ctx->start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
st->valid &= ~ctx->stat_invalid;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,7 +306,7 @@ window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_sou
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(data, &ctx->attributes, sizeof(ctx->attributes));
|
(void)memcpy_s(data, sizeof(ctx->attributes), &ctx->attributes, sizeof(ctx->attributes));
|
||||||
return sizeof(ctx->attributes);
|
return sizeof(ctx->attributes);
|
||||||
|
|
||||||
case ZIP_SOURCE_SUPPORTS:
|
case ZIP_SOURCE_SUPPORTS:
|
||||||
@@ -296,8 +316,7 @@ window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_sou
|
|||||||
return (zip_int64_t)(ctx->offset - ctx->start);
|
return (zip_int64_t)(ctx->offset - ctx->start);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
|
return zip_source_pass_to_lower_layer(src, data, len, cmd);
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "zipint.h"
|
#include "zipint.h"
|
||||||
|
#include "zip_crypto.h"
|
||||||
|
|
||||||
struct winzip_aes {
|
struct winzip_aes {
|
||||||
char *password;
|
char *password;
|
||||||
@@ -72,7 +73,7 @@ zip_source_winzip_aes_decode(zip_t *za, zip_source_t *src, zip_uint16_t encrypti
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (zip_source_stat(src, &st) != 0) {
|
if (zip_source_stat(src, &st) != 0) {
|
||||||
_zip_error_set_from_source(&za->error, src);
|
zip_error_set_from_source(&za->error, src);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +108,7 @@ decrypt_header(zip_source_t *src, struct winzip_aes *ctx) {
|
|||||||
|
|
||||||
headerlen = WINZIP_AES_PASSWORD_VERIFY_LENGTH + SALT_LENGTH(ctx->encryption_method);
|
headerlen = WINZIP_AES_PASSWORD_VERIFY_LENGTH + SALT_LENGTH(ctx->encryption_method);
|
||||||
if ((n = zip_source_read(src, header, headerlen)) < 0) {
|
if ((n = zip_source_read(src, header, headerlen)) < 0) {
|
||||||
_zip_error_set_from_source(&ctx->error, src);
|
zip_error_set_from_source(&ctx->error, src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,9 +132,9 @@ decrypt_header(zip_source_t *src, struct winzip_aes *ctx) {
|
|||||||
|
|
||||||
static bool
|
static bool
|
||||||
verify_hmac(zip_source_t *src, struct winzip_aes *ctx) {
|
verify_hmac(zip_source_t *src, struct winzip_aes *ctx) {
|
||||||
unsigned char computed[SHA1_LENGTH], from_file[HMAC_LENGTH];
|
unsigned char computed[ZIP_CRYPTO_SHA1_LENGTH], from_file[HMAC_LENGTH];
|
||||||
if (zip_source_read(src, from_file, HMAC_LENGTH) < HMAC_LENGTH) {
|
if (zip_source_read(src, from_file, HMAC_LENGTH) < HMAC_LENGTH) {
|
||||||
_zip_error_set_from_source(&ctx->error, src);
|
zip_error_set_from_source(&ctx->error, src);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,7 +182,7 @@ winzip_aes_decrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zi
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((n = zip_source_read(src, data, len)) < 0) {
|
if ((n = zip_source_read(src, data, len)) < 0) {
|
||||||
_zip_error_set_from_source(&ctx->error, src);
|
zip_error_set_from_source(&ctx->error, src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ctx->current_position += (zip_uint64_t)n;
|
ctx->current_position += (zip_uint64_t)n;
|
||||||
@@ -211,7 +212,7 @@ winzip_aes_decrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zi
|
|||||||
}
|
}
|
||||||
|
|
||||||
case ZIP_SOURCE_SUPPORTS:
|
case ZIP_SOURCE_SUPPORTS:
|
||||||
return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, -1);
|
return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, ZIP_SOURCE_SUPPORTS_REOPEN, -1);
|
||||||
|
|
||||||
case ZIP_SOURCE_ERROR:
|
case ZIP_SOURCE_ERROR:
|
||||||
return zip_error_to_data(&ctx->error, data, len);
|
return zip_error_to_data(&ctx->error, data, len);
|
||||||
@@ -221,8 +222,7 @@ winzip_aes_decrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zi
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
|
return zip_source_pass_to_lower_layer(src, data, len, cmd);
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,13 +36,13 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "zipint.h"
|
#include "zipint.h"
|
||||||
|
#include "zip_crypto.h"
|
||||||
|
|
||||||
struct winzip_aes {
|
struct winzip_aes {
|
||||||
char *password;
|
char *password;
|
||||||
zip_uint16_t encryption_method;
|
zip_uint16_t encryption_method;
|
||||||
|
|
||||||
zip_uint8_t data[ZIP_MAX(WINZIP_AES_MAX_HEADER_LENGTH, SHA1_LENGTH)];
|
zip_uint8_t data[ZIP_MAX(WINZIP_AES_MAX_HEADER_LENGTH, ZIP_CRYPTO_SHA1_LENGTH)];
|
||||||
zip_buffer_t *buffer;
|
zip_buffer_t *buffer;
|
||||||
|
|
||||||
zip_winzip_aes_t *aes_ctx;
|
zip_winzip_aes_t *aes_ctx;
|
||||||
@@ -139,7 +139,7 @@ winzip_aes_encrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t length,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((ret = zip_source_read(src, data, length)) < 0) {
|
if ((ret = zip_source_read(src, data, length)) < 0) {
|
||||||
_zip_error_set_from_source(&ctx->error, src);
|
zip_error_set_from_source(&ctx->error, src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,8 +207,7 @@ winzip_aes_encrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t length,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
|
return zip_source_pass_to_lower_layer(src, data, length, cmd);
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define _ZIP_COMPILING_DEPRECATED
|
||||||
#include "zipint.h"
|
#include "zipint.h"
|
||||||
|
|
||||||
ZIP_EXTERN zip_source_t *zip_source_zip_create(zip_t *srcza, zip_uint64_t srcidx, zip_flags_t flags, zip_uint64_t start, zip_int64_t len, zip_error_t *error) {
|
ZIP_EXTERN zip_source_t *zip_source_zip_create(zip_t *srcza, zip_uint64_t srcidx, zip_flags_t flags, zip_uint64_t start, zip_int64_t len, zip_error_t *error) {
|
||||||
@@ -42,15 +43,18 @@ ZIP_EXTERN zip_source_t *zip_source_zip_create(zip_t *srcza, zip_uint64_t srcidx
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len == -1)
|
if (len == 0) {
|
||||||
len = 0;
|
len = -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (start == 0 && len == 0)
|
if (start == 0 && len == -1) {
|
||||||
flags |= ZIP_FL_COMPRESSED;
|
flags |= ZIP_FL_COMPRESSED;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
flags &= ~ZIP_FL_COMPRESSED;
|
flags &= ~ZIP_FL_COMPRESSED;
|
||||||
|
}
|
||||||
|
|
||||||
return _zip_source_zip_new(srcza, srcidx, flags, start, (zip_uint64_t)len, NULL, error);
|
return zip_source_zip_file_create(srcza, srcidx, flags, start, len, NULL, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -38,52 +38,98 @@
|
|||||||
|
|
||||||
static void _zip_file_attributes_from_dirent(zip_file_attributes_t *attributes, zip_dirent_t *de);
|
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 *srcza, zip_uint64_t srcidx, zip_flags_t flags, zip_uint64_t start, zip_uint64_t len, const char *password, zip_error_t *error) {
|
ZIP_EXTERN zip_source_t *zip_source_zip_file(zip_t* za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t flags, zip_uint64_t start, zip_int64_t len, const char *password) {
|
||||||
|
return zip_source_zip_file_create(srcza, srcidx, flags, start, len, password, &za->error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ZIP_EXTERN zip_source_t *zip_source_zip_file_create(zip_t *srcza, zip_uint64_t srcidx, zip_flags_t flags, zip_uint64_t start, zip_int64_t len, const char *password, zip_error_t *error) {
|
||||||
|
/* TODO: We need to make sure that the returned source is invalidated when srcza is closed. */
|
||||||
zip_source_t *src, *s2;
|
zip_source_t *src, *s2;
|
||||||
zip_stat_t st;
|
zip_stat_t st;
|
||||||
zip_file_attributes_t attributes;
|
zip_file_attributes_t attributes;
|
||||||
zip_dirent_t *de;
|
zip_dirent_t *de;
|
||||||
bool partial_data, needs_crc, needs_decrypt, needs_decompress;
|
bool partial_data, needs_crc, encrypted, needs_decrypt, compressed, needs_decompress, changed_data, have_size, have_comp_size;
|
||||||
|
zip_flags_t stat_flags;
|
||||||
|
zip_int64_t data_len;
|
||||||
|
bool take_ownership = false;
|
||||||
|
|
||||||
if (srcza == NULL || srcidx >= srcza->nentry || len > ZIP_INT64_MAX) {
|
if (srcza == NULL || srcidx >= srcza->nentry || len < -1) {
|
||||||
zip_error_set(error, ZIP_ER_INVAL, 0);
|
zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & ZIP_FL_UNCHANGED) == 0 && (ZIP_ENTRY_DATA_CHANGED(srcza->entry + srcidx) || srcza->entry[srcidx].deleted)) {
|
|
||||||
zip_error_set(error, ZIP_ER_CHANGED, 0);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (zip_stat_index(srcza, srcidx, flags | ZIP_FL_UNCHANGED, &st) < 0) {
|
|
||||||
zip_error_set(error, ZIP_ER_INTERNAL, 0);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & ZIP_FL_ENCRYPTED) {
|
if (flags & ZIP_FL_ENCRYPTED) {
|
||||||
flags |= ZIP_FL_COMPRESSED;
|
flags |= ZIP_FL_COMPRESSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((start > 0 || len > 0) && (flags & ZIP_FL_COMPRESSED)) {
|
changed_data = false;
|
||||||
|
if ((flags & ZIP_FL_UNCHANGED) == 0) {
|
||||||
|
zip_entry_t *entry = srcza->entry + srcidx;
|
||||||
|
if (ZIP_ENTRY_DATA_CHANGED(entry)) {
|
||||||
|
if ((flags & ZIP_FL_COMPRESSED) || !zip_source_supports_reopen(entry->source)) {
|
||||||
|
zip_error_set(error, ZIP_ER_CHANGED, 0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
changed_data = true;
|
||||||
|
}
|
||||||
|
else if (entry->deleted) {
|
||||||
|
zip_error_set(error, ZIP_ER_CHANGED, 0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stat_flags = flags;
|
||||||
|
if (!changed_data) {
|
||||||
|
stat_flags |= ZIP_FL_UNCHANGED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zip_stat_index(srcza, srcidx, stat_flags, &st) < 0) {
|
||||||
|
zip_error_set(error, ZIP_ER_INTERNAL, 0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((start > 0 || len >= 0) && (flags & ZIP_FL_COMPRESSED)) {
|
||||||
zip_error_set(error, ZIP_ER_INVAL, 0);
|
zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
have_size = (st.valid & ZIP_STAT_SIZE) != 0;
|
||||||
/* overflow or past end of file */
|
/* overflow or past end of file */
|
||||||
if ((start > 0 || len > 0) && (start + len < start || start + len > st.size)) {
|
if (len >= 0 && ((start > 0 && start + len < start) || (have_size && start + len > st.size))) {
|
||||||
zip_error_set(error, ZIP_ER_INVAL, 0);
|
zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len == 0) {
|
if (len == -1) {
|
||||||
len = st.size - start;
|
if (have_size) {
|
||||||
|
if (st.size - start > ZIP_INT64_MAX) {
|
||||||
|
zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
data_len = (zip_int64_t)(st.size - start);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
data_len = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
data_len = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
partial_data = len < st.size;
|
if (have_size) {
|
||||||
needs_decrypt = ((flags & ZIP_FL_ENCRYPTED) == 0) && (st.encryption_method != ZIP_EM_NONE);
|
partial_data = (zip_uint64_t)(data_len) < st.size;
|
||||||
needs_decompress = ((flags & ZIP_FL_COMPRESSED) == 0) && (st.comp_method != ZIP_CM_STORE);
|
}
|
||||||
|
else {
|
||||||
|
partial_data = true;
|
||||||
|
}
|
||||||
|
encrypted = (st.valid & ZIP_STAT_ENCRYPTION_METHOD) && (st.encryption_method != ZIP_EM_NONE);
|
||||||
|
needs_decrypt = ((flags & ZIP_FL_ENCRYPTED) == 0) && encrypted;
|
||||||
|
compressed = (st.valid & ZIP_STAT_COMP_METHOD) && (st.comp_method != ZIP_CM_STORE);
|
||||||
|
needs_decompress = ((flags & ZIP_FL_COMPRESSED) == 0) && compressed;
|
||||||
/* when reading the whole file, check for CRC errors */
|
/* when reading the whole file, check for CRC errors */
|
||||||
needs_crc = ((flags & ZIP_FL_COMPRESSED) == 0 || st.comp_method == ZIP_CM_STORE) && !partial_data;
|
needs_crc = ((flags & ZIP_FL_COMPRESSED) == 0 || !compressed) && !partial_data && (st.valid & ZIP_STAT_CRC) != 0;
|
||||||
|
|
||||||
if (needs_decrypt) {
|
if (needs_decrypt) {
|
||||||
if (password == NULL) {
|
if (password == NULL) {
|
||||||
@@ -100,32 +146,102 @@ zip_source_t *_zip_source_zip_new(zip_t *srcza, zip_uint64_t srcidx, zip_flags_t
|
|||||||
}
|
}
|
||||||
_zip_file_attributes_from_dirent(&attributes, de);
|
_zip_file_attributes_from_dirent(&attributes, de);
|
||||||
|
|
||||||
if (st.comp_size == 0) {
|
have_comp_size = (st.valid & ZIP_STAT_COMP_SIZE) != 0;
|
||||||
return zip_source_buffer_with_attributes_create(NULL, 0, 0, &attributes, error);
|
if (compressed) {
|
||||||
|
if (have_comp_size && st.comp_size == 0) {
|
||||||
|
src = zip_source_buffer_with_attributes_create(NULL, 0, 0, &attributes, error);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
src = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else if (have_size && st.size == 0) {
|
||||||
|
src = zip_source_buffer_with_attributes_create(NULL, 0, 0, &attributes, error);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
src = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* If we created source buffer above, we want the window source to take ownership of it. */
|
||||||
|
take_ownership = src != NULL;
|
||||||
|
/* if we created a buffer source above, then treat it as if
|
||||||
|
reading the changed data - that way we don't need add another
|
||||||
|
special case to the code below that wraps it in the window
|
||||||
|
source */
|
||||||
|
changed_data = changed_data || (src != NULL);
|
||||||
|
|
||||||
if (partial_data && !needs_decrypt && !needs_decompress) {
|
if (partial_data && !needs_decrypt && !needs_decompress) {
|
||||||
struct zip_stat st2;
|
struct zip_stat st2;
|
||||||
|
zip_t *source_archive;
|
||||||
|
zip_uint64_t source_index;
|
||||||
|
|
||||||
|
if (changed_data) {
|
||||||
|
if (src == NULL) {
|
||||||
|
src = srcza->entry[srcidx].source;
|
||||||
|
}
|
||||||
|
source_archive = NULL;
|
||||||
|
source_index = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
src = srcza->src;
|
||||||
|
source_archive = srcza;
|
||||||
|
source_index = srcidx;
|
||||||
|
}
|
||||||
|
|
||||||
st2.size = len;
|
|
||||||
st2.comp_size = len;
|
|
||||||
st2.comp_method = ZIP_CM_STORE;
|
st2.comp_method = ZIP_CM_STORE;
|
||||||
st2.mtime = st.mtime;
|
st2.valid = ZIP_STAT_COMP_METHOD;
|
||||||
st2.valid = ZIP_STAT_SIZE | ZIP_STAT_COMP_SIZE | ZIP_STAT_COMP_METHOD | ZIP_STAT_MTIME;
|
if (data_len >= 0) {
|
||||||
|
st2.size = (zip_uint64_t)data_len;
|
||||||
|
st2.comp_size = (zip_uint64_t)data_len;
|
||||||
|
st2.valid |= ZIP_STAT_SIZE | ZIP_STAT_COMP_SIZE;
|
||||||
|
}
|
||||||
|
if (st.valid & ZIP_STAT_MTIME) {
|
||||||
|
st2.mtime = st.mtime;
|
||||||
|
st2.valid |= ZIP_STAT_MTIME;
|
||||||
|
}
|
||||||
|
|
||||||
if ((src = _zip_source_window_new(srcza->src, start, (zip_int64_t)len, &st2, &attributes, srcza, srcidx, error)) == NULL) {
|
if ((src = _zip_source_window_new(src, start, data_len, &st2, ZIP_STAT_NAME, &attributes, source_archive, source_index, take_ownership, error)) == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
/* here we restrict src to file data, so no point in doing it for
|
||||||
|
source that already represents only the file data */
|
||||||
|
else if (!changed_data) {
|
||||||
|
/* this branch is executed only for archive sources; we know
|
||||||
|
that stat data come from the archive too, so it's safe to
|
||||||
|
assume that st has a comp_size specified */
|
||||||
if (st.comp_size > ZIP_INT64_MAX) {
|
if (st.comp_size > ZIP_INT64_MAX) {
|
||||||
zip_error_set(error, ZIP_ER_INVAL, 0);
|
zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if ((src = _zip_source_window_new(srcza->src, 0, (zip_int64_t)st.comp_size, &st, &attributes, srcza, srcidx, error)) == NULL) {
|
/* despite the fact that we want the whole data file, we still
|
||||||
|
wrap the source into a window source to add st and
|
||||||
|
attributes and to have a source that positions the read
|
||||||
|
offset properly before each read for multiple zip_file_t
|
||||||
|
referring to the same underlying source */
|
||||||
|
if ((src = _zip_source_window_new(srcza->src, 0, (zip_int64_t)st.comp_size, &st, ZIP_STAT_NAME, &attributes, srcza, srcidx, take_ownership, error)) == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
/* this branch gets executed when reading the whole changed
|
||||||
|
data file or when "reading" from a zero-sized source buffer
|
||||||
|
that we created above */
|
||||||
|
if (src == NULL) {
|
||||||
|
src = srcza->entry[srcidx].source;
|
||||||
|
}
|
||||||
|
/* despite the fact that we want the whole data file, we still
|
||||||
|
wrap the source into a window source to add st and
|
||||||
|
attributes and to have a source that positions the read
|
||||||
|
offset properly before each read for multiple zip_file_t
|
||||||
|
referring to the same underlying source */
|
||||||
|
if ((src = _zip_source_window_new(src, 0, data_len, &st, ZIP_STAT_NAME, &attributes, NULL, 0, take_ownership, error)) == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* In all cases, src is a window source and therefore is owned by this function. */
|
||||||
|
|
||||||
if (_zip_source_set_source_archive(src, srcza) < 0) {
|
if (_zip_source_set_source_archive(src, srcza) < 0) {
|
||||||
zip_source_free(src);
|
zip_source_free(src);
|
||||||
@@ -143,33 +259,40 @@ zip_source_t *_zip_source_zip_new(zip_t *srcza, zip_uint64_t srcidx, zip_flags_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
s2 = enc_impl(srcza, src, st.encryption_method, 0, password);
|
s2 = enc_impl(srcza, src, st.encryption_method, 0, password);
|
||||||
zip_source_free(src);
|
|
||||||
if (s2 == NULL) {
|
if (s2 == NULL) {
|
||||||
|
zip_source_free(src);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
src = s2;
|
src = s2;
|
||||||
}
|
}
|
||||||
if (needs_decompress) {
|
if (needs_decompress) {
|
||||||
s2 = zip_source_decompress(srcza, src, st.comp_method);
|
s2 = zip_source_decompress(srcza, src, st.comp_method);
|
||||||
zip_source_free(src);
|
|
||||||
if (s2 == NULL) {
|
if (s2 == NULL) {
|
||||||
|
zip_source_free(src);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
src = s2;
|
src = s2;
|
||||||
}
|
}
|
||||||
if (needs_crc) {
|
if (needs_crc) {
|
||||||
s2 = zip_source_crc_create(src, 1, error);
|
s2 = zip_source_crc_create(src, 1, error);
|
||||||
zip_source_free(src);
|
|
||||||
if (s2 == NULL) {
|
if (s2 == NULL) {
|
||||||
|
zip_source_free(src);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
src = s2;
|
src = s2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (partial_data && (needs_decrypt || needs_decompress)) {
|
if (partial_data && (needs_decrypt || needs_decompress)) {
|
||||||
s2 = zip_source_window_create(src, start, (zip_int64_t)len, error);
|
zip_stat_t st2;
|
||||||
zip_source_free(src);
|
zip_stat_init(&st2);
|
||||||
|
if (data_len >= 0) {
|
||||||
|
st2.valid = ZIP_STAT_SIZE;
|
||||||
|
st2.size = (zip_uint64_t)data_len;
|
||||||
|
}
|
||||||
|
s2 = _zip_source_window_new(src, start, data_len, &st2, ZIP_STAT_NAME, NULL, NULL, 0, true, error);
|
||||||
if (s2 == NULL) {
|
if (s2 == NULL) {
|
||||||
|
zip_source_free(src);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
src = s2;
|
src = s2;
|
||||||
|
|||||||
@@ -39,22 +39,43 @@ ZIP_EXTERN int
|
|||||||
zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags, zip_stat_t *st) {
|
zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags, zip_stat_t *st) {
|
||||||
const char *name;
|
const char *name;
|
||||||
zip_dirent_t *de;
|
zip_dirent_t *de;
|
||||||
|
zip_entry_t *entry;
|
||||||
|
|
||||||
if ((de = _zip_get_dirent(za, index, flags, NULL)) == NULL)
|
if ((de = _zip_get_dirent(za, index, flags, NULL)) == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if ((name = zip_get_name(za, index, flags)) == NULL)
|
if ((name = zip_get_name(za, index, flags)) == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = za->entry + index;
|
||||||
|
|
||||||
if ((flags & ZIP_FL_UNCHANGED) == 0 && ZIP_ENTRY_DATA_CHANGED(za->entry + index)) {
|
if ((flags & ZIP_FL_UNCHANGED) == 0 && ZIP_ENTRY_DATA_CHANGED(za->entry + index)) {
|
||||||
zip_entry_t *entry = za->entry + index;
|
|
||||||
|
|
||||||
if (zip_source_stat(entry->source, st) < 0) {
|
if (zip_source_stat(entry->source, st) < 0) {
|
||||||
zip_error_set(&za->error, ZIP_ER_CHANGED, 0);
|
zip_error_set(&za->error, ZIP_ER_CHANGED, 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ZIP_CM_IS_DEFAULT(de->comp_method)) {
|
||||||
|
if (!(st->valid & ZIP_STAT_COMP_METHOD) || st->comp_method == ZIP_CM_STORE) {
|
||||||
|
st->valid &= ~(ZIP_STAT_COMP_SIZE|ZIP_STAT_COMP_METHOD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ((st->valid & ZIP_STAT_COMP_METHOD) && st->comp_method != de->comp_method) {
|
||||||
|
st->valid &= ~ZIP_STAT_COMP_SIZE;
|
||||||
|
}
|
||||||
|
st->valid |= ZIP_STAT_COMP_METHOD;
|
||||||
|
st->comp_method = de->comp_method;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((st->valid & (ZIP_STAT_COMP_METHOD|ZIP_STAT_SIZE)) == (ZIP_STAT_COMP_METHOD|ZIP_STAT_SIZE)) && st->comp_method == ZIP_CM_STORE) {
|
||||||
|
st->valid |= ZIP_STAT_COMP_SIZE;
|
||||||
|
st->comp_size = st->size;
|
||||||
|
}
|
||||||
|
|
||||||
if (entry->changes != NULL && entry->changes->changed & ZIP_DIRENT_LAST_MOD) {
|
if (entry->changes != NULL && entry->changes->changed & ZIP_DIRENT_LAST_MOD) {
|
||||||
st->mtime = de->last_mod;
|
st->mtime = de->last_mod;
|
||||||
st->valid |= ZIP_STAT_MTIME;
|
st->valid |= ZIP_STAT_MTIME;
|
||||||
@@ -70,6 +91,16 @@ zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags, zip_stat_t *st)
|
|||||||
st->comp_method = (zip_uint16_t)de->comp_method;
|
st->comp_method = (zip_uint16_t)de->comp_method;
|
||||||
st->encryption_method = de->encryption_method;
|
st->encryption_method = de->encryption_method;
|
||||||
st->valid = (de->crc_valid ? ZIP_STAT_CRC : 0) | ZIP_STAT_SIZE | ZIP_STAT_MTIME | ZIP_STAT_COMP_SIZE | ZIP_STAT_COMP_METHOD | ZIP_STAT_ENCRYPTION_METHOD;
|
st->valid = (de->crc_valid ? ZIP_STAT_CRC : 0) | ZIP_STAT_SIZE | ZIP_STAT_MTIME | ZIP_STAT_COMP_SIZE | ZIP_STAT_COMP_METHOD | ZIP_STAT_ENCRYPTION_METHOD;
|
||||||
|
if (entry->changes != NULL && entry->changes->changed & ZIP_DIRENT_COMP_METHOD) {
|
||||||
|
st->valid &= ~ZIP_STAT_COMP_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((za->ch_flags & ZIP_AFL_WANT_TORRENTZIP) && (flags & ZIP_FL_UNCHANGED) == 0) {
|
||||||
|
st->comp_method = ZIP_CM_DEFLATE;
|
||||||
|
st->mtime = _zip_d2u_time(0xbc00, 0x2198);
|
||||||
|
st->valid |= ZIP_STAT_MTIME | ZIP_STAT_COMP_METHOD;
|
||||||
|
st->valid &= ~ZIP_STAT_COMP_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
st->index = index;
|
st->index = index;
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ _zip_string_new(const zip_uint8_t *raw, zip_uint16_t length, zip_flags_t flags,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(s->raw, raw, length);
|
(void)memcpy_s(s->raw, length + 1, raw, length);
|
||||||
s->raw[length] = '\0';
|
s->raw[length] = '\0';
|
||||||
s->length = length;
|
s->length = length;
|
||||||
s->encoding = ZIP_ENCODING_UNKNOWN;
|
s->encoding = ZIP_ENCODING_UNKNOWN;
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ _zip_winzip_aes_new(const zip_uint8_t *password, zip_uint64_t password_length, c
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (password_verify) {
|
if (password_verify) {
|
||||||
memcpy(password_verify, buffer + (2 * key_size / 8), WINZIP_AES_PASSWORD_VERIFY_LENGTH);
|
(void)memcpy_s(password_verify, WINZIP_AES_PASSWORD_VERIFY_LENGTH, buffer + (2 * key_size / 8), WINZIP_AES_PASSWORD_VERIFY_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx;
|
return ctx;
|
||||||
|
|||||||
@@ -8,10 +8,10 @@
|
|||||||
based on ../cmake-zipconf.h.in.
|
based on ../cmake-zipconf.h.in.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define LIBZIP_VERSION "1.9.2"
|
#define LIBZIP_VERSION "1.10.0"
|
||||||
#define LIBZIP_VERSION_MAJOR 1
|
#define LIBZIP_VERSION_MAJOR 1
|
||||||
#define LIBZIP_VERSION_MINOR 9
|
#define LIBZIP_VERSION_MINOR 10
|
||||||
#define LIBZIP_VERSION_MICRO 2
|
#define LIBZIP_VERSION_MICRO 0
|
||||||
|
|
||||||
/* #undef ZIP_STATIC */
|
/* #undef ZIP_STATIC */
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,9 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _ZIP_COMPILING_DEPRECATED
|
#ifdef _ZIP_COMPILING_DEPRECATED
|
||||||
|
#define ZIP_DEPRECATED(x)
|
||||||
|
#else
|
||||||
#define ZIP_DISABLE_DEPRECATED
|
#define ZIP_DISABLE_DEPRECATED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -67,6 +69,12 @@
|
|||||||
#define EF_WINZIP_AES_SIZE 7
|
#define EF_WINZIP_AES_SIZE 7
|
||||||
#define MAX_DATA_DESCRIPTOR_LENGTH 24
|
#define MAX_DATA_DESCRIPTOR_LENGTH 24
|
||||||
|
|
||||||
|
#define TORRENTZIP_SIGNATURE "TORRENTZIPPED-"
|
||||||
|
#define TORRENTZIP_SIGNATURE_LENGTH 14
|
||||||
|
#define TORRENTZIP_CRC_LENGTH 8
|
||||||
|
#define TORRENTZIP_MEM_LEVEL 8
|
||||||
|
#define TORRENTZIP_COMPRESSION_FLAGS ZIP_UINT16_MAX
|
||||||
|
|
||||||
#define ZIP_CRYPTO_PKWARE_HEADERLEN 12
|
#define ZIP_CRYPTO_PKWARE_HEADERLEN 12
|
||||||
|
|
||||||
#define ZIP_CM_REPLACED_DEFAULT (-2)
|
#define ZIP_CM_REPLACED_DEFAULT (-2)
|
||||||
@@ -76,7 +84,6 @@
|
|||||||
#define WINZIP_AES_MAX_HEADER_LENGTH (16 + WINZIP_AES_PASSWORD_VERIFY_LENGTH)
|
#define WINZIP_AES_MAX_HEADER_LENGTH (16 + WINZIP_AES_PASSWORD_VERIFY_LENGTH)
|
||||||
#define AES_BLOCK_SIZE 16
|
#define AES_BLOCK_SIZE 16
|
||||||
#define HMAC_LENGTH 10
|
#define HMAC_LENGTH 10
|
||||||
#define SHA1_LENGTH 20
|
|
||||||
#define SALT_LENGTH(method) ((method) == ZIP_EM_AES_128 ? 8 : ((method) == ZIP_EM_AES_192 ? 12 : 16))
|
#define SALT_LENGTH(method) ((method) == ZIP_EM_AES_128 ? 8 : ((method) == ZIP_EM_AES_192 ? 12 : 16))
|
||||||
|
|
||||||
#define ZIP_CM_IS_DEFAULT(x) ((x) == ZIP_CM_DEFAULT || (x) == ZIP_CM_REPLACED_DEFAULT)
|
#define ZIP_CM_IS_DEFAULT(x) ((x) == ZIP_CM_DEFAULT || (x) == ZIP_CM_REPLACED_DEFAULT)
|
||||||
@@ -126,7 +133,7 @@ struct zip_compression_algorithm {
|
|||||||
zip_uint64_t (*maximum_compressed_size)(zip_uint64_t uncompressed_size);
|
zip_uint64_t (*maximum_compressed_size)(zip_uint64_t uncompressed_size);
|
||||||
|
|
||||||
/* called once to create new context */
|
/* called once to create new context */
|
||||||
void *(*allocate)(zip_uint16_t method, int compression_flags, zip_error_t *error);
|
void *(*allocate)(zip_uint16_t method, zip_uint32_t compression_flags, zip_error_t *error);
|
||||||
/* called once to free context */
|
/* called once to free context */
|
||||||
void (*deallocate)(void *ctx);
|
void (*deallocate)(void *ctx);
|
||||||
|
|
||||||
@@ -170,16 +177,14 @@ const zip_uint8_t *zip_get_extra_field_by_id(zip_t *, int, int, zip_uint16_t, in
|
|||||||
user-supplied compression/encryption implementation is finished.
|
user-supplied compression/encryption implementation is finished.
|
||||||
Thus we will keep it private for now. */
|
Thus we will keep it private for now. */
|
||||||
|
|
||||||
typedef zip_int64_t (*zip_source_layered_callback)(zip_source_t *, void *, void *, zip_uint64_t, enum zip_source_cmd);
|
zip_source_t *zip_source_compress(zip_t *za, zip_source_t *src, zip_int32_t cm, zip_uint32_t compression_flags);
|
||||||
zip_source_t *zip_source_compress(zip_t *za, zip_source_t *src, zip_int32_t cm, int compression_flags);
|
|
||||||
zip_source_t *zip_source_crc_create(zip_source_t *, int, zip_error_t *error);
|
zip_source_t *zip_source_crc_create(zip_source_t *, int, zip_error_t *error);
|
||||||
zip_source_t *zip_source_decompress(zip_t *za, zip_source_t *src, zip_int32_t cm);
|
zip_source_t *zip_source_decompress(zip_t *za, zip_source_t *src, zip_int32_t cm);
|
||||||
zip_source_t *zip_source_layered(zip_t *, zip_source_t *, zip_source_layered_callback, void *);
|
|
||||||
zip_source_t *zip_source_layered_create(zip_source_t *src, zip_source_layered_callback cb, void *ud, zip_error_t *error);
|
|
||||||
zip_source_t *zip_source_pkware_decode(zip_t *, zip_source_t *, zip_uint16_t, int, const char *);
|
zip_source_t *zip_source_pkware_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 *);
|
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 *);
|
int zip_source_remove(zip_source_t *);
|
||||||
zip_int64_t zip_source_supports(zip_source_t *src);
|
zip_int64_t zip_source_supports(zip_source_t *src);
|
||||||
|
bool zip_source_supports_reopen(zip_source_t *src);
|
||||||
zip_source_t *zip_source_winzip_aes_decode(zip_t *, zip_source_t *, zip_uint16_t, int, const char *);
|
zip_source_t *zip_source_winzip_aes_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_winzip_aes_encode(zip_t *, zip_source_t *, zip_uint16_t, int, const char *);
|
||||||
zip_source_t *zip_source_buffer_with_attributes(zip_t *za, const void *data, zip_uint64_t len, int freep, zip_file_attributes_t *attributes);
|
zip_source_t *zip_source_buffer_with_attributes(zip_t *za, const void *data, zip_uint64_t len, int freep, zip_file_attributes_t *attributes);
|
||||||
@@ -300,14 +305,14 @@ struct zip {
|
|||||||
zip_hash_t *names; /* hash table for name lookup */
|
zip_hash_t *names; /* hash table for name lookup */
|
||||||
|
|
||||||
zip_progress_t *progress; /* progress callback for zip_close() */
|
zip_progress_t *progress; /* progress callback for zip_close() */
|
||||||
|
|
||||||
|
zip_uint32_t* write_crc; /* have _zip_write() compute CRC */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* file in zip archive, part of API */
|
/* file in zip archive, part of API */
|
||||||
|
|
||||||
struct zip_file {
|
struct zip_file {
|
||||||
zip_t *za; /* zip archive containing this file */
|
|
||||||
zip_error_t error; /* error information */
|
zip_error_t error; /* error information */
|
||||||
bool eof;
|
|
||||||
zip_source_t *src; /* data source */
|
zip_source_t *src; /* data source */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -346,7 +351,7 @@ struct zip_dirent {
|
|||||||
zip_uint32_t ext_attrib; /* (c) external file attributes */
|
zip_uint32_t ext_attrib; /* (c) external file attributes */
|
||||||
zip_uint64_t offset; /* (c) offset of local header */
|
zip_uint64_t offset; /* (c) offset of local header */
|
||||||
|
|
||||||
zip_uint16_t compression_level; /* level of compression to use (never valid in orig) */
|
zip_uint32_t compression_level; /* level of compression to use (never valid in orig) */
|
||||||
zip_uint16_t encryption_method; /* encryption method, computed from other fields */
|
zip_uint16_t encryption_method; /* encryption method, computed from other fields */
|
||||||
char *password; /* file specific encryption password */
|
char *password; /* file specific encryption password */
|
||||||
};
|
};
|
||||||
@@ -456,7 +461,7 @@ struct zip_buffer {
|
|||||||
|
|
||||||
struct zip_filelist {
|
struct zip_filelist {
|
||||||
zip_uint64_t idx;
|
zip_uint64_t idx;
|
||||||
/* TODO const char *name; */
|
const char *name;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct zip_filelist zip_filelist_t;
|
typedef struct zip_filelist zip_filelist_t;
|
||||||
@@ -477,6 +482,8 @@ typedef struct _zip_pkware_keys zip_pkware_keys_t;
|
|||||||
#define ZIP_ENTRY_HAS_CHANGES(e) (ZIP_ENTRY_DATA_CHANGED(e) || (e)->deleted || ZIP_ENTRY_CHANGED((e), ZIP_DIRENT_ALL))
|
#define ZIP_ENTRY_HAS_CHANGES(e) (ZIP_ENTRY_DATA_CHANGED(e) || (e)->deleted || ZIP_ENTRY_CHANGED((e), ZIP_DIRENT_ALL))
|
||||||
|
|
||||||
#define ZIP_IS_RDONLY(za) ((za)->ch_flags & ZIP_AFL_RDONLY)
|
#define ZIP_IS_RDONLY(za) ((za)->ch_flags & ZIP_AFL_RDONLY)
|
||||||
|
#define ZIP_IS_TORRENTZIP(za) ((za)->flags & ZIP_AFL_IS_TORRENTZIP)
|
||||||
|
#define ZIP_WANT_TORRENTZIP(za) ((za)->ch_flags & ZIP_AFL_WANT_TORRENTZIP)
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_EXPLICIT_MEMSET
|
#ifdef HAVE_EXPLICIT_MEMSET
|
||||||
@@ -531,8 +538,11 @@ void _zip_dirent_finalize(zip_dirent_t *);
|
|||||||
void _zip_dirent_init(zip_dirent_t *);
|
void _zip_dirent_init(zip_dirent_t *);
|
||||||
bool _zip_dirent_needs_zip64(const zip_dirent_t *, zip_flags_t);
|
bool _zip_dirent_needs_zip64(const zip_dirent_t *, zip_flags_t);
|
||||||
zip_dirent_t *_zip_dirent_new(void);
|
zip_dirent_t *_zip_dirent_new(void);
|
||||||
|
bool zip_dirent_process_ef_zip64(zip_dirent_t * zde, const zip_uint8_t * ef, zip_uint64_t got_len, bool local, zip_error_t * error);
|
||||||
zip_int64_t _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, bool local, zip_error_t *error);
|
zip_int64_t _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, bool local, zip_error_t *error);
|
||||||
void _zip_dirent_set_version_needed(zip_dirent_t *de, bool force_zip64);
|
void _zip_dirent_set_version_needed(zip_dirent_t *de, bool force_zip64);
|
||||||
|
void zip_dirent_torrentzip_normalize(zip_dirent_t *de);
|
||||||
|
|
||||||
zip_int32_t _zip_dirent_size(zip_source_t *src, zip_uint16_t, zip_error_t *);
|
zip_int32_t _zip_dirent_size(zip_source_t *src, zip_uint16_t, zip_error_t *);
|
||||||
int _zip_dirent_write(zip_t *za, zip_dirent_t *dirent, zip_flags_t flags);
|
int _zip_dirent_write(zip_t *za, zip_dirent_t *dirent, zip_flags_t flags);
|
||||||
|
|
||||||
@@ -554,7 +564,6 @@ void _zip_error_clear(zip_error_t *);
|
|||||||
void _zip_error_get(const zip_error_t *, int *, int *);
|
void _zip_error_get(const zip_error_t *, int *, int *);
|
||||||
|
|
||||||
void _zip_error_copy(zip_error_t *dst, const zip_error_t *src);
|
void _zip_error_copy(zip_error_t *dst, const zip_error_t *src);
|
||||||
void _zip_error_set_from_source(zip_error_t *, zip_source_t *);
|
|
||||||
|
|
||||||
const zip_uint8_t *_zip_extract_extra_field_by_id(zip_error_t *, zip_uint16_t, int, const zip_uint8_t *, zip_uint16_t, zip_uint16_t *);
|
const zip_uint8_t *_zip_extract_extra_field_by_id(zip_error_t *, zip_uint16_t, int, const zip_uint8_t *, zip_uint16_t, zip_uint16_t *);
|
||||||
|
|
||||||
@@ -607,8 +616,7 @@ bool _zip_source_had_error(zip_source_t *);
|
|||||||
void _zip_source_invalidate(zip_source_t *src);
|
void _zip_source_invalidate(zip_source_t *src);
|
||||||
zip_source_t *_zip_source_new(zip_error_t *error);
|
zip_source_t *_zip_source_new(zip_error_t *error);
|
||||||
int _zip_source_set_source_archive(zip_source_t *, zip_t *);
|
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_int64_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_window_new(zip_source_t *src, zip_uint64_t start, zip_int64_t length, zip_stat_t *st, zip_uint64_t st_invalid, zip_file_attributes_t *attributes, zip_t *source_archive, zip_uint64_t source_index, bool take_ownership, zip_error_t *error);
|
||||||
zip_source_t *_zip_source_zip_new(zip_t *, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_uint64_t, const char *, zip_error_t *error);
|
|
||||||
|
|
||||||
int _zip_stat_merge(zip_stat_t *dst, const zip_stat_t *src, zip_error_t *error);
|
int _zip_stat_merge(zip_stat_t *dst, const zip_stat_t *src, zip_error_t *error);
|
||||||
int _zip_string_equal(const zip_string_t *a, const zip_string_t *b);
|
int _zip_string_equal(const zip_string_t *a, const zip_string_t *b);
|
||||||
|
|||||||
Reference in New Issue
Block a user