Deps: Update to libzip 1.11.1

This commit is contained in:
JordanTheToaster 2024-09-28 01:48:55 +01:00 committed by Ty
parent 31dcda05b7
commit 02fda478ea
144 changed files with 1432 additions and 646 deletions

View File

@ -1,2 +1,2 @@
Dieter Baron <dillo@nih.at> Dieter Baron <dillo@nih.at>
Thomas Klausner <tk@giga.or.at> Thomas Klausner <wiz@gatalith.at>

View File

@ -250,6 +250,7 @@ add_library(zip STATIC
lib/zip_unchange_archive.c lib/zip_unchange_archive.c
lib/zip_unchange_data.c lib/zip_unchange_data.c
lib/zip_utf-8.c lib/zip_utf-8.c
lib/zip_source_get_dostime.c
${CMAKE_CURRENT_BINARY_DIR}/zip_err_str.c ${CMAKE_CURRENT_BINARY_DIR}/zip_err_str.c
) )

343
3rdparty/libzip/NEWS.md vendored Normal file
View File

@ -0,0 +1,343 @@
# 1.11.1 [2024-09-19]
* Fix zipconf.h for version number with missing third component.
# 1.11 [2024-09-19]
* Stop searching after finding acceptable central directory, even if it contains inconsistencies.
* Only write Zip64 EOCD if fields don't fit in normal EOCD. Previously libzip also wrote it when any directory entry required Zip64.
* Allow bytes from 0x00-0x1F as UTF-8.
* Add new error code `ZIP_ER_TRUNCATED_ZIP` for files that start with a valid local header signature.
* `zipcmp`: add `-T` option for comparing timestamps.
* `zip_file_replace` now removes the target's extra field information.
# 1.10.1 [2023-08-23]
* Add `ZIP_LENGTH_TO_END` and `ZIP_LENGTH_UNCHECKED`. Unless `ZIP_LENGTH_UNCHECKED` is used as `length`, it is an error for a file to shrink between the time when the source is created and when its data is read.
* Fix test on Windows.
# 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.
# 1.9.1 [2022-06-28]
* Fix `zip_file_is_seekable()`.
# 1.9.0 [2022-06-13]
* Add `zip_file_is_seekable()`.
* Improve compatibility with WinAES.
* Fix encoding handling in `zip_name_locate()`.
* Add option to `zipcmp` to output summary of changes.
* Various bug fixes and documentation improvements.
# 1.8.0 [2021-06-18]
* Add support for zstd (Zstandard) compression.
* Add support for lzma (ID 14) compression.
* Add `zip_source_window_create()`.
* Add `zip_source_zip_create()` variant to `zip_source_zip()`.
* Allow method specific `comp_flags` in `zip_set_file_compression()`.
* Allow `zip_source_tell()` on sources that don't support seeking and `zip_ftell()` on compressed data.
* Provide more details for consistency check errors.
* Improve output of `zipcmp`.
* In `zipcmp`, dont 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()`.
# 1.7.3 [2020-07-15]
* Support cmake < 3.17 again.
* Fix pkgconfig file (regression in 1.7.2).
# 1.7.2 [2020-07-11]
* Fixes for the CMake `find_project()` files.
* libzip moved to the CMake `libzip::` `NAMESPACE`.
* CMake usage best practice cleanups.
# 1.7.1 [2020-06-13]
* Restore `LIBZIP_VERSION_{MAJOR,MINOR,MICRO}` symbols.
* Fixes warnings reported by PVS-Studio.
* Add `LIBZIP_DO_INSTALL` build setting to make it easier to use
libzip as subproject.
# 1.7.0 [2020-06-05]
* Add support for encrypting using traditional PKWare encryption.
* Add `zip_compression_method_supported()`.
* Add `zip_encryption_method_supported()`.
* Add the `ZIP_SOURCE_GET_FILE_ATTRIBUTES` source command.
* Refactor stdio file backend.
* Add CMake find_project() support.
# 1.6.1 [2020-02-03]
* Bugfix for double-free in `zipcmp(1)` during cleanup.
# 1.6.0 [2020-01-24]
* Avoid using `umask()` since it's not thread-safe.
* Set close-on-exec flag when opening files.
* Do not accept empty files as valid zip archives any longer.
* Add support for XZ compressed files (using liblzma).
* Add support for cancelling while closing zip archives.
* Add support for setting the time in the on-disk format.
# 1.5.2 [2019-03-12]
* Fix bug in AES encryption affecting certain file sizes
* Keep file permissions when modifying zip archives
* Support systems with small stack size.
* Support mbed TLS as crypto backend.
* Add nullability annotations.
# 1.5.1 [2018-04-11]
* Choose format of installed documentation based on available tools.
* Fix visibility of symbols.
* Fix zipcmp directory support.
* Don't set RPATH on Linux.
* Use Libs.private for link dependencies in pkg-config file.
* Fix build with LibreSSL.
* Various bugfixes.
# 1.5.0 [2018-03-11]
* Use standard cryptographic library instead of custom AES implementation.
This also simplifies the license.
* Use `clang-format` to format the source code.
* More Windows improvements.
# 1.4.0 [2017-12-29]
* Improve build with cmake
* Retire autoconf/automake build system
* Add `zip_source_buffer_fragment()`.
* Add support to clone unchanged beginning of archive (instead of rewriting it).
Supported for buffer sources and on Apple File System.
* Add support for Microsoft Universal Windows Platform.
# 1.3.2 [2017-11-20]
* Fix bug introduced in last: zip_t was erroneously freed if zip_close() failed.
# 1.3.1 [2017-11-19]
* Install zipconf.h into ${PREFIX}/include
* Add zip_libzip_version()
* Fix AES tests on Linux
# 1.3.0 [2017-09-02]
* Support bzip2 compressed zip archives
* Improve file progress callback code
* Fix zip_fdopen()
* CVE-2017-12858: Fix double free()
* CVE-2017-14107: Improve EOCD64 parsing
# 1.2.0 [2017-02-19]
* Support for AES encryption (Winzip version), both encryption
and decryption
* Support legacy zip files with >64k entries
* Fix seeking in zip_source_file if start > 0
* Add zip_fseek() for seeking in uncompressed data
* Add zip_ftell() for telling position in uncompressed data
* Add zip_register_progress_callback() for UI updates during zip_close()
# 1.1.3 [2016-05-28]
* Fix build on Windows when using autoconf
# 1.1.2 [2016-02-19]
* Improve support for 3MF files
# 1.1.1 [2016-02-07]
* Build fixes for Linux
* Fix some warnings reported by PVS-Studio
# 1.1 [2016-01-26]
* ziptool(1): command line tool to modify zip archives
* Speedups for archives with many entries
* Coverity fixes
* Better APK support
* Support for running tests on Windows
* More build fixes for Windows
* Portability fixes
* Documentation improvements
# 1.0.1 [2015-05-04]
* Build fixes for Windows
# 1.0 [2015-05-03]
* Implemented an I/O abstraction layer
* Added support for native Windows API for files
* Added support for setting the last modification time for a file
* Added a new type zip_error_t for errors
* Added more typedefs for structs
* Torrentzip support was removed
* CVE-2015-2331 was fixed
* Addressed all Coverity CIDs
# 0.11.2 [2013-12-19]
* Support querying/setting operating system and external attributes
* For newly added files, set operating system to UNIX, permissions
to 0666 (0777 for directories)
* Fix bug when writing zip archives containing files bigger than 4GB
# 0.11.1 [2013-04-27]
* Fix bugs in zip_set_file_compression()
* Include Xcode build infrastructure
# 0.11 [2013-03-23]
* Added Zip64 support (large file support)
* Added UTF-8 support for file names, file comments, and archive comments
* Changed API for name and comment related functions for UTF-8 support
* Added zip_discard()
* Added ZIP_TRUNCATE for zip_open()
* Added zip_set_file_compression()
* Added API for accessing and modifying extra fields
* Improved API type consistency
* Use gcc4's visibility __attribute__
* More changes for Windows support
* Additional test cases
# 0.10.1 [2012-03-20]
* Fixed CVE-2012-1162
* Fixed CVE-2012-1163
# 0.10 [2010-03-18]
* Added zip_get_num_entries(), deprecated zip_get_num_files()
* Better windows support
* Support for traditional PKWARE encryption added
* Fix opening archives with more than 65535 entries
* Fix some memory leaks
* Fix cmake build and installation
* Fix memory leak in error case in zip_open()
* Fixed CVE-2011-0421 (no security implications though)
* More documentation
# 0.9.3 [2010-02-01]
* Include m4/ directory in distribution; some packagers need it
# 0.9.2 [2010-01-31]
* Avoid passing uninitialized data to deflate()
* Fix memory leak when closing zip archives
# 0.9.1 [2010-01-24]
* Fix infinite loop on reading some broken files
* Optimization in time conversion (don't call localtime())
* Clear data descriptor flag in central directory, fixing Open Office files
* Allow more than 64k entries
# 0.9 [2008-07-25]
* on Windows, explicitly set dllimport/dllexport
* remove erroneous references to GPL
* add support for torrentzip
* new functions: zip_get_archive_flag, zip_set_archive_flag
* zip_source_zip: add flag to force recompression
* zip_sorce_file: only keep file open while reading from it
# 0.8 [2007-06-06]
* fix for zip archives larger than 2GiB
* fix zip_error_strerror to include libzip error string
* add support for reading streamed zip files
* new functions: zip_add_dir, zip_error_clear, zip_file_error_clear
* add basic support for building with CMake (incomplete)
# 0.7.1 [2006-05-18]
* bugfix for zip_close
# 0.7 [2006-05-06]
* struct zip_stat increased for future encryption support
* zip_add return value changed (now returns new index of added file)
* shared library major bump because of previous two
* added functions for reading and writing file and archive comments
New functions: zip_get_archive_comment, zip_get_file_comment,
zip_set_archive_comment, zip_set_file_comment, zip_unchange_archive
# 0.6.1 [2005-07-14]
* various bug fixes
# 0.6 [2005-06-09]
* first standalone release
* changed license to three-clause BSD
* overhauled API
* added man pages
* install zipcmp and zipmerge

View File

@ -82,6 +82,7 @@ add_library(zip
zip_source_file_stdio.c zip_source_file_stdio.c
zip_source_free.c zip_source_free.c
zip_source_function.c zip_source_function.c
zip_source_get_dostime.c
zip_source_get_file_attributes.c zip_source_get_file_attributes.c
zip_source_is_deleted.c zip_source_is_deleted.c
zip_source_layered.c zip_source_layered.c
@ -117,6 +118,7 @@ add_library(zip
add_library(libzip::zip ALIAS zip) add_library(libzip::zip ALIAS zip)
if(WIN32) if(WIN32)
target_compile_definitions(zip PRIVATE WIN32_LEAN_AND_MEAN)
target_sources(zip PRIVATE target_sources(zip PRIVATE
zip_source_file_win32.c zip_source_file_win32.c
zip_source_file_win32_named.c zip_source_file_win32_named.c
@ -172,7 +174,8 @@ if(HAVE_CRYPTO)
endif() endif()
if(SHARED_LIB_VERSIONNING) if(SHARED_LIB_VERSIONNING)
set_target_properties(zip PROPERTIES VERSION 5.5 SOVERSION 5) # MACHO_*_VERSION can be removed when SOVERSION gets increased. Cf #405
set_target_properties(zip PROPERTIES VERSION 5.5 SOVERSION 5 MACHO_CURRENT_VERSION 6.5 MACHO_COMPATIBILITY_VERSION 6)
endif() endif()
target_link_libraries(zip PRIVATE ZLIB::ZLIB) target_link_libraries(zip PRIVATE ZLIB::ZLIB)

View File

@ -3,7 +3,7 @@
/* /*
compat.h -- compatibility defines. compat.h -- compatibility defines.
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -3,7 +3,7 @@
/* /*
zip.h -- exported declarations. zip.h -- exported declarations.
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>
@ -154,6 +154,7 @@ extern "C" {
#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_DATA_LENGTH 33 /* N Unexpected length of data */
#define ZIP_ER_NOT_ALLOWED 34 /* N Not allowed in torrentzip */ #define ZIP_ER_NOT_ALLOWED 34 /* N Not allowed in torrentzip */
#define ZIP_ER_TRUNCATED_ZIP 35 /* N Possibly truncated or corrupted zip archive */
/* type of system error value */ /* type of system error value */
@ -256,7 +257,8 @@ enum zip_source_cmd {
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 */ ZIP_SOURCE_SUPPORTS_REOPEN, /* allow reading from changed entry */
ZIP_SOURCE_GET_DOS_TIME /* get last modification time in DOS format */
}; };
typedef enum zip_source_cmd zip_source_cmd_t; typedef enum zip_source_cmd zip_source_cmd_t;

View File

@ -1,6 +1,6 @@
/* /*
zip_add.c -- add file via callback function zip_add.c -- add file via callback function
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_add_dir.c -- add directory zip_add_dir.c -- add directory
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_add_entry.c -- create and init struct zip_entry zip_add_entry.c -- create and init struct zip_entry
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>
@ -64,7 +64,7 @@ _zip_add_entry(zip_t *za) {
return -1; return -1;
} }
rentries = (zip_entry_t *)realloc(za->entry, sizeof(struct zip_entry) * (size_t)nalloc); rentries = (zip_entry_t *)realloc(za->entry, sizeof(struct zip_entry) * (size_t)nalloc);
if (!rentries) { if (rentries == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0); zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1; return -1;
} }

View File

@ -1,6 +1,6 @@
/* /*
zip_algorithm_bzip2.c -- bzip2 (de)compression routines zip_algorithm_bzip2.c -- bzip2 (de)compression routines
Copyright (C) 2017-2021 Dieter Baron and Thomas Klausner Copyright (C) 2017-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_algorithm_deflate.c -- deflate (de)compression routines zip_algorithm_deflate.c -- deflate (de)compression routines
Copyright (C) 2017-2021 Dieter Baron and Thomas Klausner Copyright (C) 2017-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,7 +1,7 @@
/* /*
zip_algorithm_xz.c -- LZMA/XZ (de)compression routines zip_algorithm_xz.c -- LZMA/XZ (de)compression routines
Bazed on zip_algorithm_deflate.c -- deflate (de)compression routines Bazed on zip_algorithm_deflate.c -- deflate (de)compression routines
Copyright (C) 2017-2021 Dieter Baron and Thomas Klausner Copyright (C) 2017-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_algorithm_zstd.c -- zstd (de)compression routines zip_algorithm_zstd.c -- zstd (de)compression routines
Copyright (C) 2020-2021 Dieter Baron and Thomas Klausner Copyright (C) 2020-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_buffer.c -- bounds checked access to memory buffer zip_buffer.c -- bounds checked access to memory buffer
Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner Copyright (C) 2014-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>
@ -306,8 +306,7 @@ _zip_buffer_put_8(zip_buffer_t *buffer, zip_uint8_t i) {
} }
int int _zip_buffer_set_offset(zip_buffer_t *buffer, zip_uint64_t offset) {
_zip_buffer_set_offset(zip_buffer_t *buffer, zip_uint64_t offset) {
if (offset > buffer->size) { if (offset > buffer->size) {
buffer->ok = false; buffer->ok = false;
return -1; return -1;

View File

@ -1,6 +1,6 @@
/* /*
zip_close.c -- close zip archive and update changes zip_close.c -- close zip archive and update changes
Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner Copyright (C) 1999-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>
@ -44,7 +44,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_source_t *, zip_int64_t);
static int torrentzip_compare_names(const void *a, const void *b); 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);
@ -468,11 +468,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
/* PKWare encryption uses last_mod, make sure it gets the right value. */ /* PKWare encryption uses last_mod, make sure it gets the right value. */
if (de->changed & ZIP_DIRENT_LAST_MOD) { if (de->changed & ZIP_DIRENT_LAST_MOD) {
zip_stat_t st_mtime; if ((src_tmp = _zip_source_window_new(src_final, 0, -1, NULL, 0, NULL, &de->last_mod, NULL, 0, true, &za->error)) == NULL) {
zip_stat_init(&st_mtime);
st_mtime.valid = ZIP_STAT_MTIME;
st_mtime.mtime = de->last_mod;
if ((src_tmp = _zip_source_window_new(src_final, 0, -1, &st_mtime, 0, NULL, NULL, 0, true, &za->error)) == NULL) {
zip_source_free(src_final); zip_source_free(src_final);
return -1; return -1;
} }
@ -495,7 +491,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
return -1; return -1;
} }
ret = copy_source(za, src_final, data_length); ret = copy_source(za, src_final, src, 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);
@ -529,10 +525,23 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
} }
if ((de->changed & ZIP_DIRENT_LAST_MOD) == 0) { if ((de->changed & ZIP_DIRENT_LAST_MOD) == 0) {
if (st.valid & ZIP_STAT_MTIME) int ret2 = zip_source_get_dos_time(src, &de->last_mod);
de->last_mod = st.mtime; if (ret2 < 0) {
else zip_error_set_from_source(&za->error, src);
time(&de->last_mod); return -1;
}
if (ret2 == 0) {
time_t mtime;
if (st.valid & ZIP_STAT_MTIME) {
mtime = st.mtime;
}
else {
time(&mtime);
}
if (_zip_u2d_time(mtime, &de->last_mod, &za->error) < 0) {
return -1;
}
}
} }
de->comp_method = st.comp_method; de->comp_method = st.comp_method;
de->crc = st.crc; de->crc = st.crc;
@ -605,7 +614,7 @@ copy_data(zip_t *za, zip_uint64_t len) {
static int static int
copy_source(zip_t *za, zip_source_t *src, zip_int64_t data_length) { copy_source(zip_t *za, zip_source_t *src, zip_source_t *src_for_length, zip_int64_t data_length) {
DEFINE_BYTE_ARRAY(buf, BUFSIZE); DEFINE_BYTE_ARRAY(buf, BUFSIZE);
zip_int64_t n, current; zip_int64_t n, current;
int ret; int ret;
@ -628,7 +637,13 @@ copy_source(zip_t *za, zip_source_t *src, zip_int64_t data_length) {
break; break;
} }
if (n == BUFSIZE && za->progress && data_length > 0) { if (n == BUFSIZE && za->progress && data_length > 0) {
current += n; zip_int64_t t;
t = zip_source_tell(src_for_length);
if (t >= 0) {
current = t;
} else {
current += n;
}
if (_zip_progress_update(za->progress, (double)current / (double)data_length) != 0) { if (_zip_progress_update(za->progress, (double)current / (double)data_length) != 0) {
zip_error_set(&za->error, ZIP_ER_CANCELLED, 0); zip_error_set(&za->error, ZIP_ER_CANCELLED, 0);
ret = -1; ret = -1;
@ -742,4 +757,4 @@ static int torrentzip_compare_names(const void *a, const void *b) {
} }
return strcasecmp(aname, bname); return strcasecmp(aname, bname);
} }

View File

@ -1,6 +1,6 @@
/* /*
zip_crypto.h -- crypto definitions zip_crypto.h -- crypto definitions
Copyright (C) 2017-2021 Dieter Baron and Thomas Klausner Copyright (C) 2017-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_crypto_commoncrypto.c -- CommonCrypto wrapper. zip_crypto_commoncrypto.c -- CommonCrypto wrapper.
Copyright (C) 2018-2021 Dieter Baron and Thomas Klausner Copyright (C) 2018-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_crypto_commoncrypto.h -- definitions for CommonCrypto wrapper. zip_crypto_commoncrypto.h -- definitions for CommonCrypto wrapper.
Copyright (C) 2018 Dieter Baron and Thomas Klausner Copyright (C) 2018-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_crypto_gnutls.c -- GnuTLS wrapper. zip_crypto_gnutls.c -- GnuTLS wrapper.
Copyright (C) 2018-2021 Dieter Baron and Thomas Klausner Copyright (C) 2018-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_crypto_gnutls.h -- definitions for GnuTLS wrapper. zip_crypto_gnutls.h -- definitions for GnuTLS wrapper.
Copyright (C) 2018-2021 Dieter Baron and Thomas Klausner Copyright (C) 2018-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_crypto_mbedtls.c -- mbed TLS wrapper zip_crypto_mbedtls.c -- mbed TLS wrapper
Copyright (C) 2018-2021 Dieter Baron and Thomas Klausner Copyright (C) 2018-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_crypto_mbedtls.h -- definitions for mbedtls wrapper zip_crypto_mbedtls.h -- definitions for mbedtls wrapper
Copyright (C) 2018-2021 Dieter Baron and Thomas Klausner Copyright (C) 2018-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_crypto_openssl.c -- OpenSSL wrapper. zip_crypto_openssl.c -- OpenSSL wrapper.
Copyright (C) 2018-2021 Dieter Baron and Thomas Klausner Copyright (C) 2018-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>
@ -126,8 +126,9 @@ _zip_crypto_aes_free(_zip_crypto_aes_t *aes) {
bool bool
_zip_crypto_aes_encrypt_block(_zip_crypto_aes_t *aes, const zip_uint8_t *in, zip_uint8_t *out) { _zip_crypto_aes_encrypt_block(_zip_crypto_aes_t *aes, const zip_uint8_t *in, zip_uint8_t *out) {
int len; int len = 0;
if (EVP_EncryptUpdate(aes, out, &len, in, ZIP_CRYPTO_AES_BLOCK_LENGTH) != 1) { if (EVP_EncryptUpdate(aes, out, &len, in, ZIP_CRYPTO_AES_BLOCK_LENGTH) != 1
|| len != ZIP_CRYPTO_AES_BLOCK_LENGTH) {
return false; return false;
} }
return true; return true;
@ -214,11 +215,11 @@ _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 #ifdef USE_OPENSSL_3_API
size_t length; size_t length = 0;
return EVP_MAC_final(hmac->ctx, data, &length, ZIP_CRYPTO_SHA1_LENGTH) == 1 && length == ZIP_CRYPTO_SHA1_LENGTH; return EVP_MAC_final(hmac->ctx, data, &length, ZIP_CRYPTO_SHA1_LENGTH) == 1 && length == ZIP_CRYPTO_SHA1_LENGTH;
#else #else
unsigned int length; unsigned int length = 0;
return HMAC_Final(hmac, data, &length) == 1; return HMAC_Final(hmac, data, &length) == 1 && length == ZIP_CRYPTO_SHA1_LENGTH;
#endif #endif
} }

View File

@ -1,6 +1,6 @@
/* /*
zip_crypto_openssl.h -- definitions for OpenSSL wrapper. zip_crypto_openssl.h -- definitions for OpenSSL wrapper.
Copyright (C) 2018-2021 Dieter Baron and Thomas Klausner Copyright (C) 2018-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_crypto_win.c -- Windows Crypto API wrapper. zip_crypto_win.c -- Windows Crypto API wrapper.
Copyright (C) 2018-2021 Dieter Baron and Thomas Klausner Copyright (C) 2018-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>
@ -37,9 +37,6 @@
#include "zip_crypto.h" #include "zip_crypto.h"
#define WIN32_LEAN_AND_MEAN
#define NOCRYPT
#include <windows.h> #include <windows.h>
#include <bcrypt.h> #include <bcrypt.h>

View File

@ -1,6 +1,6 @@
/* /*
zip_crypto_win.h -- Windows Crypto API wrapper. zip_crypto_win.h -- Windows Crypto API wrapper.
Copyright (C) 2018-2021 Dieter Baron and Thomas Klausner Copyright (C) 2018-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_delete.c -- delete file from zip archive zip_delete.c -- delete file from zip archive
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_dir_add.c -- add directory zip_dir_add.c -- add directory
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_dirent.c -- read directory entry (local or central), clean dirent zip_dirent.c -- read directory entry (local or central), clean dirent
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>
@ -39,9 +39,10 @@
#include <time.h> #include <time.h>
#include <zlib.h> #include <zlib.h>
#include "zip.h"
#include "zipint.h" #include "zipint.h"
static zip_string_t *_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str); static zip_string_t *_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str, bool check_consistency);
static zip_extra_field_t *_zip_ef_utf8(zip_uint16_t, zip_string_t *, zip_error_t *); static zip_extra_field_t *_zip_ef_utf8(zip_uint16_t, zip_string_t *, zip_error_t *);
static bool _zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error); static bool _zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error);
@ -50,8 +51,9 @@ void
_zip_cdir_free(zip_cdir_t *cd) { _zip_cdir_free(zip_cdir_t *cd) {
zip_uint64_t i; zip_uint64_t i;
if (!cd) if (cd == NULL) {
return; return;
}
for (i = 0; i < cd->nentry; i++) for (i = 0; i < cd->nentry; i++)
_zip_entry_finalize(cd->entry + i); _zip_entry_finalize(cd->entry + i);
@ -62,7 +64,7 @@ _zip_cdir_free(zip_cdir_t *cd) {
zip_cdir_t * zip_cdir_t *
_zip_cdir_new(zip_uint64_t nentry, zip_error_t *error) { _zip_cdir_new(zip_error_t *error) {
zip_cdir_t *cd; zip_cdir_t *cd;
if ((cd = (zip_cdir_t *)malloc(sizeof(*cd))) == NULL) { if ((cd = (zip_cdir_t *)malloc(sizeof(*cd))) == NULL) {
@ -76,11 +78,6 @@ _zip_cdir_new(zip_uint64_t nentry, zip_error_t *error) {
cd->comment = NULL; cd->comment = NULL;
cd->is_zip64 = false; cd->is_zip64 = false;
if (!_zip_cdir_grow(cd, nentry, error)) {
_zip_cdir_free(cd);
return NULL;
}
return cd; return cd;
} }
@ -126,8 +123,6 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor
zip_buffer_t *buffer; zip_buffer_t *buffer;
zip_int64_t off; zip_int64_t off;
zip_uint64_t i; zip_uint64_t i;
bool is_zip64;
int ret;
zip_uint32_t cdir_crc; zip_uint32_t cdir_crc;
if ((off = zip_source_tell_write(za->src)) < 0) { if ((off = zip_source_tell_write(za->src)) < 0) {
@ -136,8 +131,6 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor
} }
offset = (zip_uint64_t)off; offset = (zip_uint64_t)off;
is_zip64 = false;
if (ZIP_WANT_TORRENTZIP(za)) { if (ZIP_WANT_TORRENTZIP(za)) {
cdir_crc = (zip_uint32_t)crc32(0, NULL, 0); cdir_crc = (zip_uint32_t)crc32(0, NULL, 0);
za->write_crc = &cdir_crc; za->write_crc = &cdir_crc;
@ -146,10 +139,10 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor
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;
if ((ret = _zip_dirent_write(za, entry->changes ? entry->changes : entry->orig, ZIP_FL_CENTRAL)) < 0) if (_zip_dirent_write(za, entry->changes ? entry->changes : entry->orig, ZIP_FL_CENTRAL) < 0) {
za->write_crc = NULL;
return -1; return -1;
if (ret) }
is_zip64 = true;
} }
za->write_crc = NULL; za->write_crc = NULL;
@ -160,16 +153,12 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor
} }
size = (zip_uint64_t)off - offset; size = (zip_uint64_t)off - offset;
if (offset > ZIP_UINT32_MAX || survivors > ZIP_UINT16_MAX) {
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);
return -1; return -1;
} }
if (is_zip64) { if (survivors > ZIP_UINT16_MAX || offset > ZIP_UINT32_MAX || size > ZIP_UINT32_MAX) {
_zip_buffer_put(buffer, EOCD64_MAGIC, 4); _zip_buffer_put(buffer, EOCD64_MAGIC, 4);
_zip_buffer_put_64(buffer, EOCD64LEN - 12); _zip_buffer_put_64(buffer, EOCD64LEN - 12);
_zip_buffer_put_16(buffer, 45); _zip_buffer_put_16(buffer, 45);
@ -298,7 +287,8 @@ _zip_dirent_init(zip_dirent_t *de) {
de->version_needed = 10; /* 1.0 */ de->version_needed = 10; /* 1.0 */
de->bitflags = 0; de->bitflags = 0;
de->comp_method = ZIP_CM_DEFAULT; de->comp_method = ZIP_CM_DEFAULT;
de->last_mod = 0; de->last_mod.date = 0;
de->last_mod.time = 0;
de->crc = 0; de->crc = 0;
de->comp_size = 0; de->comp_size = 0;
de->uncomp_size = 0; de->uncomp_size = 0;
@ -336,7 +326,7 @@ _zip_dirent_new(void) {
} }
/* _zip_dirent_read(zde, fp, bufp, left, localp, error): /*
Fills the zip directory entry zde. Fills the zip directory entry zde.
If buffer is non-NULL, data is taken from there; otherwise data is read from fp as needed. If buffer is non-NULL, data is taken from there; otherwise data is read from fp as needed.
@ -347,11 +337,12 @@ _zip_dirent_new(void) {
*/ */
zip_int64_t 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_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, bool local, zip_uint64_t central_compressed_size, bool check_consistency, zip_error_t *error) {
zip_uint8_t buf[CDENTRYSIZE]; zip_uint8_t buf[CDENTRYSIZE];
zip_uint16_t dostime, dosdate;
zip_uint32_t size, variable_size; zip_uint32_t size, variable_size;
zip_uint16_t filename_len, comment_len, ef_len; zip_uint16_t filename_len, comment_len, ef_len;
zip_string_t *utf8_string;
bool is_zip64 = false;
bool from_buffer = (buffer != NULL); bool from_buffer = (buffer != NULL);
@ -389,9 +380,8 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
zde->comp_method = _zip_buffer_get_16(buffer); zde->comp_method = _zip_buffer_get_16(buffer);
/* convert to time_t */ /* convert to time_t */
dostime = _zip_buffer_get_16(buffer); zde->last_mod.time = _zip_buffer_get_16(buffer);
dosdate = _zip_buffer_get_16(buffer); zde->last_mod.date = _zip_buffer_get_16(buffer);
zde->last_mod = _zip_d2u_time(dostime, dosdate);
zde->crc = _zip_buffer_get_32(buffer); zde->crc = _zip_buffer_get_32(buffer);
zde->comp_size = _zip_buffer_get_32(buffer); zde->comp_size = _zip_buffer_get_32(buffer);
@ -458,7 +448,7 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
if (filename_len) { if (filename_len) {
zde->filename = _zip_read_string(buffer, src, filename_len, 1, error); zde->filename = _zip_read_string(buffer, src, filename_len, 1, error);
if (!zde->filename) { if (zde->filename == NULL) {
if (zip_error_code_zip(error) == ZIP_ER_EOF) { if (zip_error_code_zip(error) == ZIP_ER_EOF) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_VARIABLE_SIZE_OVERFLOW); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_VARIABLE_SIZE_OVERFLOW);
} }
@ -502,7 +492,7 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
if (comment_len) { if (comment_len) {
zde->comment = _zip_read_string(buffer, src, comment_len, 0, error); zde->comment = _zip_read_string(buffer, src, comment_len, 0, error);
if (!zde->comment) { if (zde->comment == NULL) {
if (!from_buffer) { if (!from_buffer) {
_zip_buffer_free(buffer); _zip_buffer_free(buffer);
} }
@ -519,8 +509,24 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
} }
} }
zde->filename = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_NAME, zde->filename); if ((utf8_string = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_NAME, zde->filename, check_consistency)) == NULL && zde->filename != NULL) {
zde->comment = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_COMMENT, zde->comment); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_UTF8_FILENAME_MISMATCH);
if (!from_buffer) {
_zip_buffer_free(buffer);
}
return -1;
}
zde->filename = utf8_string;
if (!local) {
if ((utf8_string = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_COMMENT, zde->comment, check_consistency)) == NULL && zde->comment != NULL) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_UTF8_COMMENT_MISMATCH);
if (!from_buffer) {
_zip_buffer_free(buffer);
}
return -1;
}
zde->comment = utf8_string;
}
/* Zip64 */ /* Zip64 */
@ -535,6 +541,7 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
return -1; return -1;
} }
} }
is_zip64 = true;
} }
@ -545,10 +552,40 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
} }
return -1; return -1;
} }
if (!from_buffer) { if (!from_buffer) {
_zip_buffer_free(buffer); _zip_buffer_free(buffer);
} }
if (local && zde->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) {
zip_uint32_t df_crc;
zip_uint64_t df_comp_size, df_uncomp_size;
if (zip_source_seek(src, central_compressed_size, SEEK_CUR) != 0 || (buffer = _zip_buffer_new_from_source(src, MAX_DATA_DESCRIPTOR_LENGTH, buf, error)) == NULL) {
return -1;
}
if (memcmp(_zip_buffer_peek(buffer, MAGIC_LEN), DATADES_MAGIC, MAGIC_LEN) == 0) {
_zip_buffer_skip(buffer, MAGIC_LEN);
}
df_crc = _zip_buffer_get_32(buffer);
df_comp_size = is_zip64 ? _zip_buffer_get_64(buffer) : _zip_buffer_get_32(buffer);
df_uncomp_size = is_zip64 ? _zip_buffer_get_64(buffer) : _zip_buffer_get_32(buffer);
if (!_zip_buffer_ok(buffer)) {
zip_error_set(error, ZIP_ER_INTERNAL, 0);
_zip_buffer_free(buffer);
return -1;
}
_zip_buffer_free(buffer);
if ((zde->crc != 0 && zde->crc != df_crc) || (zde->comp_size != 0 && zde->comp_size != df_comp_size) || (zde->uncomp_size != 0 && zde->uncomp_size != df_uncomp_size)) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_DATA_DESCRIPTOR_MISMATCH);
return -1;
}
zde->crc = df_crc;
zde->comp_size = df_comp_size;
zde->uncomp_size = df_uncomp_size;
}
/* zip_source_seek / zip_source_tell don't support values > ZIP_INT64_MAX */ /* zip_source_seek / zip_source_tell don't support values > ZIP_INT64_MAX */
if (zde->offset > ZIP_INT64_MAX) { if (zde->offset > ZIP_INT64_MAX) {
zip_error_set(error, ZIP_ER_SEEK, EFBIG); zip_error_set(error, ZIP_ER_SEEK, EFBIG);
@ -564,7 +601,8 @@ _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) { 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; zip_buffer_t *ef_buffer;
if ((ef_buffer = _zip_buffer_new((zip_uint8_t *)ef, got_len)) == NULL) { if ((ef_buffer = _zip_buffer_new((zip_uint8_t *)ef, got_len)) == NULL) {
@ -625,7 +663,7 @@ bool zip_dirent_process_ef_zip64(zip_dirent_t* zde, const zip_uint8_t* ef, zip_u
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, bool check_consistency) {
zip_uint16_t ef_len; zip_uint16_t ef_len;
zip_uint32_t ef_crc; zip_uint32_t ef_crc;
zip_buffer_t *buffer; zip_buffer_t *buffer;
@ -648,6 +686,14 @@ _zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string
zip_string_t *ef_str = _zip_string_new(_zip_buffer_get(buffer, len), len, ZIP_FL_ENC_UTF_8, NULL); zip_string_t *ef_str = _zip_string_new(_zip_buffer_get(buffer, len), len, ZIP_FL_ENC_UTF_8, NULL);
if (ef_str != NULL) { if (ef_str != NULL) {
if (check_consistency) {
if (!_zip_string_equal(str, ef_str) && _zip_string_is_ascii(ef_str)) {
_zip_string_free(ef_str);
_zip_buffer_free(buffer);
return NULL;
}
}
_zip_string_free(str); _zip_string_free(str);
str = ef_str; str = ef_str;
} }
@ -688,18 +734,18 @@ _zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error) {
crc_valid = true; crc_valid = true;
switch (_zip_buffer_get_16(buffer)) { switch (_zip_buffer_get_16(buffer)) {
case 1: case 1:
break; break;
case 2: case 2:
crc_valid = false; crc_valid = false;
/* TODO: When checking consistency, check that crc is 0. */ /* TODO: When checking consistency, check that crc is 0. */
break; break;
default: default:
zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0); zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0);
_zip_buffer_free(buffer); _zip_buffer_free(buffer);
return false; return false;
} }
/* vendor */ /* vendor */
@ -787,7 +833,7 @@ _zip_dirent_size(zip_source_t *src, zip_uint16_t flags, zip_error_t *error) {
int int
_zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) { _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) {
zip_uint16_t dostime, dosdate; zip_dostime_t dostime;
zip_encoding_type_t com_enc, name_enc; zip_encoding_type_t com_enc, name_enc;
zip_extra_field_t *ef; zip_extra_field_t *ef;
zip_extra_field_t *ef64; zip_extra_field_t *ef64;
@ -926,14 +972,14 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) {
} }
if (ZIP_WANT_TORRENTZIP(za)) { if (ZIP_WANT_TORRENTZIP(za)) {
dostime = 0xbc00; dostime.time = 0xbc00;
dosdate = 0x2198; dostime.date = 0x2198;
} }
else { else {
_zip_u2d_time(de->last_mod, &dostime, &dosdate); dostime = de->last_mod;
} }
_zip_buffer_put_16(buffer, dostime); _zip_buffer_put_16(buffer, dostime.time);
_zip_buffer_put_16(buffer, dosdate); _zip_buffer_put_16(buffer, dostime.date);
if (is_winzip_aes && de->uncomp_size < 20) { if (is_winzip_aes && de->uncomp_size < 20) {
_zip_buffer_put_32(buffer, 0); _zip_buffer_put_32(buffer, 0);
@ -1034,7 +1080,7 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) {
time_t time_t
_zip_d2u_time(zip_uint16_t dtime, zip_uint16_t ddate) { _zip_d2u_time(const zip_dostime_t *dtime) {
struct tm tm; struct tm tm;
memset(&tm, 0, sizeof(tm)); memset(&tm, 0, sizeof(tm));
@ -1042,13 +1088,13 @@ _zip_d2u_time(zip_uint16_t dtime, zip_uint16_t ddate) {
/* let mktime decide if DST is in effect */ /* let mktime decide if DST is in effect */
tm.tm_isdst = -1; tm.tm_isdst = -1;
tm.tm_year = ((ddate >> 9) & 127) + 1980 - 1900; tm.tm_year = ((dtime->date >> 9) & 127) + 1980 - 1900;
tm.tm_mon = ((ddate >> 5) & 15) - 1; tm.tm_mon = ((dtime->date >> 5) & 15) - 1;
tm.tm_mday = ddate & 31; tm.tm_mday = dtime->date & 31;
tm.tm_hour = (dtime >> 11) & 31; tm.tm_hour = (dtime->time >> 11) & 31;
tm.tm_min = (dtime >> 5) & 63; tm.tm_min = (dtime->time >> 5) & 63;
tm.tm_sec = (dtime << 1) & 62; tm.tm_sec = (dtime->time << 1) & 62;
return mktime(&tm); return mktime(&tm);
} }
@ -1119,23 +1165,28 @@ _zip_get_dirent(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_error_t *err
} }
void int
_zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate) { _zip_u2d_time(time_t intime, zip_dostime_t *dtime, zip_error_t *ze) {
struct tm *tpm; struct tm *tpm;
struct tm tm; struct tm tm;
tpm = zip_localtime(&intime, &tm); tpm = zip_localtime(&intime, &tm);
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; dtime->date = (1 << 5) + 1;
*dtime = 0; dtime->time = 0;
return; if (ze) {
zip_error_set(ze, ZIP_ER_INVAL, errno);
}
return -1;
} }
if (tpm->tm_year < 80) { if (tpm->tm_year < 80) {
tpm->tm_year = 80; tpm->tm_year = 80;
} }
*ddate = (zip_uint16_t)(((tpm->tm_year + 1900 - 1980) << 9) + ((tpm->tm_mon + 1) << 5) + tpm->tm_mday); dtime->date = (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->time = (zip_uint16_t)(((tpm->tm_hour) << 11) + ((tpm->tm_min) << 5) + ((tpm->tm_sec) >> 1));
return 0;
} }
@ -1192,10 +1243,11 @@ _zip_dirent_apply_attributes(zip_dirent_t *de, zip_file_attributes_t *attributes
Set values suitable for torrentzip. Set values suitable for torrentzip.
*/ */
void zip_dirent_torrentzip_normalize(zip_dirent_t *de) { void
zip_dirent_torrentzip_normalize(zip_dirent_t *de) {
de->version_madeby = 0; de->version_madeby = 0;
de->version_needed = 20; /* 2.0 */ de->version_needed = 20; /* 2.0 */
de->bitflags = 2; /* maximum compression */ de->bitflags = 2; /* maximum compression */
de->comp_method = ZIP_CM_DEFLATE; de->comp_method = ZIP_CM_DEFLATE;
de->compression_level = TORRENTZIP_COMPRESSION_FLAGS; de->compression_level = TORRENTZIP_COMPRESSION_FLAGS;
de->disk_number = 0; de->disk_number = 0;
@ -1203,5 +1255,12 @@ void zip_dirent_torrentzip_normalize(zip_dirent_t *de) {
de->ext_attrib = 0; de->ext_attrib = 0;
/* last_mod, extra_fields, and comment are normalized in zip_dirent_write() directly */ /* last_mod, extra_fields, and comment are normalized in zip_dirent_write() directly */
}
int
zip_dirent_check_consistency(zip_dirent_t *dirent) {
if (dirent->comp_method == ZIP_CM_STORE && dirent->comp_size != dirent->uncomp_size) {
return ZIP_ER_DETAIL_STORED_SIZE_MISMATCH;
}
return 0;
} }

View File

@ -1,6 +1,6 @@
/* /*
zip_discard.c -- discard and free struct zip zip_discard.c -- discard and free struct zip
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_entry.c -- struct zip_entry helper functions zip_entry.c -- struct zip_entry helper functions
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_error.c -- zip_error_t helper functions zip_error.c -- zip_error_t helper functions
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_error_clear.c -- clear zip error zip_error_clear.c -- clear zip error
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_error_get.c -- get zip error zip_error_get.c -- get zip error
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_error_get_sys_type.c -- return type of system error code zip_error_get_sys_type.c -- return type of system error code
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_error_sterror.c -- get string representation of struct zip_error zip_error_sterror.c -- get string representation of struct zip_error
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>
@ -49,6 +49,9 @@ zip_error_strerror(zip_error_t *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) {
system_error_buffer = (char *)malloc(128); system_error_buffer = (char *)malloc(128);
if (system_error_buffer == NULL) {
return _zip_err_str[ZIP_ER_MEMORY].description;
}
snprintf_s(system_error_buffer, 128, "Unknown error %d", err->zip_err); snprintf_s(system_error_buffer, 128, "Unknown error %d", err->zip_err);
system_error_buffer[128 - 1] = '\0'; /* make sure string is NUL-terminated */ system_error_buffer[128 - 1] = '\0'; /* make sure string is NUL-terminated */
zip_error_string = NULL; zip_error_string = NULL;
@ -61,6 +64,9 @@ zip_error_strerror(zip_error_t *err) {
case ZIP_ET_SYS: { case ZIP_ET_SYS: {
size_t len = strerrorlen_s(err->sys_err) + 1; size_t len = strerrorlen_s(err->sys_err) + 1;
system_error_buffer = malloc(len); system_error_buffer = malloc(len);
if (system_error_buffer == NULL) {
return _zip_err_str[ZIP_ER_MEMORY].description;
}
strerror_s(system_error_buffer, len, err->sys_err); strerror_s(system_error_buffer, len, err->sys_err);
system_error_string = system_error_buffer; system_error_string = system_error_buffer;
break; break;
@ -79,12 +85,18 @@ zip_error_strerror(zip_error_t *err) {
} }
else if (error >= _zip_err_details_count) { else if (error >= _zip_err_details_count) {
system_error_buffer = (char *)malloc(128); system_error_buffer = (char *)malloc(128);
if (system_error_buffer == NULL) {
return _zip_err_str[ZIP_ER_MEMORY].description;
}
snprintf_s(system_error_buffer, 128, "invalid detail error %u", error); snprintf_s(system_error_buffer, 128, "invalid detail error %u", error);
system_error_buffer[128 - 1] = '\0'; /* make sure string is NUL-terminated */ system_error_buffer[128 - 1] = '\0'; /* make sure string is NUL-terminated */
system_error_string = system_error_buffer; 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) {
system_error_buffer = (char *)malloc(128); system_error_buffer = (char *)malloc(128);
if (system_error_buffer == NULL) {
return _zip_err_str[ZIP_ER_MEMORY].description;
}
snprintf_s(system_error_buffer, 128, "entry %d: %s", index, _zip_err_details[error].description); snprintf_s(system_error_buffer, 128, "entry %d: %s", index, _zip_err_details[error].description);
system_error_buffer[128 - 1] = '\0'; /* make sure string is NUL-terminated */ system_error_buffer[128 - 1] = '\0'; /* make sure string is NUL-terminated */
system_error_string = system_error_buffer; system_error_string = system_error_buffer;

View File

@ -1,6 +1,6 @@
/* /*
zip_error_to_str.c -- get string representation of zip error code zip_error_to_str.c -- get string representation of zip error code
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_extra_field.c -- manipulate extra fields zip_extra_field.c -- manipulate extra fields
Copyright (C) 2012-2021 Dieter Baron and Thomas Klausner Copyright (C) 2012-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_extra_field_api.c -- public extra fields API functions zip_extra_field_api.c -- public extra fields API functions
Copyright (C) 2012-2021 Dieter Baron and Thomas Klausner Copyright (C) 2012-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>
@ -56,10 +56,6 @@ 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;

View File

@ -1,6 +1,6 @@
/* /*
zip_fclose.c -- close file in zip archive zip_fclose.c -- close file in zip archive
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_fdopen.c -- open read-only archive from file descriptor zip_fdopen.c -- open read-only archive from file descriptor
Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner Copyright (C) 2009-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_file_add.c -- add file via callback function zip_file_add.c -- add file via callback function
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_file_error_clear.c -- clear zip file error zip_file_error_clear.c -- clear zip file error
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_file_error_get.c -- get zip file error zip_file_error_get.c -- get zip file error
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_file_get_comment.c -- get file comment zip_file_get_comment.c -- get file comment
Copyright (C) 2006-2021 Dieter Baron and Thomas Klausner Copyright (C) 2006-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_file_get_external_attributes.c -- get opsys/external attributes zip_file_get_external_attributes.c -- get opsys/external attributes
Copyright (C) 2013-2021 Dieter Baron and Thomas Klausner Copyright (C) 2013-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_file_get_offset.c -- get offset of file data in archive. zip_file_get_offset.c -- get offset of file data in archive.
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_file_rename.c -- rename file in zip archive zip_file_rename.c -- rename file in zip archive
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_file_replace.c -- replace file via callback function zip_file_replace.c -- replace file via callback function
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>
@ -83,6 +83,12 @@ _zip_file_replace(zip_t *za, zip_uint64_t idx, const char *name, zip_source_t *s
return -1; return -1;
} }
/* delete all extra fields - these are usually data that are
* strongly coupled with the original data */
if (zip_file_extra_field_delete(za, idx, ZIP_EXTRA_FIELD_ALL, ZIP_FL_CENTRAL | ZIP_FL_LOCAL) < 0) {
return -1;
}
/* does not change any name related data, so we can do it here; /* does not change any name related data, so we can do it here;
* needed for a double add of the same file name */ * needed for a double add of the same file name */
_zip_unchange_data(za->entry + idx); _zip_unchange_data(za->entry + idx);

View File

@ -1,6 +1,6 @@
/* /*
zip_file_set_comment.c -- set comment for file in archive zip_file_set_comment.c -- set comment for file in archive
Copyright (C) 2006-2021 Dieter Baron and Thomas Klausner Copyright (C) 2006-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_file_set_encryption.c -- set encryption for file in archive zip_file_set_encryption.c -- set encryption for file in archive
Copyright (C) 2016-2021 Dieter Baron and Thomas Klausner Copyright (C) 2016-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_file_set_external_attributes.c -- set external attributes for entry zip_file_set_external_attributes.c -- set external attributes for entry
Copyright (C) 2013-2021 Dieter Baron and Thomas Klausner Copyright (C) 2013-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_file_set_mtime.c -- set modification time of entry. zip_file_set_mtime.c -- set modification time of entry.
Copyright (C) 2014-2022 Dieter Baron and Thomas Klausner Copyright (C) 2014-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>
@ -35,17 +35,11 @@
ZIP_EXTERN int ZIP_EXTERN int
zip_file_set_dostime(zip_t *za, zip_uint64_t idx, zip_uint16_t dtime, zip_uint16_t ddate, zip_flags_t flags) { zip_file_set_dostime(zip_t *za, zip_uint64_t idx, zip_uint16_t dtime, zip_uint16_t ddate, zip_flags_t flags) {
time_t mtime;
mtime = _zip_d2u_time(dtime, ddate);
return zip_file_set_mtime(za, idx, mtime, flags);
}
ZIP_EXTERN int
zip_file_set_mtime(zip_t *za, zip_uint64_t idx, time_t mtime, zip_flags_t flags) {
zip_entry_t *e; zip_entry_t *e;
if (_zip_get_dirent(za, idx, 0, NULL) == NULL) if (_zip_get_dirent(za, idx, 0, NULL) == NULL) {
return -1; return -1;
}
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);
@ -70,8 +64,20 @@ zip_file_set_mtime(zip_t *za, zip_uint64_t idx, time_t mtime, zip_flags_t flags)
} }
} }
e->changes->last_mod = mtime; e->changes->last_mod.time = dtime;
e->changes->last_mod.date = ddate;
e->changes->changed |= ZIP_DIRENT_LAST_MOD; e->changes->changed |= ZIP_DIRENT_LAST_MOD;
return 0; return 0;
} }
ZIP_EXTERN int
zip_file_set_mtime(zip_t *za, zip_uint64_t idx, time_t mtime, zip_flags_t flags) {
zip_dostime_t dostime;
if (_zip_u2d_time(mtime, &dostime, &za->error) < 0) {
return -1;
}
return zip_file_set_dostime(za, idx, dostime.time, dostime.date, flags);
}

View File

@ -1,6 +1,6 @@
/* /*
zip_file_sterror.c -- get string representation of zip file error zip_file_sterror.c -- get string representation of zip file error
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_fopen.c -- open file in zip archive for reading zip_fopen.c -- open file in zip archive for reading
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_fopen_encrypted.c -- open file for reading with password zip_fopen_encrypted.c -- open file for reading with password
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_fopen_index.c -- open file in zip archive for reading by index zip_fopen_index.c -- open file in zip archive for reading by index
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_fopen_index_encrypted.c -- open file for reading by index w/ password zip_fopen_index_encrypted.c -- open file for reading by index w/ password
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_fread.c -- read from file zip_fread.c -- read from file
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>
@ -39,11 +39,13 @@ ZIP_EXTERN zip_int64_t
zip_fread(zip_file_t *zf, void *outbuf, zip_uint64_t toread) { zip_fread(zip_file_t *zf, void *outbuf, zip_uint64_t toread) {
zip_int64_t n; zip_int64_t n;
if (!zf) if (zf == NULL) {
return -1; return -1;
}
if (zf->error.zip_err != 0) if (zf->error.zip_err != 0) {
return -1; return -1;
}
if (toread > ZIP_INT64_MAX) { if (toread > ZIP_INT64_MAX) {
zip_error_set(&zf->error, ZIP_ER_INVAL, 0); zip_error_set(&zf->error, ZIP_ER_INVAL, 0);

View File

@ -1,6 +1,6 @@
/* /*
zip_fseek.c -- seek in file zip_fseek.c -- seek in file
Copyright (C) 2016-2021 Dieter Baron and Thomas Klausner Copyright (C) 2016-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>
@ -36,11 +36,13 @@
ZIP_EXTERN zip_int8_t ZIP_EXTERN zip_int8_t
zip_fseek(zip_file_t *zf, zip_int64_t offset, int whence) { zip_fseek(zip_file_t *zf, zip_int64_t offset, int whence) {
if (!zf) if (zf == NULL) {
return -1; return -1;
}
if (zf->error.zip_err != 0) if (zf->error.zip_err != 0) {
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);
@ -53,7 +55,7 @@ zip_fseek(zip_file_t *zf, zip_int64_t offset, int whence) {
ZIP_EXTERN int ZIP_EXTERN int
zip_file_is_seekable(zip_file_t *zfile) { zip_file_is_seekable(zip_file_t *zfile) {
if (!zfile) { if (zfile == NULL) {
return -1; return -1;
} }

View File

@ -1,6 +1,6 @@
/* /*
zip_ftell.c -- tell position in file zip_ftell.c -- tell position in file
Copyright (C) 2016-2021 Dieter Baron and Thomas Klausner Copyright (C) 2016-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>
@ -38,11 +38,13 @@ ZIP_EXTERN zip_int64_t
zip_ftell(zip_file_t *zf) { zip_ftell(zip_file_t *zf) {
zip_int64_t res; zip_int64_t res;
if (!zf) if (zf == NULL) {
return -1; return -1;
}
if (zf->error.zip_err != 0) if (zf->error.zip_err != 0) {
return -1; return -1;
}
res = zip_source_tell(zf->src); res = zip_source_tell(zf->src);
if (res < 0) { if (res < 0) {

View File

@ -1,6 +1,6 @@
/* /*
zip_get_archive_comment.c -- get archive comment zip_get_archive_comment.c -- get archive comment
Copyright (C) 2006-2021 Dieter Baron and Thomas Klausner Copyright (C) 2006-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_get_archive_flag.c -- get archive global flag zip_get_archive_flag.c -- get archive global flag
Copyright (C) 2008-2021 Dieter Baron and Thomas Klausner Copyright (C) 2008-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_get_encryption_implementation.c -- get encryption implementation zip_get_encryption_implementation.c -- get encryption implementation
Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner Copyright (C) 2009-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_get_file_comment.c -- get file comment zip_get_file_comment.c -- get file comment
Copyright (C) 2006-2021 Dieter Baron and Thomas Klausner Copyright (C) 2006-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_get_name.c -- get filename for a file in zip file zip_get_name.c -- get filename for a file in zip file
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_get_num_entries.c -- get number of entries in archive zip_get_num_entries.c -- get number of entries in archive
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_get_num_files.c -- get number of files in archive zip_get_num_files.c -- get number of files in archive
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_hash.c -- hash table string -> uint64 zip_hash.c -- hash table string -> uint64
Copyright (C) 2015-2021 Dieter Baron and Thomas Klausner Copyright (C) 2015-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_io_util.c -- I/O helper functions zip_io_util.c -- I/O helper functions
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>
@ -70,7 +70,7 @@ _zip_read_data(zip_buffer_t *buffer, zip_source_t *src, size_t length, bool nulp
} }
r = (zip_uint8_t *)malloc(length + (nulp ? 1 : 0)); r = (zip_uint8_t *)malloc(length + (nulp ? 1 : 0));
if (!r) { if (r == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0); zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL; return NULL;
} }

View File

@ -1,6 +1,6 @@
/* /*
zip_libzip_version.c -- return run-time version of library zip_libzip_version.c -- return run-time version of library
Copyright (C) 2017-2021 Dieter Baron and Thomas Klausner Copyright (C) 2017-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_memdup.c -- internal zip function, "strdup" with len zip_memdup.c -- internal zip function, "strdup" with len
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>
@ -45,7 +45,7 @@ _zip_memdup(const void *mem, size_t len, zip_error_t *error) {
return NULL; return NULL;
ret = malloc(len); ret = malloc(len);
if (!ret) { if (ret == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0); zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL; return NULL;
} }

View File

@ -1,6 +1,6 @@
/* /*
zip_new.c -- create and init struct zip zip_new.c -- create and init struct zip
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>
@ -46,7 +46,7 @@ _zip_new(zip_error_t *error) {
zip_t *za; zip_t *za;
za = (zip_t *)malloc(sizeof(struct zip)); za = (zip_t *)malloc(sizeof(struct zip));
if (!za) { if (za == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0); zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL; return NULL;
} }

View File

@ -1,6 +1,6 @@
/* /*
zip_open.c -- open zip archive by name zip_open.c -- open zip archive by name
Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner Copyright (C) 1999-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>
@ -31,7 +31,6 @@
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <limits.h> #include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -39,17 +38,30 @@
#include "zipint.h" #include "zipint.h"
typedef enum { EXISTS_ERROR = -1, EXISTS_NOT = 0, EXISTS_OK } exists_t; typedef enum {
EXISTS_ERROR = -1,
EXISTS_NOT = 0,
EXISTS_OK
} exists_t;
typedef enum {
CDIR_OK,
CDIR_INVALID,
CDIR_NOT_FOUND
} cdir_status_t;
static bool check_eocd(zip_cdir_t *cd, unsigned int flags, zip_error_t *error);
static bool check_magic(zip_uint64_t offset, zip_buffer_t *buffer, zip_uint64_t buffer_offset, zip_source_t *src, const char* magic);
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 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 const unsigned char *_zip_memmem(const unsigned char *, size_t, const unsigned char *, size_t); static bool _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_cdir_t **cdirp, 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, 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 cdir_status_t _zip_read_eocd64(zip_cdir_t *cdir, 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); static const unsigned char *find_eocd(zip_buffer_t *buffer, const unsigned char *last);
ZIP_EXTERN zip_t * ZIP_EXTERN zip_t *
@ -144,6 +156,27 @@ zip_open_from_source(zip_source_t *src, int _flags, zip_error_t *error) {
} }
static bool
_is_truncated_zip(zip_source_t *src) {
unsigned char data[4];
/* check if the source is a truncated zip archive: true if yes, no
if not or can't be determined */
if (zip_source_seek(src, 0, SEEK_SET) < 0) {
return false;
}
if (zip_source_read(src, data, 4) != 4) {
return false;
}
if (memcmp(data, LOCAL_MAGIC, 4) == 0) {
/* file starts with a ZIP local header signature */
return true;
}
return false;
}
zip_t * zip_t *
_zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error) { _zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error) {
zip_t *za; zip_t *za;
@ -174,6 +207,12 @@ _zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error) {
if ((cdir = _zip_find_central_dir(za, len)) == NULL) { if ((cdir = _zip_find_central_dir(za, len)) == NULL) {
_zip_error_copy(error, &za->error); _zip_error_copy(error, &za->error);
if (zip_error_code_zip(error) == ZIP_ER_NOZIP) {
/* not a zip - find out if it's truncated */
if (_is_truncated_zip(src)) {
zip_error_set(error, ZIP_ER_TRUNCATED_ZIP, 0);
}
}
/* keep src so discard does not get rid of it */ /* keep src so discard does not get rid of it */
zip_source_keep(src); zip_source_keep(src);
zip_discard(za); zip_discard(za);
@ -228,14 +267,14 @@ void
_zip_set_open_error(int *zep, const zip_error_t *err, int ze) { _zip_set_open_error(int *zep, const zip_error_t *err, int ze) {
if (err) { if (err) {
ze = zip_error_code_zip(err); ze = zip_error_code_zip(err);
switch (zip_error_system_type(err)) { switch (zip_error_system_type(err)) {
case ZIP_ET_SYS: case ZIP_ET_SYS:
case ZIP_ET_LIBZIP: case ZIP_ET_LIBZIP:
errno = zip_error_code_system(err); errno = zip_error_code_system(err);
break; break;
default: default:
break; break;
} }
} }
@ -250,37 +289,67 @@ _zip_set_open_error(int *zep, const zip_error_t *err, int ze) {
Returns a struct zip_cdir which contains the central directory Returns a struct zip_cdir which contains the central directory
entries, or NULL if unsuccessful. */ entries, or NULL if unsuccessful. */
static zip_cdir_t * static bool _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_cdir_t **cdirp, zip_error_t *error) {
_zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_error_t *error) {
zip_cdir_t *cd; zip_cdir_t *cd;
zip_uint16_t comment_len; zip_uint16_t comment_len;
zip_uint64_t i, left; zip_uint64_t i, left;
zip_uint64_t eocd_offset = _zip_buffer_offset(buffer); zip_uint64_t eocd_offset = _zip_buffer_offset(buffer);
zip_buffer_t *cd_buffer; zip_buffer_t *cd_buffer;
bool eocd64_found = false;
if (_zip_buffer_left(buffer) < EOCDLEN) { *cdirp = NULL;
/* not enough bytes left for comment */
zip_error_set(error, ZIP_ER_NOZIP, 0);
return NULL;
}
/* check for end-of-central-dir magic */ if ((cd = _zip_read_eocd(buffer, buf_offset, error)) == NULL) {
if (memcmp(_zip_buffer_get(buffer, 4), EOCD_MAGIC, 4) != 0) { return false;
zip_error_set(error, ZIP_ER_NOZIP, 0);
return NULL;
} }
if (eocd_offset >= EOCD64LOCLEN && memcmp(_zip_buffer_data(buffer) + eocd_offset - EOCD64LOCLEN, EOCD64LOC_MAGIC, 4) == 0) { if (eocd_offset >= EOCD64LOCLEN && memcmp(_zip_buffer_data(buffer) + eocd_offset - EOCD64LOCLEN, EOCD64LOC_MAGIC, 4) == 0) {
eocd64_found = true;
_zip_buffer_set_offset(buffer, eocd_offset - EOCD64LOCLEN); _zip_buffer_set_offset(buffer, eocd_offset - EOCD64LOCLEN);
cd = _zip_read_eocd64(za->src, buffer, buf_offset, za->flags, error); switch (_zip_read_eocd64(cd, za->src, buffer, buf_offset, za->flags, error)) {
} case CDIR_OK:
else { break;
_zip_buffer_set_offset(buffer, eocd_offset);
cd = _zip_read_eocd(buffer, buf_offset, za->flags, error); case CDIR_INVALID:
_zip_cdir_free(cd);
return true;
case CDIR_NOT_FOUND:
_zip_cdir_free(cd);
return false;
}
} }
if (cd == NULL) if ((cd->eocd_disk != 0 || cd->this_disk != 0) && !eocd64_found && cd->eocd_disk != cd->this_disk) {
return NULL; /* If the central directory doesn't start on this disk, we can't check that offset is valid. Check as much as we can instead. */
if (cd->this_disk < cd->eocd_disk) {
/* Disks before the start of the central directory don't contain an EOCD. */
_zip_cdir_free(cd);
return false;
}
if (cd->size <= cd->eocd_offset) {
/* The complete central directory would fit on this disk. */
_zip_cdir_free(cd);
return false;
}
}
if (!eocd64_found) {
if (cd->this_disk == 0 && cd->eocd_disk == 0 && cd->eocd_offset == 0 && cd->offset == 0 && cd->num_entries == 0) {
/* An empty archive doesn't contain central directory entries. */
}
else if (!check_magic(cd->offset, buffer, buf_offset, za->src, CENTRAL_MAGIC)) {
_zip_cdir_free(cd);
return false;
}
}
/* We accept this EOCD as valid and won't search for an earlier one if it is unusable. */
if (!check_eocd(cd, za->flags, error)) {
_zip_cdir_free(cd);
return true;
}
_zip_buffer_set_offset(buffer, eocd_offset + 20); _zip_buffer_set_offset(buffer, eocd_offset + 20);
comment_len = _zip_buffer_get_16(buffer); comment_len = _zip_buffer_get_16(buffer);
@ -289,7 +358,7 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
/* cdir spans past EOCD record */ /* cdir spans past EOCD record */
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_OVERLAPS_EOCD); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_OVERLAPS_EOCD);
_zip_cdir_free(cd); _zip_cdir_free(cd);
return NULL; return true;
} }
if (comment_len || (za->open_flags & ZIP_CHECKCONS)) { if (comment_len || (za->open_flags & ZIP_CHECKCONS)) {
@ -298,16 +367,21 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
_zip_buffer_set_offset(buffer, eocd_offset + EOCDLEN); _zip_buffer_set_offset(buffer, eocd_offset + EOCDLEN);
tail_len = _zip_buffer_left(buffer); tail_len = _zip_buffer_left(buffer);
if (tail_len < comment_len || ((za->open_flags & ZIP_CHECKCONS) && tail_len != comment_len)) { if (tail_len != comment_len) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_COMMENT_LENGTH_INVALID); if (za->open_flags & ZIP_CHECKCONS) {
_zip_cdir_free(cd); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_COMMENT_LENGTH_INVALID);
return NULL; _zip_cdir_free(cd);
return true;
}
if (tail_len < comment_len) {
comment_len = tail_len;
}
} }
if (comment_len) { if (comment_len) {
if ((cd->comment = _zip_string_new(_zip_buffer_get(buffer, comment_len), comment_len, ZIP_FL_ENC_GUESS, error)) == NULL) { if ((cd->comment = _zip_string_new(_zip_buffer_get(buffer, comment_len), comment_len, ZIP_FL_ENC_GUESS, error)) == NULL) {
_zip_cdir_free(cd); _zip_cdir_free(cd);
return NULL; return true;
} }
} }
} }
@ -320,12 +394,12 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
if ((data = _zip_buffer_get(buffer, cd->size)) == NULL) { if ((data = _zip_buffer_get(buffer, cd->size)) == NULL) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_LENGTH_INVALID); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_LENGTH_INVALID);
_zip_cdir_free(cd); _zip_cdir_free(cd);
return NULL; return true;
} }
if ((cd_buffer = _zip_buffer_new(data, cd->size)) == NULL) { if ((cd_buffer = _zip_buffer_new(data, cd->size)) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0); zip_error_set(error, ZIP_ER_MEMORY, 0);
_zip_cdir_free(cd); _zip_cdir_free(cd);
return NULL; return true;
} }
} }
else { else {
@ -334,17 +408,22 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
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 true;
} }
/* possible consistency check: cd->offset = len-(cd->size+cd->comment_len+EOCDLEN) ? */ /* possible consistency check: cd->offset = len-(cd->size+cd->comment_len+EOCDLEN) ? */
if (zip_source_tell(za->src) != (zip_int64_t)cd->offset) { if (zip_source_tell(za->src) != (zip_int64_t)cd->offset) {
zip_error_set(error, ZIP_ER_NOZIP, 0); zip_error_set(error, ZIP_ER_NOZIP, 0);
_zip_cdir_free(cd); _zip_cdir_free(cd);
return NULL; return true;
} }
} }
if (!_zip_cdir_grow(cd, cd->num_entries, error)) {
_zip_cdir_free(cd);
_zip_buffer_free(cd_buffer);
return true;
}
left = (zip_uint64_t)cd->size; left = (zip_uint64_t)cd->size;
i = 0; i = 0;
while (left > 0) { while (left > 0) {
@ -362,31 +441,32 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
if (!_zip_cdir_grow(cd, 0x10000, error)) { if (!_zip_cdir_grow(cd, 0x10000, error)) {
_zip_cdir_free(cd); _zip_cdir_free(cd);
_zip_buffer_free(cd_buffer); _zip_buffer_free(cd_buffer);
return NULL; return true;
} }
grown = true; grown = true;
} }
if ((cd->entry[i].orig = _zip_dirent_new()) == NULL || (entry_size = _zip_dirent_read(cd->entry[i].orig, za->src, cd_buffer, false, error)) < 0) { if ((cd->entry[i].orig = _zip_dirent_new()) == NULL || (entry_size = _zip_dirent_read(cd->entry[i].orig, za->src, cd_buffer, false, 0, za->open_flags & ZIP_CHECKCONS, error)) < 0) {
if (zip_error_code_zip(error) == ZIP_ER_INCONS) { if (zip_error_code_zip(error) == ZIP_ER_INCONS) {
zip_error_set(error, ZIP_ER_INCONS, ADD_INDEX_TO_DETAIL(zip_error_code_system(error), i)); zip_error_set(error, ZIP_ER_INCONS, ADD_INDEX_TO_DETAIL(zip_error_code_system(error), i));
} }
else if (grown && zip_error_code_zip(error) == ZIP_ER_NOZIP) { else if (grown && zip_error_code_zip(error) == ZIP_ER_NOZIP) {
zip_error_set(error, ZIP_ER_INCONS, MAKE_DETAIL_WITH_INDEX(ZIP_ER_DETAIL_CDIR_ENTRY_INVALID, i)); zip_error_set(error, ZIP_ER_INCONS, MAKE_DETAIL_WITH_INDEX(ZIP_ER_DETAIL_CDIR_ENTRY_INVALID, i));
} }
_zip_cdir_free(cd); _zip_cdir_free(cd);
_zip_buffer_free(cd_buffer); _zip_buffer_free(cd_buffer);
return NULL; return true;
} }
i++; i++;
left -= (zip_uint64_t)entry_size; left -= (zip_uint64_t)entry_size;
} }
/* If we didn't fill all we grew, cd->num_entries was wrong. */
if (i != cd->nentry || left > 0) { if (i != cd->nentry || left > 0) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_WRONG_ENTRIES_COUNT); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_WRONG_ENTRIES_COUNT);
_zip_buffer_free(cd_buffer); _zip_buffer_free(cd_buffer);
_zip_cdir_free(cd); _zip_cdir_free(cd);
return NULL; return true;
} }
if (za->open_flags & ZIP_CHECKCONS) { if (za->open_flags & ZIP_CHECKCONS) {
@ -401,7 +481,7 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
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 true;
} }
ok = ((zip_uint64_t)offset == cd->offset + cd->size); ok = ((zip_uint64_t)offset == cd->offset + cd->size);
} }
@ -410,12 +490,32 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_LENGTH_INVALID); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_LENGTH_INVALID);
_zip_buffer_free(cd_buffer); _zip_buffer_free(cd_buffer);
_zip_cdir_free(cd); _zip_cdir_free(cd);
return NULL; return true;
} }
} }
_zip_buffer_free(cd_buffer); _zip_buffer_free(cd_buffer);
return cd; *cdirp = cd;
return true;
}
static bool check_magic(zip_uint64_t offset, zip_buffer_t *buffer, zip_uint64_t buffer_offset, zip_source_t *src, const char* magic) {
if (buffer_offset <= offset) {
zip_uint8_t* data;
if (_zip_buffer_set_offset(buffer, offset - buffer_offset) < 0 || (data = _zip_buffer_get(buffer, MAGIC_LEN)) == NULL) {
return false;
}
return memcmp(data, magic, MAGIC_LEN) == 0;
}
else {
zip_uint8_t data[MAGIC_LEN];
if (zip_source_seek(src, offset, SEEK_SET) < 0 || zip_source_read(src, data, MAGIC_LEN) != MAGIC_LEN) {
return false;
}
return memcmp(data, magic, MAGIC_LEN) == 0;
}
} }
@ -430,6 +530,7 @@ _zip_checkcons(zip_t *za, zip_cdir_t *cd, zip_error_t *error) {
zip_uint64_t i; zip_uint64_t i;
zip_uint64_t min, max, j; zip_uint64_t min, max, j;
struct zip_dirent temp; struct zip_dirent temp;
int detail;
_zip_dirent_init(&temp); _zip_dirent_init(&temp);
if (cd->nentry) { if (cd->nentry) {
@ -460,10 +561,10 @@ _zip_checkcons(zip_t *za, zip_cdir_t *cd, zip_error_t *error) {
return -1; return -1;
} }
if (_zip_dirent_read(&temp, za->src, NULL, true, error) == -1) { if (_zip_dirent_read(&temp, za->src, NULL, true, cd->entry[i].orig->comp_size, true, error) == -1) {
if (zip_error_code_zip(error) == ZIP_ER_INCONS) { if (zip_error_code_zip(error) == ZIP_ER_INCONS) {
zip_error_set(error, ZIP_ER_INCONS, ADD_INDEX_TO_DETAIL(zip_error_code_system(error), i)); zip_error_set(error, ZIP_ER_INCONS, ADD_INDEX_TO_DETAIL(zip_error_code_system(error), i));
} }
_zip_dirent_finalize(&temp); _zip_dirent_finalize(&temp);
return -1; return -1;
} }
@ -479,6 +580,11 @@ _zip_checkcons(zip_t *za, zip_cdir_t *cd, zip_error_t *error) {
temp.extra_fields = NULL; temp.extra_fields = NULL;
_zip_dirent_finalize(&temp); _zip_dirent_finalize(&temp);
if ((detail = zip_dirent_check_consistency(cd->entry[i].orig)) != 0) {
zip_error_set(error, ZIP_ER_INCONS, MAKE_DETAIL_WITH_INDEX(detail, i));
return -1;
}
} }
return (max - min) < ZIP_INT64_MAX ? (zip_int64_t)(max - min) : ZIP_INT64_MAX; return (max - min) < ZIP_INT64_MAX ? (zip_int64_t)(max - min) : ZIP_INT64_MAX;
@ -497,25 +603,23 @@ _zip_headercomp(const zip_dirent_t *central, const zip_dirent_t *local) {
and global headers for the bitflags */ and global headers for the bitflags */
|| (central->bitflags != local->bitflags) || (central->bitflags != local->bitflags)
#endif #endif
|| (central->comp_method != local->comp_method) || (central->last_mod != local->last_mod) || !_zip_string_equal(central->filename, local->filename)) || (central->comp_method != local->comp_method) || (central->last_mod.time != local->last_mod.time) || (central->last_mod.date != local->last_mod.date) || !_zip_string_equal(central->filename, local->filename))
return -1; return -1;
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.
macOS Archive sets the compressed size even when data descriptor is used ( but not the others), macOS Archive sets the compressed size even when data descriptor is used ( but not the others),
also in violation of the appnote. also in violation of the appnote.
*/ */
/* if data descriptor is not used, the values must match */ /* if data descriptor is not used, the values must match */
if ((local->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0) { 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 */ /* when using a data descriptor, the local header value must be zero or match */
if ((local->crc != 0 && central->crc != local->crc) || 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)) {
(local->comp_size != 0 && central->comp_size != local->comp_size) || return -1;
(local->uncomp_size != 0 && central->uncomp_size != local->uncomp_size)) { }
return -1;
}
} }
return 0; return 0;
@ -568,12 +672,10 @@ _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;
const 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 best;
zip_error_t error; zip_error_t error;
zip_buffer_t *buffer; zip_buffer_t *buffer;
@ -600,7 +702,6 @@ _zip_find_central_dir(zip_t *za, zip_uint64_t len) {
return NULL; return NULL;
} }
best = -1;
cdir = NULL; cdir = NULL;
if (buflen >= CDBUFSIZE) { if (buflen >= CDBUFSIZE) {
/* EOCD64 locator is before EOCD, so leave place for it */ /* EOCD64 locator is before EOCD, so leave place for it */
@ -608,165 +709,139 @@ _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 = NULL;
/* The size of buffer never greater than CDBUFSIZE. */ while ((match = find_eocd(buffer, match)) != NULL) {
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 (_zip_read_cdir(za, buffer, (zip_uint64_t)buf_offset, &cdir, &error)) {
if (cdir) { if (cdir != NULL && (za->open_flags & ZIP_CHECKCONS) && _zip_checkcons(za, cdir, &error) < 0) {
if (best <= 0) { _zip_cdir_free(cdir);
best = _zip_checkcons(za, cdir, &error); cdir = NULL;
}
a = _zip_checkcons(za, cdirnew, &error);
if (best < a) {
_zip_cdir_free(cdir);
cdir = cdirnew;
best = a;
}
else {
_zip_cdir_free(cdirnew);
}
} }
else { break;
cdir = cdirnew;
if (za->open_flags & ZIP_CHECKCONS)
best = _zip_checkcons(za, cdir, &error);
else {
best = 0;
}
}
cdirnew = NULL;
} }
match++;
_zip_buffer_set_offset(buffer, (zip_uint64_t)(match - _zip_buffer_data(buffer)));
} }
_zip_buffer_free(buffer); _zip_buffer_free(buffer);
if (best < 0) { if (cdir == NULL) {
_zip_error_copy(&za->error, &error); _zip_error_copy(&za->error, &error);
_zip_cdir_free(cdir);
return NULL;
} }
return cdir; return cdir;
} }
static const unsigned char *_zip_memmem(const unsigned char *big, size_t biglen, const unsigned char *little, size_t littlelen) { static const unsigned char *
find_eocd(zip_buffer_t *buffer, const unsigned char *last) {
const unsigned char *data = _zip_buffer_data(buffer);
const unsigned char *p; const unsigned char *p;
if (littlelen == 0) { if (last == NULL) {
return big; last = data + _zip_buffer_size(buffer) - MAGIC_LEN;
} }
else if (last == _zip_buffer_data(buffer)) {
if (biglen < littlelen) {
return NULL; return NULL;
} }
else {
p = big; last -= 1;
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;
} }
for (p = last; p >= data; p -= 1) {
if (*p == EOCD_MAGIC[0]) {
if (memcmp(p, EOCD_MAGIC, MAGIC_LEN) == 0) {
return p;
}
}
}
return NULL;
} }
static zip_cdir_t * static zip_cdir_t *
_zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error) { _zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_error_t *error) {
zip_cdir_t *cd; zip_cdir_t *cd;
zip_uint64_t i, nentry, size, offset, eocd_offset;
if (_zip_buffer_left(buffer) < EOCDLEN) { if (_zip_buffer_left(buffer) < EOCDLEN) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EOCD_LENGTH_INVALID); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EOCD_LENGTH_INVALID);
return NULL; return NULL;
} }
eocd_offset = _zip_buffer_offset(buffer); if ((cd = _zip_cdir_new(error)) == NULL) {
_zip_buffer_get(buffer, 4); /* magic already verified */
if (_zip_buffer_get_32(buffer) != 0) {
zip_error_set(error, ZIP_ER_MULTIDISK, 0);
return NULL; return NULL;
} }
cd->eocd_offset = buf_offset + _zip_buffer_offset(buffer);
/* This function is only called where EOCD magic was found, so no need to check that here. */
_zip_buffer_skip(buffer, MAGIC_LEN);
cd->is_zip64 = false;
cd->this_disk = _zip_buffer_get_16(buffer);
cd->eocd_disk = _zip_buffer_get_16(buffer);
/* number of cdir-entries on this disk */ /* number of cdir-entries on this disk */
i = _zip_buffer_get_16(buffer); cd->disk_entries = _zip_buffer_get_16(buffer);
/* number of cdir-entries */ /* number of cdir-entries */
nentry = _zip_buffer_get_16(buffer); cd->num_entries = _zip_buffer_get_16(buffer);
cd->size = _zip_buffer_get_32(buffer);
if (nentry != i) { cd->offset = _zip_buffer_get_32(buffer);
zip_error_set(error, ZIP_ER_NOZIP, 0);
return NULL;
}
size = _zip_buffer_get_32(buffer);
offset = _zip_buffer_get_32(buffer);
if (offset + size < offset) {
zip_error_set(error, ZIP_ER_SEEK, EFBIG);
return NULL;
}
if (offset + size > buf_offset + eocd_offset) {
/* cdir spans past EOCD record */
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_OVERLAPS_EOCD);
return NULL;
}
if ((flags & ZIP_CHECKCONS) && offset + size != buf_offset + eocd_offset) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_LENGTH_INVALID);
return NULL;
}
if ((cd = _zip_cdir_new(nentry, error)) == NULL)
return NULL;
cd->is_zip64 = false;
cd->size = size;
cd->offset = offset;
return cd; return cd;
} }
static bool
check_eocd(zip_cdir_t *cd, unsigned int flags, zip_error_t *error) {
if (cd->disk_entries != cd->num_entries || cd->this_disk != 0 || cd->eocd_disk != 0) {
zip_error_set(error, ZIP_ER_MULTIDISK, 0);
return false;
}
static zip_cdir_t * if (cd->offset + cd->size < cd->offset) {
_zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error) { zip_error_set(error, ZIP_ER_SEEK, EFBIG);
zip_cdir_t *cd; return false;
}
if ((flags & ZIP_CHECKCONS) && cd->offset + cd->size != cd->eocd_offset) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_LENGTH_INVALID);
return false;
}
return true;
}
cdir_status_t _zip_read_eocd64(zip_cdir_t *cdir, zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error) {
zip_uint64_t offset; zip_uint64_t offset;
zip_uint8_t eocd[EOCD64LEN]; zip_uint8_t eocd[EOCD64LEN];
zip_uint64_t eocd_offset; zip_uint64_t eocd_offset;
zip_uint64_t size, nentry, i, eocdloc_offset; zip_uint64_t size, nentry, i, eocdloc_offset;
bool free_buffer; bool free_buffer;
zip_uint32_t num_disks, num_disks64, eocd_disk, eocd_disk64; zip_uint32_t num_disks, eocd_disk, this_disk;
eocdloc_offset = _zip_buffer_offset(buffer); eocdloc_offset = _zip_buffer_offset(buffer);
_zip_buffer_get(buffer, 4); /* magic already verified */ _zip_buffer_get(buffer, 4); /* magic already verified */
num_disks = _zip_buffer_get_16(buffer); eocd_disk = _zip_buffer_get_32(buffer);
eocd_disk = _zip_buffer_get_16(buffer);
eocd_offset = _zip_buffer_get_64(buffer); eocd_offset = _zip_buffer_get_64(buffer);
num_disks = _zip_buffer_get_32(buffer);
if (!check_magic(eocd_offset, buffer, buf_offset, src, EOCD64_MAGIC)) {
return CDIR_NOT_FOUND;
}
if (num_disks != 1) {
zip_error_set(error, ZIP_ER_MULTIDISK, 0);
return CDIR_INVALID;
}
/* valid seek value for start of EOCD */ /* valid seek value for start of EOCD */
if (eocd_offset > ZIP_INT64_MAX) { if (eocd_offset > ZIP_INT64_MAX) {
zip_error_set(error, ZIP_ER_SEEK, EFBIG); zip_error_set(error, ZIP_ER_SEEK, EFBIG);
return NULL; return CDIR_INVALID;
} }
/* does EOCD fit before EOCD locator? */ /* does EOCD fit before EOCD locator? */
if (eocd_offset + EOCD64LEN > eocdloc_offset + buf_offset) { if (eocd_offset + EOCD64LEN > eocdloc_offset + buf_offset) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EOCD64_OVERLAPS_EOCD); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EOCD64_OVERLAPS_EOCD);
return NULL; return CDIR_INVALID;
} }
/* make sure current position of buffer is beginning of EOCD */ /* make sure current position of buffer is beginning of EOCD */
@ -777,10 +852,10 @@ _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 CDIR_INVALID;
} }
if ((buffer = _zip_buffer_new_from_source(src, EOCD64LEN, eocd, error)) == NULL) { if ((buffer = _zip_buffer_new_from_source(src, EOCD64LEN, eocd, error)) == NULL) {
return NULL; return CDIR_INVALID;
} }
free_buffer = true; free_buffer = true;
} }
@ -790,7 +865,7 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse
if (free_buffer) { if (free_buffer) {
_zip_buffer_free(buffer); _zip_buffer_free(buffer);
} }
return NULL; return CDIR_INVALID;
} }
/* size of EOCD */ /* size of EOCD */
@ -802,47 +877,29 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse
if (free_buffer) { if (free_buffer) {
_zip_buffer_free(buffer); _zip_buffer_free(buffer);
} }
return NULL; return CDIR_INVALID;
} }
_zip_buffer_get(buffer, 4); /* skip version made by/needed */ _zip_buffer_get(buffer, 4); /* skip version made by/needed */
num_disks64 = _zip_buffer_get_32(buffer); this_disk = _zip_buffer_get_32(buffer);
eocd_disk64 = _zip_buffer_get_32(buffer); if (_zip_buffer_get_32(buffer) != eocd_disk) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EOCD64_LOCATOR_MISMATCH);
/* if eocd values are 0xffff, we have to use eocd64 values.
otherwise, if the values are not the same, it's inconsistent;
in any case, if the value is not 0, we don't support it */
if (num_disks == 0xffff) {
num_disks = num_disks64;
}
if (eocd_disk == 0xffff) {
eocd_disk = eocd_disk64;
}
if ((flags & ZIP_CHECKCONS) && (eocd_disk != eocd_disk64 || num_disks != num_disks64)) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EOCD64_MISMATCH);
if (free_buffer) { if (free_buffer) {
_zip_buffer_free(buffer); _zip_buffer_free(buffer);
} }
return NULL; return CDIR_INVALID;
}
if (num_disks != 0 || eocd_disk != 0) {
zip_error_set(error, ZIP_ER_MULTIDISK, 0);
if (free_buffer) {
_zip_buffer_free(buffer);
}
return NULL;
} }
nentry = _zip_buffer_get_64(buffer);
i = _zip_buffer_get_64(buffer); i = _zip_buffer_get_64(buffer);
nentry = _zip_buffer_get_64(buffer);
if (nentry != i) { if (nentry != i) {
zip_error_set(error, ZIP_ER_MULTIDISK, 0); zip_error_set(error, ZIP_ER_MULTIDISK, 0);
if (free_buffer) { if (free_buffer) {
_zip_buffer_free(buffer); _zip_buffer_free(buffer);
} }
return NULL; return CDIR_INVALID;
} }
size = _zip_buffer_get_64(buffer); size = _zip_buffer_get_64(buffer);
@ -854,7 +911,7 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse
if (free_buffer) { if (free_buffer) {
_zip_buffer_free(buffer); _zip_buffer_free(buffer);
} }
return NULL; return CDIR_INVALID;
} }
if (free_buffer) { if (free_buffer) {
@ -863,35 +920,33 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse
if (offset > ZIP_INT64_MAX || offset + size < offset) { if (offset > ZIP_INT64_MAX || offset + size < offset) {
zip_error_set(error, ZIP_ER_SEEK, EFBIG); zip_error_set(error, ZIP_ER_SEEK, EFBIG);
return NULL; return CDIR_INVALID;
}
if (offset + size > buf_offset + eocd_offset) {
/* cdir spans past EOCD record */
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_OVERLAPS_EOCD);
return NULL;
}
if ((flags & ZIP_CHECKCONS) && offset + size != buf_offset + eocd_offset) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_OVERLAPS_EOCD);
return NULL;
} }
if (nentry > size / CDENTRYSIZE) { if (nentry > size / CDENTRYSIZE) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_INVALID); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_INVALID);
return NULL; return CDIR_INVALID;
} }
if ((cd = _zip_cdir_new(nentry, error)) == NULL) if ((cdir->size != 0xffffffff && cdir->size != size) || (cdir->offset != 0xffffffff && cdir->offset != offset) || (cdir->num_entries != 0xffff && cdir->num_entries != nentry) || (cdir->disk_entries != 0xffff && cdir->disk_entries != i) || (cdir->this_disk != 0xffff && cdir->this_disk != this_disk) || (cdir->eocd_disk != 0xffff && cdir->eocd_disk != eocd_disk)) {
return NULL; zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EOCD64_MISMATCH);
return CDIR_INVALID;
}
cd->is_zip64 = true; cdir->is_zip64 = true;
cd->size = size; cdir->size = size;
cd->offset = offset; cdir->offset = offset;
cdir->disk_entries = i;
cdir->num_entries = nentry;
cdir->this_disk = this_disk;
cdir->eocd_disk = eocd_disk;
return cd; return CDIR_OK;
} }
static int decode_hex(char c) { static int
decode_hex(char c) {
if (c >= '0' && c <= '9') { if (c >= '0' && c <= '9') {
return c - '0'; return c - '0';
} }
@ -906,17 +961,17 @@ static int decode_hex(char c) {
/* _zip_check_torrentzip: /* _zip_check_torrentzip:
check whether ZA has a valid TORRENTZIP comment, i.e. is torrentzipped */ 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) { static void
zip_check_torrentzip(zip_t *za, const zip_cdir_t *cdir) {
zip_uint32_t crc_should; zip_uint32_t crc_should;
char buf[8+1]; char buf[8 + 1];
size_t i; size_t i;
if (cdir == NULL) { if (cdir == NULL) {
return; return;
} }
if (_zip_string_length(cdir->comment) != TORRENTZIP_SIGNATURE_LENGTH + TORRENTZIP_CRC_LENGTH if (_zip_string_length(cdir->comment) != TORRENTZIP_SIGNATURE_LENGTH + TORRENTZIP_CRC_LENGTH || strncmp((const char *)cdir->comment->raw, TORRENTZIP_SIGNATURE, TORRENTZIP_SIGNATURE_LENGTH) != 0)
|| strncmp((const char *)cdir->comment->raw, TORRENTZIP_SIGNATURE, TORRENTZIP_SIGNATURE_LENGTH) != 0)
return; return;
memcpy(buf, cdir->comment->raw + TORRENTZIP_SIGNATURE_LENGTH, TORRENTZIP_CRC_LENGTH); memcpy(buf, cdir->comment->raw + TORRENTZIP_SIGNATURE_LENGTH, TORRENTZIP_CRC_LENGTH);
@ -934,8 +989,8 @@ static void zip_check_torrentzip(zip_t *za, const zip_cdir_t *cdir) {
{ {
zip_stat_t st; zip_stat_t st;
zip_source_t* src_window; zip_source_t *src_window;
zip_source_t* src_crc; zip_source_t *src_crc;
zip_uint8_t buffer[512]; zip_uint8_t buffer[512];
zip_int64_t ret; zip_int64_t ret;
@ -943,7 +998,7 @@ static void zip_check_torrentzip(zip_t *za, const zip_cdir_t *cdir) {
st.valid |= ZIP_STAT_SIZE | ZIP_STAT_CRC; st.valid |= ZIP_STAT_SIZE | ZIP_STAT_CRC;
st.size = cdir->size; st.size = cdir->size;
st.crc = crc_should; 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) { if ((src_window = _zip_source_window_new(za->src, cdir->offset, cdir->size, &st, 0, NULL, NULL, NULL, 0, false, NULL)) == NULL) {
return; return;
} }
if ((src_crc = zip_source_crc_create(src_window, 1, NULL)) == NULL) { if ((src_crc = zip_source_crc_create(src_window, 1, NULL)) == NULL) {

View File

@ -1,6 +1,6 @@
/* /*
zip_pkware.c -- Traditional PKWARE de/encryption backend routines zip_pkware.c -- Traditional PKWARE de/encryption backend routines
Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner Copyright (C) 2009-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_progress.c -- progress reporting zip_progress.c -- progress reporting
Copyright (C) 2017-2020 Dieter Baron and Thomas Klausner Copyright (C) 2017-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>
@ -191,7 +191,7 @@ _zip_progress_update(zip_progress_t *progress, double sub_current) {
if (progress->callback_progress != NULL) { if (progress->callback_progress != NULL) {
current = ZIP_MIN(ZIP_MAX(sub_current, 0.0), 1.0) * (progress->end - progress->start) + progress->start; current = ZIP_MIN(ZIP_MAX(sub_current, 0.0), 1.0) * (progress->end - progress->start) + progress->start;
if (current - progress->last_update > progress->precision) { if (current - progress->last_update > progress->precision || (progress->last_update < 1 && current == 1)) {
progress->callback_progress(progress->za, current, progress->ud_progress); progress->callback_progress(progress->za, current, progress->ud_progress);
progress->last_update = current; progress->last_update = current;
} }

View File

@ -1,6 +1,6 @@
/* /*
zip_random_unix.c -- fill the user's buffer with random stuff (Unix version) zip_random_unix.c -- fill the user's buffer with random stuff (Unix version)
Copyright (C) 2016-2021 Dieter Baron and Thomas Klausner Copyright (C) 2016-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_random_uwp.c -- fill the user's buffer with random stuff (UWP version) zip_random_uwp.c -- fill the user's buffer with random stuff (UWP version)
Copyright (C) 2017-2021 Dieter Baron and Thomas Klausner Copyright (C) 2017-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_random_win32.c -- fill the user's buffer with random stuff (Windows version) zip_random_win32.c -- fill the user's buffer with random stuff (Windows version)
Copyright (C) 2016-2021 Dieter Baron and Thomas Klausner Copyright (C) 2016-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_rename.c -- rename file in zip archive zip_rename.c -- rename file in zip archive
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_replace.c -- replace file via callback function zip_replace.c -- replace file via callback function
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_set_archive_comment.c -- set archive comment zip_set_archive_comment.c -- set archive comment
Copyright (C) 2006-2021 Dieter Baron and Thomas Klausner Copyright (C) 2006-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_get_archive_flag.c -- set archive global flag zip_get_archive_flag.c -- set archive global flag
Copyright (C) 2008-2021 Dieter Baron and Thomas Klausner Copyright (C) 2008-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_set_default_password.c -- set default password for decryption zip_set_default_password.c -- set default password for decryption
Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner Copyright (C) 2009-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_set_file_comment.c -- set comment for file in archive zip_set_file_comment.c -- set comment for file in archive
Copyright (C) 2006-2021 Dieter Baron and Thomas Klausner Copyright (C) 2006-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_set_file_compression.c -- set compression for file in archive zip_set_file_compression.c -- set compression for file in archive
Copyright (C) 2012-2021 Dieter Baron and Thomas Klausner Copyright (C) 2012-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_set_name.c -- rename helper function zip_set_name.c -- rename helper function
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_source_accept_empty.c -- if empty source is a valid archive zip_source_accept_empty.c -- if empty source is a valid archive
Copyright (C) 2019-2021 Dieter Baron and Thomas Klausner Copyright (C) 2019-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_source_begin_write.c -- start a new file for writing zip_source_begin_write.c -- start a new file for writing
Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner Copyright (C) 2014-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_source_begin_write_cloning.c -- clone part of file for writing zip_source_begin_write_cloning.c -- clone part of file for writing
Copyright (C) 2017-2021 Dieter Baron and Thomas Klausner Copyright (C) 2017-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_source_buffer.c -- create zip data source from buffer zip_source_buffer.c -- create zip data source from buffer
Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner Copyright (C) 1999-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_source_call.c -- invoke callback command on zip_source zip_source_call.c -- invoke callback command on zip_source
Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner Copyright (C) 2009-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_source_close.c -- close zip_source (stop reading) zip_source_close.c -- close zip_source (stop reading)
Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner Copyright (C) 2009-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_source_commit_write.c -- commit changes to file zip_source_commit_write.c -- commit changes to file
Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner Copyright (C) 2014-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_source_compress.c -- (de)compression routines zip_source_compress.c -- (de)compression routines
Copyright (C) 2017-2021 Dieter Baron and Thomas Klausner Copyright (C) 2017-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_source_crc.c -- pass-through source that calculates CRC32 and size zip_source_crc.c -- pass-through source that calculates CRC32 and size
Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner Copyright (C) 2009-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_source_error.c -- get last error from zip_source zip_source_error.c -- get last error from zip_source
Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner Copyright (C) 2009-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,9 @@
#ifndef _HAD_ZIP_SOURCE_FILE_H
#define _HAD_ZIP_SOURCE_FILE_H
/* /*
zip_source_file.h -- header for common file operations zip_source_file.h -- header for common file operations
Copyright (C) 2020-2022 Dieter Baron and Thomas Klausner Copyright (C) 2020-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>
@ -88,3 +91,5 @@ struct zip_source_file_operations {
}; };
zip_source_t *zip_source_file_common_new(const char *fname, void *file, zip_uint64_t start, zip_int64_t len, const zip_stat_t *st, zip_source_file_operations_t *ops, void *ops_userdata, zip_error_t *error); zip_source_t *zip_source_file_common_new(const char *fname, void *file, zip_uint64_t start, zip_int64_t len, const zip_stat_t *st, zip_source_file_operations_t *ops, void *ops_userdata, zip_error_t *error);
#endif /* _HAD_ZIP_SOURCE_FILE_H */

View File

@ -1,6 +1,6 @@
/* /*
zip_source_file_common.c -- create data source from file zip_source_file_common.c -- create data source from file
Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner Copyright (C) 1999-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

View File

@ -1,6 +1,6 @@
/* /*
zip_source_file_stdio.c -- read-only stdio file source implementation zip_source_file_stdio.c -- read-only stdio file source implementation
Copyright (C) 2020 Dieter Baron and Thomas Klausner Copyright (C) 2020-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org> The authors can be contacted at <info@libzip.org>

Some files were not shown because too many files have changed in this diff Show More