mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2025-11-11 02:58:02 -06:00
Windows: Update libzip to version 1.11.3
This commit is contained in:
@@ -1,3 +1,10 @@
|
||||
# 1.11.3 [2025-01-20]
|
||||
|
||||
* Report read error for corrupted encrypted file data.
|
||||
* Avoid unnecessary seeks when writing archive.
|
||||
* Don't hardcode `_Nullable` support in `zip.h` to allow it to be used with different compilers.
|
||||
* Improve check for GetSecurityInformation availability on Windows.
|
||||
|
||||
# 1.11.2 [2024-10-31]
|
||||
|
||||
* Fix performance regression in `zip_stat` introduced in 1.11.
|
||||
|
||||
@@ -44,22 +44,19 @@
|
||||
/* to have ISO C secure library functions */
|
||||
#define __STDC_WANT_LIB_EXT1__ 1
|
||||
|
||||
#if defined(_WIN32) && defined(ZIP_DLL) && !defined(ZIP_STATIC)
|
||||
#ifdef BUILDING_LIBZIP
|
||||
#define ZIP_EXTERN __declspec(dllexport)
|
||||
#else
|
||||
#define ZIP_EXTERN __declspec(dllimport)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef ZIP_EXTERN
|
||||
#ifndef ZIP_STATIC
|
||||
#define ZIP_EXTERN __declspec(dllexport)
|
||||
#endif
|
||||
#endif
|
||||
/* for dup(), close(), etc. */
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDBOOL_H
|
||||
#include <stdbool.h>
|
||||
#elif !defined(__BOOL_DEFINED)
|
||||
#else
|
||||
typedef char bool;
|
||||
#define true 1
|
||||
#define false 0
|
||||
@@ -127,14 +124,13 @@ typedef char bool;
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(HAVE__FSEEKI64) && defined(HAVE__FSTAT64) && defined(HAVE__FTELLI64)
|
||||
#if defined(HAVE__FSEEKI64) && defined(HAVE__FSTAT64) && defined(HAVE__SEEK64)
|
||||
/* Windows API using int64 */
|
||||
typedef zip_int64_t zip_off_t;
|
||||
typedef struct _stat64 zip_os_stat_t;
|
||||
#define zip_os_stat _stat64
|
||||
#define zip_os_fstat _fstat64
|
||||
#define zip_os_fseek _fseeki64
|
||||
#define zip_os_ftell _ftelli64
|
||||
#define zip_os_seek _fseeki64
|
||||
#define ZIP_FSEEK_MAX ZIP_INT64_MAX
|
||||
#define ZIP_FSEEK_MIN ZIP_INT64_MIN
|
||||
#else
|
||||
|
||||
@@ -12,13 +12,8 @@
|
||||
#define HAVE__FILENO
|
||||
#define HAVE__FSEEKI64
|
||||
#define HAVE__FSTAT64
|
||||
#define HAVE__FTELLI64
|
||||
#define HAVE__SETMODE
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
#define HAVE__SNPRINTF
|
||||
#else
|
||||
/* #undef HAVE__SNPRINTF */
|
||||
#endif
|
||||
#define HAVE__SNPRINTF_S
|
||||
#define HAVE__SNWPRINTF_S
|
||||
#define HAVE__STAT64
|
||||
@@ -37,6 +32,7 @@
|
||||
/* #undef HAVE_FSEEKO */
|
||||
/* #undef HAVE_FTELLO */
|
||||
/* #undef HAVE_GETPROGNAME */
|
||||
#define HAVE_GETSECURITYINFO
|
||||
/* #undef HAVE_GNUTLS */
|
||||
/* #undef HAVE_LIBBZ2 */
|
||||
/* #undef HAVE_LIBLZMA */
|
||||
@@ -46,14 +42,9 @@
|
||||
#define HAVE_MEMCPY_S
|
||||
/* #undef HAVE_MBEDTLS */
|
||||
/* #undef HAVE_MKSTEMP */
|
||||
/* #undef HAVE_NULLABLE */
|
||||
/* #undef HAVE_OPENSSL */
|
||||
#define HAVE_SETMODE
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
/* #undef HAVE_SNPRINTF */
|
||||
#else
|
||||
#define HAVE_SNPRINTF
|
||||
#endif
|
||||
/* #undef HAVE_SNPRINTF_S */
|
||||
/* #undef HAVE_STRCASECMP */
|
||||
#define HAVE_STRDUP
|
||||
@@ -61,37 +52,24 @@
|
||||
/* #undef HAVE_STRERRORLEN_S */
|
||||
#define HAVE_STRICMP
|
||||
#define HAVE_STRNCPY_S
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1800
|
||||
/* #undef HAVE_STRTOLL */
|
||||
/* #undef HAVE_STRTOULL */
|
||||
#else
|
||||
#define HAVE_STRTOLL
|
||||
#define HAVE_STRTOULL
|
||||
#endif
|
||||
/* #undef HAVE_STRUCT_TM_TM_ZONE */
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1800
|
||||
/* #undef HAVE_STDBOOL_H */
|
||||
#else
|
||||
#define HAVE_STDBOOL_H
|
||||
#endif
|
||||
/* #undef HAVE_STRINGS_H */
|
||||
/* #undef HAVE_UNISTD_H */
|
||||
#define HAVE_WINDOWS_CRYPTO
|
||||
#define SIZEOF_OFF_T 4
|
||||
#ifdef _WIN64
|
||||
#define SIZEOF_SIZE_T 8
|
||||
#else
|
||||
#define SIZEOF_SIZE_T 4
|
||||
#endif
|
||||
/* #undef HAVE_DIRENT_H */
|
||||
/* #undef HAVE_FTS_H */
|
||||
/* #undef HAVE_NDIR_H */
|
||||
/* #undef HAVE_SYS_DIR_H */
|
||||
/* #undef HAVE_SYS_NDIR_H */
|
||||
/* #undef WORDS_BIGENDIAN */
|
||||
#define HAVE_SHARED
|
||||
/* #undef HAVE_SHARED */
|
||||
/* END DEFINES */
|
||||
#define PACKAGE "libzip"
|
||||
#define VERSION "1.11.2"
|
||||
#define VERSION "1.11.3"
|
||||
|
||||
#endif /* HAD_CONFIG_H */
|
||||
|
||||
@@ -34,6 +34,15 @@
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__has_feature)
|
||||
#if !__has_feature(nullability)
|
||||
#define _Nullable
|
||||
#define _Nonnull
|
||||
#endif
|
||||
#else
|
||||
#define _Nullable
|
||||
#define _Nonnull
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -45,13 +54,9 @@ extern "C" {
|
||||
#include <zipconf.h>
|
||||
|
||||
#ifndef ZIP_EXTERN
|
||||
#if defined(ZIP_DLL) && !defined(ZIP_STATIC)
|
||||
#ifndef ZIP_STATIC
|
||||
#ifdef _WIN32
|
||||
#ifdef BUILDING_LIBZIP
|
||||
#define ZIP_EXTERN __declspec(dllexport)
|
||||
#else
|
||||
#define ZIP_EXTERN __declspec(dllimport)
|
||||
#endif
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 4
|
||||
#define ZIP_EXTERN __attribute__((visibility("default")))
|
||||
#else
|
||||
|
||||
@@ -208,11 +208,11 @@ input(void *ud, zip_uint8_t *data, zip_uint64_t length) {
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
end_of_input(void *ud) {
|
||||
static bool end_of_input(void *ud) {
|
||||
struct ctx *ctx = (struct ctx *)ud;
|
||||
|
||||
ctx->end_of_input = true;
|
||||
return ctx->zstr.avail_in != 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -196,11 +196,11 @@ input(void *ud, zip_uint8_t *data, zip_uint64_t length) {
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
end_of_input(void *ud) {
|
||||
static bool end_of_input(void *ud) {
|
||||
struct ctx *ctx = (struct ctx *)ud;
|
||||
|
||||
ctx->end_of_input = true;
|
||||
return ctx->zstr.avail_in != 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -302,11 +302,11 @@ input(void *ud, zip_uint8_t *data, zip_uint64_t length) {
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
end_of_input(void *ud) {
|
||||
static bool end_of_input(void *ud) {
|
||||
struct ctx *ctx = (struct ctx *)ud;
|
||||
|
||||
ctx->end_of_input = true;
|
||||
return ctx->zstr.avail_in != 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -211,11 +211,11 @@ input(void *ud, zip_uint8_t *data, zip_uint64_t length) {
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
end_of_input(void *ud) {
|
||||
static bool end_of_input(void *ud) {
|
||||
struct ctx *ctx = (struct ctx *)ud;
|
||||
|
||||
ctx->end_of_input = true;
|
||||
return ctx->in.pos != ctx->in.size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -295,8 +295,7 @@ zip_close(zip_t *za) {
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
|
||||
static int add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
|
||||
zip_int64_t offstart, offdata, offend, data_length;
|
||||
zip_stat_t st;
|
||||
zip_file_attributes_t attributes;
|
||||
@@ -305,19 +304,24 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
|
||||
int is_zip64;
|
||||
zip_flags_t flags;
|
||||
bool needs_recompress, needs_decompress, needs_crc, needs_compress, needs_reencrypt, needs_decrypt, needs_encrypt;
|
||||
bool have_dos_time, dirent_changed;
|
||||
time_t mtime_before_copy;
|
||||
|
||||
if (zip_source_stat(src, &st) < 0) {
|
||||
zip_error_set_from_source(&za->error, src);
|
||||
return -1;
|
||||
}
|
||||
|
||||
de->bitflags &= ~ZIP_GPBF_DATA_DESCRIPTOR;
|
||||
|
||||
if ((st.valid & ZIP_STAT_COMP_METHOD) == 0) {
|
||||
st.valid |= ZIP_STAT_COMP_METHOD;
|
||||
st.comp_method = ZIP_CM_STORE;
|
||||
}
|
||||
|
||||
if (ZIP_CM_IS_DEFAULT(de->comp_method) && st.comp_method != ZIP_CM_STORE)
|
||||
if (ZIP_CM_IS_DEFAULT(de->comp_method) && st.comp_method != ZIP_CM_STORE) {
|
||||
de->comp_method = st.comp_method;
|
||||
}
|
||||
else if (de->comp_method == ZIP_CM_STORE && (st.valid & ZIP_STAT_SIZE)) {
|
||||
st.valid |= ZIP_STAT_COMP_SIZE;
|
||||
st.comp_size = st.size;
|
||||
@@ -372,14 +376,30 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
|
||||
}
|
||||
}
|
||||
|
||||
if ((offstart = zip_source_tell_write(za->src)) < 0) {
|
||||
zip_error_set_from_source(&za->error, za->src);
|
||||
return -1;
|
||||
if ((de->changed & ZIP_DIRENT_LAST_MOD) == 0) {
|
||||
int ret2 = zip_source_get_dos_time(src, &de->last_mod);
|
||||
if (ret2 < 0) {
|
||||
zip_error_set_from_source(&za->error, src);
|
||||
return -1;
|
||||
}
|
||||
if (ret2 == 1) {
|
||||
have_dos_time = true;
|
||||
}
|
||||
else {
|
||||
if (st.valid & ZIP_STAT_MTIME) {
|
||||
mtime_before_copy = st.mtime;
|
||||
}
|
||||
else {
|
||||
time(&mtime_before_copy);
|
||||
}
|
||||
if (_zip_u2d_time(mtime_before_copy, &de->last_mod, &za->error) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* as long as we don't support non-seekable output, clear data descriptor bit */
|
||||
de->bitflags &= (zip_uint16_t)~ZIP_GPBF_DATA_DESCRIPTOR;
|
||||
if ((is_zip64 = _zip_dirent_write(za, de, flags)) < 0) {
|
||||
if ((offstart = zip_source_tell_write(za->src)) < 0) {
|
||||
zip_error_set_from_source(&za->error, za->src);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -485,9 +505,24 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
|
||||
src_final = src_tmp;
|
||||
}
|
||||
|
||||
if (!ZIP_WANT_TORRENTZIP(za)) {
|
||||
if (zip_source_get_file_attributes(src_final, &attributes) != 0) {
|
||||
zip_error_set_from_source(&za->error, src_final);
|
||||
zip_source_free(src_final);
|
||||
return -1;
|
||||
}
|
||||
_zip_dirent_apply_attributes(de, &attributes, (flags & ZIP_FL_FORCE_ZIP64) != 0, changed);
|
||||
}
|
||||
|
||||
/* as long as we don't support non-seekable output, clear data descriptor bit */
|
||||
if ((is_zip64 = _zip_dirent_write(za, de, flags)) < 0) {
|
||||
zip_source_free(src_final);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((offdata = zip_source_tell_write(za->src)) < 0) {
|
||||
zip_error_set_from_source(&za->error, za->src);
|
||||
zip_source_free(src_final);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -498,9 +533,11 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if (zip_source_get_file_attributes(src_final, &attributes) != 0) {
|
||||
zip_error_set_from_source(&za->error, src_final);
|
||||
ret = -1;
|
||||
if (!ZIP_WANT_TORRENTZIP(za)) {
|
||||
if (zip_source_get_file_attributes(src_final, &attributes) != 0) {
|
||||
zip_error_set_from_source(&za->error, src_final);
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
zip_source_free(src_final);
|
||||
@@ -514,57 +551,51 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (zip_source_seek_write(za->src, offstart, SEEK_SET) < 0) {
|
||||
zip_error_set_from_source(&za->error, za->src);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((st.valid & (ZIP_STAT_COMP_METHOD | ZIP_STAT_CRC | ZIP_STAT_SIZE)) != (ZIP_STAT_COMP_METHOD | ZIP_STAT_CRC | ZIP_STAT_SIZE)) {
|
||||
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((de->changed & ZIP_DIRENT_LAST_MOD) == 0) {
|
||||
int ret2 = zip_source_get_dos_time(src, &de->last_mod);
|
||||
if (ret2 < 0) {
|
||||
zip_error_set_from_source(&za->error, src);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
dirent_changed = ZIP_CM_ACTUAL(de->comp_method) != st.comp_method || de->crc != st.crc || de->uncomp_size != st.size || de->comp_size != (zip_uint64_t)(offend - offdata);
|
||||
de->comp_method = st.comp_method;
|
||||
de->crc = st.crc;
|
||||
de->uncomp_size = st.size;
|
||||
de->comp_size = (zip_uint64_t)(offend - offdata);
|
||||
_zip_dirent_apply_attributes(de, &attributes, (flags & ZIP_FL_FORCE_ZIP64) != 0, changed);
|
||||
|
||||
if (ZIP_WANT_TORRENTZIP(za)) {
|
||||
zip_dirent_torrentzip_normalize(de);
|
||||
if (!ZIP_WANT_TORRENTZIP(za)) {
|
||||
dirent_changed |= _zip_dirent_apply_attributes(de, &attributes, (flags & ZIP_FL_FORCE_ZIP64) != 0, changed);
|
||||
|
||||
if ((de->changed & ZIP_DIRENT_LAST_MOD) == 0 && !have_dos_time) {
|
||||
if (st.valid & ZIP_STAT_MTIME) {
|
||||
if (st.mtime != mtime_before_copy) {
|
||||
if (_zip_u2d_time(st.mtime, &de->last_mod, &za->error) < 0) {
|
||||
return -1;
|
||||
}
|
||||
dirent_changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((ret = _zip_dirent_write(za, de, flags)) < 0)
|
||||
return -1;
|
||||
if (dirent_changed) {
|
||||
if (zip_source_seek_write(za->src, offstart, SEEK_SET) < 0) {
|
||||
zip_error_set_from_source(&za->error, za->src);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (is_zip64 != ret) {
|
||||
/* Zip64 mismatch between preliminary file header written before data and final file header written afterwards */
|
||||
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
|
||||
return -1;
|
||||
}
|
||||
if ((ret = _zip_dirent_write(za, de, flags)) < 0)
|
||||
return -1;
|
||||
|
||||
if (zip_source_seek_write(za->src, offend, SEEK_SET) < 0) {
|
||||
zip_error_set_from_source(&za->error, za->src);
|
||||
return -1;
|
||||
if (is_zip64 != ret) {
|
||||
/* Zip64 mismatch between preliminary file header written before data and final file header written afterwards */
|
||||
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (zip_source_seek_write(za->src, offend, SEEK_SET) < 0) {
|
||||
zip_error_set_from_source(&za->error, za->src);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (de->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) {
|
||||
|
||||
@@ -968,7 +968,7 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) {
|
||||
_zip_buffer_put_16(buffer, ZIP_CM_WINZIP_AES);
|
||||
}
|
||||
else {
|
||||
_zip_buffer_put_16(buffer, (zip_uint16_t)de->comp_method);
|
||||
_zip_buffer_put_16(buffer, (zip_uint16_t)ZIP_CM_ACTUAL(de->comp_method));
|
||||
}
|
||||
|
||||
if (ZIP_WANT_TORRENTZIP(za)) {
|
||||
@@ -1190,52 +1190,75 @@ _zip_u2d_time(time_t intime, zip_dostime_t *dtime, zip_error_t *ze) {
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_zip_dirent_apply_attributes(zip_dirent_t *de, zip_file_attributes_t *attributes, bool force_zip64, zip_uint32_t changed) {
|
||||
bool _zip_dirent_apply_attributes(zip_dirent_t *de, zip_file_attributes_t *attributes, bool force_zip64, zip_uint32_t changed) {
|
||||
zip_uint16_t length;
|
||||
bool has_changed = false;
|
||||
|
||||
if (attributes->valid & ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS) {
|
||||
zip_uint16_t mask = attributes->general_purpose_bit_mask & ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS_ALLOWED_MASK;
|
||||
de->bitflags = (de->bitflags & ~mask) | (attributes->general_purpose_bit_flags & mask);
|
||||
zip_uint16_t bitflags = (de->bitflags & ~mask) | (attributes->general_purpose_bit_flags & mask);
|
||||
if (de->bitflags != bitflags) {
|
||||
de->bitflags = bitflags;
|
||||
has_changed = true;
|
||||
}
|
||||
}
|
||||
if (attributes->valid & ZIP_FILE_ATTRIBUTES_ASCII) {
|
||||
de->int_attrib = (de->int_attrib & ~0x1) | (attributes->ascii ? 1 : 0);
|
||||
zip_uint16_t int_attrib = (de->int_attrib & ~0x1) | (attributes->ascii ? 1 : 0);
|
||||
if (de->int_attrib != int_attrib) {
|
||||
de->int_attrib = int_attrib;
|
||||
has_changed = true;
|
||||
}
|
||||
}
|
||||
/* manually set attributes are preferred over attributes provided by source */
|
||||
if ((changed & ZIP_DIRENT_ATTRIBUTES) == 0 && (attributes->valid & ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES)) {
|
||||
de->ext_attrib = attributes->external_file_attributes;
|
||||
if (de->ext_attrib != attributes->external_file_attributes) {
|
||||
de->ext_attrib = attributes->external_file_attributes;
|
||||
has_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
zip_uint16_t version_needed;
|
||||
if (de->comp_method == ZIP_CM_LZMA) {
|
||||
de->version_needed = 63;
|
||||
version_needed = 63;
|
||||
}
|
||||
else if (de->encryption_method == ZIP_EM_AES_128 || de->encryption_method == ZIP_EM_AES_192 || de->encryption_method == ZIP_EM_AES_256) {
|
||||
de->version_needed = 51;
|
||||
version_needed = 51;
|
||||
}
|
||||
else if (de->comp_method == ZIP_CM_BZIP2) {
|
||||
de->version_needed = 46;
|
||||
version_needed = 46;
|
||||
}
|
||||
else if (force_zip64 || _zip_dirent_needs_zip64(de, 0)) {
|
||||
de->version_needed = 45;
|
||||
version_needed = 45;
|
||||
}
|
||||
else if (de->comp_method == ZIP_CM_DEFLATE || de->encryption_method == ZIP_EM_TRAD_PKWARE) {
|
||||
de->version_needed = 20;
|
||||
version_needed = 20;
|
||||
}
|
||||
else if ((length = _zip_string_length(de->filename)) > 0 && de->filename->raw[length - 1] == '/') {
|
||||
de->version_needed = 20;
|
||||
version_needed = 20;
|
||||
}
|
||||
else {
|
||||
de->version_needed = 10;
|
||||
version_needed = 10;
|
||||
}
|
||||
|
||||
if (attributes->valid & ZIP_FILE_ATTRIBUTES_VERSION_NEEDED) {
|
||||
de->version_needed = ZIP_MAX(de->version_needed, attributes->version_needed);
|
||||
version_needed = ZIP_MAX(version_needed, attributes->version_needed);
|
||||
}
|
||||
|
||||
de->version_madeby = 63 | (de->version_madeby & 0xff00);
|
||||
if ((changed & ZIP_DIRENT_ATTRIBUTES) == 0 && (attributes->valid & ZIP_FILE_ATTRIBUTES_HOST_SYSTEM)) {
|
||||
de->version_madeby = (de->version_madeby & 0xff) | (zip_uint16_t)(attributes->host_system << 8);
|
||||
if (de->version_needed != version_needed) {
|
||||
de->version_needed = version_needed;
|
||||
has_changed = true;
|
||||
}
|
||||
|
||||
zip_int16_t version_madeby = 63 | (de->version_madeby & 0xff00);
|
||||
if ((changed & ZIP_DIRENT_ATTRIBUTES) == 0 && (attributes->valid & ZIP_FILE_ATTRIBUTES_HOST_SYSTEM)) {
|
||||
version_madeby = (version_madeby & 0xff) | (zip_uint16_t)(attributes->host_system << 8);
|
||||
}
|
||||
if (de->version_madeby != version_madeby) {
|
||||
de->version_madeby = version_madeby;
|
||||
has_changed = true;
|
||||
}
|
||||
|
||||
return has_changed;
|
||||
}
|
||||
|
||||
|
||||
@@ -1257,15 +1280,37 @@ zip_dirent_torrentzip_normalize(zip_dirent_t *de) {
|
||||
/* 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;
|
||||
int zip_dirent_check_consistency(zip_dirent_t *dirent) {
|
||||
if (dirent->comp_method == ZIP_CM_STORE) {
|
||||
zip_uint64_t header_size = 0;
|
||||
switch (dirent->encryption_method) {
|
||||
case ZIP_EM_NONE:
|
||||
break;
|
||||
case ZIP_EM_TRAD_PKWARE:
|
||||
header_size = 12;
|
||||
break;
|
||||
case ZIP_EM_AES_128:
|
||||
header_size = 20;
|
||||
break;
|
||||
case ZIP_EM_AES_192:
|
||||
header_size = 24;
|
||||
break;
|
||||
case ZIP_EM_AES_256:
|
||||
header_size = 28;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
if (dirent->uncomp_size + header_size < dirent->uncomp_size || dirent->comp_size != dirent->uncomp_size + header_size) {
|
||||
return ZIP_ER_DETAIL_STORED_SIZE_MISMATCH;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
time_t zip_dirent_get_last_mod_mtime(zip_dirent_t *de) {
|
||||
time_t
|
||||
zip_dirent_get_last_mod_mtime(zip_dirent_t *de) {
|
||||
if (!de->last_mod_mtime_valid) {
|
||||
de->last_mod_mtime = _zip_d2u_time(&de->last_mod);
|
||||
de->last_mod_mtime_valid = true;
|
||||
|
||||
@@ -80,6 +80,7 @@ const struct _zip_err_info _zip_err_details[] = {
|
||||
{ G, "EOCD64 and EOCD64 locator do not match" },
|
||||
{ E, "UTF-8 filename is ASCII and doesn't match filename" },
|
||||
{ E, "UTF-8 comment is ASCII and doesn't match comment" },
|
||||
{ G, "garbage at end of compressed data" },
|
||||
};
|
||||
|
||||
const int _zip_err_details_count = sizeof(_zip_err_details)/sizeof(_zip_err_details[0]);
|
||||
|
||||
@@ -69,13 +69,7 @@ _zip_read_data(zip_buffer_t *buffer, zip_source_t *src, size_t length, bool nulp
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// VS2022: Workaround an Internal compiler error for Release ARM (32-bit) build.
|
||||
#if _MSC_VER >= 1940 && _MSC_VER < 1950 && defined(_M_ARM) && defined(NDEBUG)
|
||||
size_t l = length + (nulp ? 1 : 0);
|
||||
r = (zip_uint8_t *)malloc(l);
|
||||
#else
|
||||
r = (zip_uint8_t *)malloc(length + (nulp ? 1 : 0));
|
||||
#endif
|
||||
if (r == NULL) {
|
||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
return NULL;
|
||||
|
||||
@@ -207,7 +207,7 @@ _zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error) {
|
||||
|
||||
if ((cdir = _zip_find_central_dir(za, len)) == NULL) {
|
||||
_zip_error_copy(error, &za->error);
|
||||
if (zip_error_code_zip(error) == ZIP_ER_NOZIP) {
|
||||
if (zip_error_code_zip(&za->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);
|
||||
|
||||
@@ -340,6 +340,7 @@ buffer_clone(buffer_t *buffer, zip_uint64_t offset, zip_error_t *error) {
|
||||
fragment_offset = offset - buffer->fragment_offsets[fragment];
|
||||
|
||||
if (fragment_offset == 0) {
|
||||
/* We can't be at beginning of fragment zero if offset > 0. */
|
||||
fragment--;
|
||||
fragment_offset = buffer->fragments[fragment].length;
|
||||
}
|
||||
@@ -429,15 +430,13 @@ static bool
|
||||
buffer_grow_fragments(buffer_t *buffer, zip_uint64_t capacity, zip_error_t *error) {
|
||||
zip_buffer_fragment_t *fragments;
|
||||
zip_uint64_t *offsets;
|
||||
zip_uint64_t fragments_size;
|
||||
zip_uint64_t offsets_size;
|
||||
|
||||
if (capacity < buffer->fragments_capacity) {
|
||||
return true;
|
||||
}
|
||||
|
||||
fragments_size = sizeof(buffer->fragments[0]) * capacity;
|
||||
offsets_size = sizeof(buffer->fragment_offsets[0]) * (capacity + 1);
|
||||
zip_uint64_t fragments_size = sizeof(buffer->fragments[0]) * capacity;
|
||||
zip_uint64_t offsets_size = sizeof(buffer->fragment_offsets[0]) * (capacity + 1);
|
||||
|
||||
if (capacity == ZIP_UINT64_MAX || fragments_size < capacity || fragments_size > SIZE_MAX|| offsets_size < capacity || offsets_size > SIZE_MAX) {
|
||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
|
||||
@@ -44,6 +44,7 @@ struct context {
|
||||
bool can_store;
|
||||
bool is_stored; /* only valid if end_of_stream is true */
|
||||
bool compress;
|
||||
bool check_consistency;
|
||||
zip_int32_t method;
|
||||
|
||||
zip_uint64_t size;
|
||||
@@ -86,11 +87,10 @@ static size_t implementations_size = sizeof(implementations) / sizeof(implementa
|
||||
static zip_source_t *compression_source_new(zip_t *za, zip_source_t *src, zip_int32_t method, bool compress, zip_uint32_t compression_flags);
|
||||
static zip_int64_t compress_callback(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
|
||||
static void context_free(struct context *ctx);
|
||||
static struct context *context_new(zip_int32_t method, bool compress, zip_uint32_t compression_flags, zip_compression_algorithm_t *algorithm);
|
||||
static struct context *context_new(zip_int32_t method, bool compress, zip_uint32_t compression_flags, zip_compression_algorithm_t *algorithm, bool check_consistency);
|
||||
static zip_int64_t compress_read(zip_source_t *, struct context *, void *, zip_uint64_t);
|
||||
|
||||
zip_compression_algorithm_t *
|
||||
_zip_get_compression_algorithm(zip_int32_t method, bool compress) {
|
||||
zip_compression_algorithm_t *_zip_get_compression_algorithm(zip_int32_t method, bool compress) {
|
||||
size_t i;
|
||||
zip_uint16_t real_method = ZIP_CM_ACTUAL(method);
|
||||
|
||||
@@ -108,16 +108,14 @@ _zip_get_compression_algorithm(zip_int32_t method, bool compress) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_compression_method_supported(zip_int32_t method, int compress) {
|
||||
ZIP_EXTERN int zip_compression_method_supported(zip_int32_t method, int compress) {
|
||||
if (method == ZIP_CM_STORE) {
|
||||
return 1;
|
||||
}
|
||||
return _zip_get_compression_algorithm(method, compress) != NULL;
|
||||
}
|
||||
|
||||
zip_source_t *
|
||||
zip_source_compress(zip_t *za, zip_source_t *src, zip_int32_t method, zip_uint32_t compression_flags) {
|
||||
zip_source_t *zip_source_compress(zip_t *za, zip_source_t *src, zip_int32_t method, zip_uint32_t compression_flags) {
|
||||
return compression_source_new(za, src, method, true, compression_flags);
|
||||
}
|
||||
|
||||
@@ -127,8 +125,7 @@ zip_source_decompress(zip_t *za, zip_source_t *src, zip_int32_t method) {
|
||||
}
|
||||
|
||||
|
||||
static zip_source_t *
|
||||
compression_source_new(zip_t *za, zip_source_t *src, zip_int32_t method, bool compress, zip_uint32_t compression_flags) {
|
||||
static zip_source_t *compression_source_new(zip_t *za, zip_source_t *src, zip_int32_t method, bool compress, zip_uint32_t compression_flags) {
|
||||
struct context *ctx;
|
||||
zip_source_t *s2;
|
||||
zip_compression_algorithm_t *algorithm = NULL;
|
||||
@@ -143,7 +140,7 @@ compression_source_new(zip_t *za, zip_source_t *src, zip_int32_t method, bool co
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((ctx = context_new(method, compress, compression_flags, algorithm)) == NULL) {
|
||||
if ((ctx = context_new(method, compress, compression_flags, algorithm, za->open_flags & ZIP_CHECKCONS)) == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return NULL;
|
||||
}
|
||||
@@ -157,8 +154,7 @@ compression_source_new(zip_t *za, zip_source_t *src, zip_int32_t method, bool co
|
||||
}
|
||||
|
||||
|
||||
static struct context *
|
||||
context_new(zip_int32_t method, bool compress, zip_uint32_t compression_flags, zip_compression_algorithm_t *algorithm) {
|
||||
static struct context *context_new(zip_int32_t method, bool compress, zip_uint32_t compression_flags, zip_compression_algorithm_t *algorithm, bool check_consistency) {
|
||||
struct context *ctx;
|
||||
|
||||
if ((ctx = (struct context *)malloc(sizeof(*ctx))) == NULL) {
|
||||
@@ -172,6 +168,7 @@ context_new(zip_int32_t method, bool compress, zip_uint32_t compression_flags, z
|
||||
ctx->end_of_input = false;
|
||||
ctx->end_of_stream = false;
|
||||
ctx->is_stored = false;
|
||||
ctx->check_consistency = check_consistency;
|
||||
|
||||
if ((ctx->ud = ctx->algorithm->allocate(ZIP_CM_ACTUAL(method), compression_flags, &ctx->error)) == NULL) {
|
||||
zip_error_fini(&ctx->error);
|
||||
@@ -228,7 +225,23 @@ compress_read(zip_source_t *src, struct context *ctx, void *data, zip_uint64_t l
|
||||
ctx->end_of_stream = true;
|
||||
|
||||
if (!ctx->end_of_input) {
|
||||
/* TODO: garbage after stream, or compression ended before all data read */
|
||||
n = zip_source_read(src, ctx->buffer, 1);
|
||||
if (n < 0) {
|
||||
zip_error_set_from_source(&ctx->error, src);
|
||||
end = true;
|
||||
break;
|
||||
}
|
||||
else if (n == 0) {
|
||||
ctx->end_of_input = true;
|
||||
n = ctx->algorithm->end_of_input(ctx->ud) ? 1 : 0;
|
||||
}
|
||||
|
||||
if (n > 0 && ctx->check_consistency) {
|
||||
/* garbage after stream, or compression ended before all data read */
|
||||
zip_error_set(&ctx->error, ZIP_ER_INCONS, ZIP_ER_DETAIL_COMPRESSED_DATA_TRAILING_GARBAGE);
|
||||
end = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->first_read < 0) {
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef S_IWUSR
|
||||
@@ -96,9 +95,11 @@ _zip_stdio_op_close(zip_source_file_context_t *ctx) {
|
||||
zip_int64_t
|
||||
_zip_stdio_op_read(zip_source_file_context_t *ctx, void *buf, zip_uint64_t len) {
|
||||
size_t i;
|
||||
#if SIZE_MAX < ZIP_UINT64_MAX
|
||||
if (len > SIZE_MAX) {
|
||||
len = SIZE_MAX;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((i = fread(buf, 1, (size_t)len, ctx->f)) == 0) {
|
||||
if (ferror((FILE *)ctx->f)) {
|
||||
|
||||
@@ -33,13 +33,6 @@
|
||||
|
||||
#include "zip_source_file_win32.h"
|
||||
|
||||
/* ACL is not available when targeting the games API partition */
|
||||
#if defined(WINAPI_FAMILY_PARTITION) && defined(WINAPI_PARTITION_GAMES)
|
||||
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_GAMES)
|
||||
#define ACL_UNSUPPORTED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static zip_int64_t _zip_win32_named_op_commit_write(zip_source_file_context_t *ctx);
|
||||
static zip_int64_t _zip_win32_named_op_create_temp_output(zip_source_file_context_t *ctx);
|
||||
static bool _zip_win32_named_op_open(zip_source_file_context_t *ctx);
|
||||
@@ -106,29 +99,24 @@ _zip_win32_named_op_create_temp_output(zip_source_file_context_t *ctx) {
|
||||
|
||||
zip_uint32_t value, i;
|
||||
HANDLE th = INVALID_HANDLE_VALUE;
|
||||
PSECURITY_DESCRIPTOR psd = NULL;
|
||||
PSECURITY_ATTRIBUTES psa = NULL;
|
||||
PSECURITY_DESCRIPTOR psd = NULL;
|
||||
#ifdef HAVE_GETSECURITYINFO
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
SECURITY_INFORMATION si;
|
||||
DWORD success;
|
||||
PACL dacl = NULL;
|
||||
#endif
|
||||
char *tempname = NULL;
|
||||
size_t tempname_size = 0;
|
||||
|
||||
#ifdef HAVE_GETSECURITYINFO
|
||||
if ((HANDLE)ctx->f != INVALID_HANDLE_VALUE && GetFileType((HANDLE)ctx->f) == FILE_TYPE_DISK) {
|
||||
si = DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION;
|
||||
#ifdef ACL_UNSUPPORTED
|
||||
success = ERROR_NOT_SUPPORTED;
|
||||
#else
|
||||
success = GetSecurityInfo((HANDLE)ctx->f, SE_FILE_OBJECT, si, NULL, NULL, &dacl, NULL, &psd);
|
||||
#endif
|
||||
if (success == ERROR_SUCCESS) {
|
||||
if (GetSecurityInfo((HANDLE)ctx->f, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &psd) == ERROR_SUCCESS) {
|
||||
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
sa.bInheritHandle = FALSE;
|
||||
sa.lpSecurityDescriptor = psd;
|
||||
psa = &sa;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef MS_UWP
|
||||
value = GetTickCount();
|
||||
@@ -223,14 +211,12 @@ _zip_win32_named_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t
|
||||
if (file_attributes.dwFileAttributes != INVALID_FILE_ATTRIBUTES) {
|
||||
if ((file_attributes.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE)) == 0) {
|
||||
if (file_attributes.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
|
||||
#ifdef IO_REPARSE_TAG_DEDUP // Not defined in WinSDK 7.1 or before (VS2010).
|
||||
WIN32_FIND_DATA find_data;
|
||||
/* Deduplication on Windows replaces files with reparse points;
|
||||
* accept them as regular files. */
|
||||
if (file_ops->find_first_file(ctx->fname, &find_data) != INVALID_HANDLE_VALUE) {
|
||||
st->regular_file = (find_data.dwReserved0 == IO_REPARSE_TAG_DEDUP);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
st->regular_file = true;
|
||||
|
||||
@@ -39,8 +39,7 @@ zip_file_attributes_init(zip_file_attributes_t *attributes) {
|
||||
attributes->version = 1;
|
||||
}
|
||||
|
||||
int
|
||||
zip_source_get_file_attributes(zip_source_t *src, zip_file_attributes_t *attributes) {
|
||||
int zip_source_get_file_attributes(zip_source_t *src, zip_file_attributes_t *attributes) {
|
||||
if (src->source_closed) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -198,8 +198,10 @@ pkware_encrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t length, zip
|
||||
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
attributes->valid |= ZIP_FILE_ATTRIBUTES_VERSION_NEEDED;
|
||||
attributes->valid |= ZIP_FILE_ATTRIBUTES_VERSION_NEEDED | ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS;
|
||||
attributes->version_needed = 20;
|
||||
attributes->general_purpose_bit_flags = ZIP_GPBF_DATA_DESCRIPTOR;
|
||||
attributes->general_purpose_bit_mask = ZIP_GPBF_DATA_DESCRIPTOR;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -8,26 +8,19 @@
|
||||
based on ../cmake-zipconf.h.in.
|
||||
*/
|
||||
|
||||
#define LIBZIP_VERSION "1.11.2"
|
||||
#define LIBZIP_VERSION "1.11.3"
|
||||
#define LIBZIP_VERSION_MAJOR 1
|
||||
#define LIBZIP_VERSION_MINOR 11
|
||||
#define LIBZIP_VERSION_MICRO 2
|
||||
#define LIBZIP_VERSION_MICRO 3
|
||||
|
||||
/* #undef ZIP_STATIC */
|
||||
|
||||
#define _Nullable
|
||||
#define _Nonnull
|
||||
#ifndef ZIP_STATIC
|
||||
#define ZIP_STATIC
|
||||
#endif
|
||||
|
||||
#if !defined(__STDC_FORMAT_MACROS)
|
||||
#define __STDC_FORMAT_MACROS 1
|
||||
#endif
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1700
|
||||
#include <stdint.h>
|
||||
#define PRIu32 "lu"
|
||||
#define PRIu64 "llu"
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
typedef int8_t zip_int8_t;
|
||||
typedef uint8_t zip_uint8_t;
|
||||
|
||||
@@ -102,7 +102,8 @@
|
||||
/* according to unzip-6.0's zipinfo.c, this corresponds to a directory with rwx permissions for everyone */
|
||||
#define ZIP_EXT_ATTRIB_DEFAULT_DIR (0040777u << 16)
|
||||
|
||||
#define ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS_ALLOWED_MASK 0x0836
|
||||
/* Allowed: Encryption specific bits, data descriptor, compression specific, UTF-8 filename */
|
||||
#define ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS_ALLOWED_MASK 0x083e
|
||||
|
||||
#define ZIP_MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define ZIP_MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
@@ -152,7 +153,7 @@ struct zip_compression_algorithm {
|
||||
bool (*input)(void *ctx, zip_uint8_t *data, zip_uint64_t length);
|
||||
|
||||
/* all input data has been provided */
|
||||
void (*end_of_input)(void *ctx);
|
||||
bool (*end_of_input)(void *ctx);
|
||||
|
||||
/* process input data, writing to data, which has room for length bytes, update length to number of bytes written */
|
||||
zip_compression_status_t (*process)(void *ctx, zip_uint8_t *data, zip_uint64_t *length);
|
||||
@@ -241,6 +242,7 @@ extern const int _zip_err_details_count;
|
||||
#define ZIP_ER_DETAIL_EOCD64_LOCATOR_MISMATCH 22 /* G EOCD64 and EOCD64 locator do not match */
|
||||
#define ZIP_ER_DETAIL_UTF8_FILENAME_MISMATCH 23 /* E UTF-8 filename is ASCII and doesn't match filename */
|
||||
#define ZIP_ER_DETAIL_UTF8_COMMENT_MISMATCH 24 /* E UTF-8 comment is ASCII and doesn't match comment */
|
||||
#define ZIP_ER_DETAIL_COMPRESSED_DATA_TRAILING_GARBAGE 25 /* G garbage at end of compressed data */
|
||||
|
||||
/* directory entry: general purpose bit flags */
|
||||
|
||||
@@ -552,7 +554,7 @@ zip_int64_t _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint6
|
||||
time_t _zip_d2u_time(const zip_dostime_t*);
|
||||
void _zip_deregister_source(zip_t *za, zip_source_t *src);
|
||||
|
||||
void _zip_dirent_apply_attributes(zip_dirent_t *, zip_file_attributes_t *, bool, zip_uint32_t);
|
||||
bool _zip_dirent_apply_attributes(zip_dirent_t *, zip_file_attributes_t *, bool, zip_uint32_t);
|
||||
int zip_dirent_check_consistency(zip_dirent_t *dirent);
|
||||
zip_dirent_t *_zip_dirent_clone(const zip_dirent_t *);
|
||||
void _zip_dirent_free(zip_dirent_t *);
|
||||
|
||||
Reference in New Issue
Block a user