1
0
mirror of https://github.com/veracrypt/VeraCrypt.git synced 2025-11-11 02:58:02 -06:00

Windows: Update libzip to version 1.11.2

This commit is contained in:
Mounir IDRASSI
2025-01-01 10:37:56 +01:00
parent fcc6302e61
commit 138e5e7c1d
143 changed files with 1215 additions and 684 deletions

View File

@@ -1,3 +1,20 @@
# 1.11.2 [2024-10-31]
* Fix performance regression in `zip_stat` introduced in 1.11.
# 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.

View File

@@ -3,7 +3,7 @@
/*
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.
The authors can be contacted at <info@libzip.org>
@@ -126,14 +126,65 @@ typedef char bool;
#endif
#endif
#ifndef HAVE_FSEEKO
#define fseeko(s, o, w) (fseek((s), (long int)(o), (w)))
#if defined(HAVE__FSEEKI64) && defined(HAVE__FSTAT64) && defined(HAVE__FTELLI64)
/* 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_FSEEK_MAX ZIP_INT64_MAX
#define ZIP_FSEEK_MIN ZIP_INT64_MIN
#else
/* Normal API */
#include <sys/stat.h>
typedef struct stat zip_os_stat_t;
#define zip_os_fstat fstat
#define zip_os_stat stat
#if defined(HAVE_FTELLO) && defined(HAVE_FSEEKO)
/* Using off_t */
typedef off_t zip_off_t;
#if SIZEOF_OFF_T == 8
#define ZIP_OFF_MAX ZIP_INT64_MAX
#define ZIP_OFF_MIN ZIP_INT64_MIN
#elif SIZEOF_OFF_T == 4
#define ZIP_OFF_MAX ZIP_INT32_MAX
#define ZIP_OFF_MIN ZIP_INT32_MIN
#elif SIZEOF_OFF_T == 2
#define ZIP_OFF_MAX ZIP_INT16_MAX
#define ZIP_OFF_MIN ZIP_INT16_MIN
#else
#error unsupported size of off_t
#endif
#define ZIP_FSEEK_MAX ZIP_OFF_MAX
#define ZIP_FSEEK_MIN ZIP_OFF_MIN
#define zip_os_fseek fseeko
#define zip_os_ftell ftello
#else
/* Using long */
typedef long zip_off_t;
#include <limits.h>
#define ZIP_FSEEK_MAX LONG_MAX
#define ZIP_FSEEK_MIN LONG_MIN
#define zip_os_fseek fseek
#define zip_os_ftell ftell
#endif
#endif
#ifndef HAVE_FTELLO
#define ftello(s) ((long)ftell((s)))
#endif
#ifdef HAVE_LOCALTIME_S
#ifdef _WIN32
/* Windows is incompatible to the C11 standard, hurray! */
@@ -182,27 +233,6 @@ typedef char bool;
#endif
#endif
#if SIZEOF_OFF_T == 8
#define ZIP_OFF_MAX ZIP_INT64_MAX
#define ZIP_OFF_MIN ZIP_INT64_MIN
#elif SIZEOF_OFF_T == 4
#define ZIP_OFF_MAX ZIP_INT32_MAX
#define ZIP_OFF_MIN ZIP_INT32_MIN
#elif SIZEOF_OFF_T == 2
#define ZIP_OFF_MAX ZIP_INT16_MAX
#define ZIP_OFF_MIN ZIP_INT16_MIN
#else
#error unsupported size of off_t
#endif
#if defined(HAVE_FTELLO) && defined(HAVE_FSEEKO)
#define ZIP_FSEEK_MAX ZIP_OFF_MAX
#define ZIP_FSEEK_MIN ZIP_OFF_MIN
#else
#include <limits.h>
#define ZIP_FSEEK_MAX LONG_MAX
#define ZIP_FSEEK_MIN LONG_MIN
#endif
#ifndef SIZE_MAX
#if SIZEOF_SIZE_T == 8

View File

@@ -10,6 +10,9 @@
#define HAVE__DUP
#define HAVE__FDOPEN
#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
@@ -18,6 +21,7 @@
#endif
#define HAVE__SNPRINTF_S
#define HAVE__SNWPRINTF_S
#define HAVE__STAT64
#define HAVE__STRDUP
#define HAVE__STRICMP
#define HAVE__STRTOI64
@@ -88,6 +92,6 @@
#define HAVE_SHARED
/* END DEFINES */
#define PACKAGE "libzip"
#define VERSION "1.10.1"
#define VERSION "1.11.2"
#endif /* HAD_CONFIG_H */

View File

@@ -3,7 +3,7 @@
/*
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.
The authors can be contacted at <info@libzip.org>
@@ -158,6 +158,7 @@ extern "C" {
#define ZIP_ER_CANCELLED 32 /* N Operation cancelled */
#define ZIP_ER_DATA_LENGTH 33 /* N Unexpected length of data */
#define ZIP_ER_NOT_ALLOWED 34 /* N Not allowed in torrentzip */
#define ZIP_ER_TRUNCATED_ZIP 35 /* N Possibly truncated or corrupted zip archive */
/* type of system error value */
@@ -260,7 +261,8 @@ enum zip_source_cmd {
ZIP_SOURCE_BEGIN_WRITE_CLONING, /* like ZIP_SOURCE_BEGIN_WRITE, but keep part of original file */
ZIP_SOURCE_ACCEPT_EMPTY, /* whether empty files are valid archives */
ZIP_SOURCE_GET_FILE_ATTRIBUTES, /* get additional file attributes */
ZIP_SOURCE_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;

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
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
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.
The authors can be contacted at <info@libzip.org>
@@ -64,7 +64,7 @@ _zip_add_entry(zip_t *za) {
return -1;
}
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);
return -1;
}

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,7 +1,7 @@
/*
zip_algorithm_xz.c -- LZMA/XZ (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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
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
_zip_buffer_set_offset(zip_buffer_t *buffer, zip_uint64_t offset) {
int _zip_buffer_set_offset(zip_buffer_t *buffer, zip_uint64_t offset) {
if (offset > buffer->size) {
buffer->ok = false;
return -1;

View File

@@ -1,6 +1,6 @@
/*
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.
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 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 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);
@@ -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. */
if (de->changed & ZIP_DIRENT_LAST_MOD) {
zip_stat_t st_mtime;
zip_stat_init(&st_mtime);
st_mtime.valid = ZIP_STAT_MTIME;
st_mtime.mtime = de->last_mod;
if ((src_tmp = _zip_source_window_new(src_final, 0, -1, &st_mtime, 0, NULL, NULL, 0, true, &za->error)) == NULL) {
if ((src_tmp = _zip_source_window_new(src_final, 0, -1, NULL, 0, NULL, &de->last_mod, NULL, 0, true, &za->error)) == NULL) {
zip_source_free(src_final);
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;
}
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) {
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 (st.valid & ZIP_STAT_MTIME)
de->last_mod = st.mtime;
else
time(&de->last_mod);
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;
}
}
}
de->comp_method = st.comp_method;
de->crc = st.crc;
@@ -605,7 +614,7 @@ copy_data(zip_t *za, zip_uint64_t len) {
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);
zip_int64_t n, current;
int ret;
@@ -628,7 +637,13 @@ copy_source(zip_t *za, zip_source_t *src, zip_int64_t data_length) {
break;
}
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) {
zip_error_set(&za->error, ZIP_ER_CANCELLED, 0);
ret = -1;
@@ -742,4 +757,4 @@ static int torrentzip_compare_names(const void *a, const void *b) {
}
return strcasecmp(aname, bname);
}
}

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>
@@ -126,8 +126,9 @@ _zip_crypto_aes_free(_zip_crypto_aes_t *aes) {
bool
_zip_crypto_aes_encrypt_block(_zip_crypto_aes_t *aes, const zip_uint8_t *in, zip_uint8_t *out) {
int len;
if (EVP_EncryptUpdate(aes, out, &len, in, ZIP_CRYPTO_AES_BLOCK_LENGTH) != 1) {
int len = 0;
if (EVP_EncryptUpdate(aes, out, &len, in, ZIP_CRYPTO_AES_BLOCK_LENGTH) != 1
|| len != ZIP_CRYPTO_AES_BLOCK_LENGTH) {
return false;
}
return true;
@@ -214,11 +215,11 @@ _zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac) {
bool
_zip_crypto_hmac_output(_zip_crypto_hmac_t *hmac, zip_uint8_t *data) {
#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;
#else
unsigned int length;
return HMAC_Final(hmac, data, &length) == 1;
unsigned int length = 0;
return HMAC_Final(hmac, data, &length) == 1 && length == ZIP_CRYPTO_SHA1_LENGTH;
#endif
}

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>
@@ -37,9 +37,6 @@
#include "zip_crypto.h"
#define WIN32_LEAN_AND_MEAN
#define NOCRYPT
#include <windows.h>
#include <bcrypt.h>

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
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
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.
The authors can be contacted at <info@libzip.org>
@@ -41,7 +41,7 @@
#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 bool _zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error);
@@ -50,8 +50,9 @@ void
_zip_cdir_free(zip_cdir_t *cd) {
zip_uint64_t i;
if (!cd)
if (cd == NULL) {
return;
}
for (i = 0; i < cd->nentry; i++)
_zip_entry_finalize(cd->entry + i);
@@ -62,7 +63,7 @@ _zip_cdir_free(zip_cdir_t *cd) {
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;
if ((cd = (zip_cdir_t *)malloc(sizeof(*cd))) == NULL) {
@@ -76,11 +77,6 @@ _zip_cdir_new(zip_uint64_t nentry, zip_error_t *error) {
cd->comment = NULL;
cd->is_zip64 = false;
if (!_zip_cdir_grow(cd, nentry, error)) {
_zip_cdir_free(cd);
return NULL;
}
return cd;
}
@@ -126,8 +122,6 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor
zip_buffer_t *buffer;
zip_int64_t off;
zip_uint64_t i;
bool is_zip64;
int ret;
zip_uint32_t cdir_crc;
if ((off = zip_source_tell_write(za->src)) < 0) {
@@ -136,8 +130,6 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor
}
offset = (zip_uint64_t)off;
is_zip64 = false;
if (ZIP_WANT_TORRENTZIP(za)) {
cdir_crc = (zip_uint32_t)crc32(0, NULL, 0);
za->write_crc = &cdir_crc;
@@ -146,10 +138,10 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor
for (i = 0; i < survivors; i++) {
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;
if (ret)
is_zip64 = true;
}
}
za->write_crc = NULL;
@@ -160,16 +152,12 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor
}
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) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
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_64(buffer, EOCD64LEN - 12);
_zip_buffer_put_16(buffer, 45);
@@ -294,11 +282,13 @@ _zip_dirent_init(zip_dirent_t *de) {
de->cloned = 0;
de->crc_valid = true;
de->last_mod_mtime_valid = false;
de->version_madeby = 63 | (ZIP_OPSYS_DEFAULT << 8);
de->version_needed = 10; /* 1.0 */
de->bitflags = 0;
de->comp_method = ZIP_CM_DEFAULT;
de->last_mod = 0;
de->last_mod.date = 0;
de->last_mod.time = 0;
de->crc = 0;
de->comp_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.
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_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_uint16_t dostime, dosdate;
zip_uint32_t size, variable_size;
zip_uint16_t filename_len, comment_len, ef_len;
zip_string_t *utf8_string;
bool is_zip64 = false;
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);
/* convert to time_t */
dostime = _zip_buffer_get_16(buffer);
dosdate = _zip_buffer_get_16(buffer);
zde->last_mod = _zip_d2u_time(dostime, dosdate);
zde->last_mod.time = _zip_buffer_get_16(buffer);
zde->last_mod.date = _zip_buffer_get_16(buffer);
zde->crc = _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) {
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) {
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) {
zde->comment = _zip_read_string(buffer, src, comment_len, 0, error);
if (!zde->comment) {
if (zde->comment == NULL) {
if (!from_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);
zde->comment = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_COMMENT, zde->comment);
if ((utf8_string = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_NAME, zde->filename, check_consistency)) == NULL && zde->filename != NULL) {
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 */
@@ -535,6 +541,7 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
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;
}
if (!from_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 */
if (zde->offset > ZIP_INT64_MAX) {
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;
}
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;
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 *
_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_uint32_t ef_crc;
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);
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);
str = ef_str;
}
@@ -688,18 +734,18 @@ _zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error) {
crc_valid = true;
switch (_zip_buffer_get_16(buffer)) {
case 1:
break;
case 1:
break;
case 2:
crc_valid = false;
/* TODO: When checking consistency, check that crc is 0. */
break;
default:
zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0);
_zip_buffer_free(buffer);
return false;
case 2:
crc_valid = false;
/* TODO: When checking consistency, check that crc is 0. */
break;
default:
zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0);
_zip_buffer_free(buffer);
return false;
}
/* vendor */
@@ -787,7 +833,7 @@ _zip_dirent_size(zip_source_t *src, zip_uint16_t flags, zip_error_t *error) {
int
_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_extra_field_t *ef;
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)) {
dostime = 0xbc00;
dosdate = 0x2198;
dostime.time = 0xbc00;
dostime.date = 0x2198;
}
else {
_zip_u2d_time(de->last_mod, &dostime, &dosdate);
dostime = de->last_mod;
}
_zip_buffer_put_16(buffer, dostime);
_zip_buffer_put_16(buffer, dosdate);
_zip_buffer_put_16(buffer, dostime.time);
_zip_buffer_put_16(buffer, dostime.date);
if (is_winzip_aes && de->uncomp_size < 20) {
_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
_zip_d2u_time(zip_uint16_t dtime, zip_uint16_t ddate) {
_zip_d2u_time(const zip_dostime_t *dtime) {
struct tm 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 */
tm.tm_isdst = -1;
tm.tm_year = ((ddate >> 9) & 127) + 1980 - 1900;
tm.tm_mon = ((ddate >> 5) & 15) - 1;
tm.tm_mday = ddate & 31;
tm.tm_year = ((dtime->date >> 9) & 127) + 1980 - 1900;
tm.tm_mon = ((dtime->date >> 5) & 15) - 1;
tm.tm_mday = dtime->date & 31;
tm.tm_hour = (dtime >> 11) & 31;
tm.tm_min = (dtime >> 5) & 63;
tm.tm_sec = (dtime << 1) & 62;
tm.tm_hour = (dtime->time >> 11) & 31;
tm.tm_min = (dtime->time >> 5) & 63;
tm.tm_sec = (dtime->time << 1) & 62;
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
_zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate) {
int
_zip_u2d_time(time_t intime, zip_dostime_t *dtime, zip_error_t *ze) {
struct tm *tpm;
struct tm tm;
tpm = zip_localtime(&intime, &tm);
if (tpm == NULL) {
/* if localtime fails, return an arbitrary date (1980-01-01 00:00:00) */
*ddate = (1 << 5) + 1;
*dtime = 0;
return;
dtime->date = (1 << 5) + 1;
dtime->time = 0;
if (ze) {
zip_error_set(ze, ZIP_ER_INVAL, errno);
}
return -1;
}
if (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 = (zip_uint16_t)(((tpm->tm_hour) << 11) + ((tpm->tm_min) << 5) + ((tpm->tm_sec) >> 1));
dtime->date = (zip_uint16_t)(((tpm->tm_year + 1900 - 1980) << 9) + ((tpm->tm_mon + 1) << 5) + tpm->tm_mday);
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.
*/
void zip_dirent_torrentzip_normalize(zip_dirent_t *de) {
void
zip_dirent_torrentzip_normalize(zip_dirent_t *de) {
de->version_madeby = 0;
de->version_needed = 20; /* 2.0 */
de->bitflags = 2; /* maximum compression */
de->bitflags = 2; /* maximum compression */
de->comp_method = ZIP_CM_DEFLATE;
de->compression_level = TORRENTZIP_COMPRESSION_FLAGS;
de->disk_number = 0;
@@ -1203,5 +1255,21 @@ void zip_dirent_torrentzip_normalize(zip_dirent_t *de) {
de->ext_attrib = 0;
/* 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;
}
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;
}
return de->last_mod_mtime;
}

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -49,6 +49,7 @@ const struct _zip_err_info _zip_err_str[] = {
{ N, "Operation cancelled" },
{ N, "Unexpected length of data" },
{ N, "Not allowed in torrentzip" },
{ N, "Possibly truncated or corrupted zip archive" },
};
const int _zip_err_str_count = sizeof(_zip_err_str)/sizeof(_zip_err_str[0]);
@@ -74,6 +75,11 @@ const struct _zip_err_info _zip_err_details[] = {
{ E, "garbage at end of extra fields" },
{ E, "extra field length is invalid" },
{ E, "file length in header doesn't match actual file length" },
{ E, "compressed and uncompressed sizes don't match for stored file" },
{ E, "local header and data descriptor do not match" },
{ 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" },
};
const int _zip_err_details_count = sizeof(_zip_err_details)/sizeof(_zip_err_details[0]);

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
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
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.
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
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.
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) {
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);
system_error_buffer[128 - 1] = '\0'; /* make sure string is NUL-terminated */
zip_error_string = NULL;
@@ -61,6 +64,9 @@ zip_error_strerror(zip_error_t *err) {
case ZIP_ET_SYS: {
size_t len = strerrorlen_s(err->sys_err) + 1;
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);
system_error_string = system_error_buffer;
break;
@@ -79,12 +85,18 @@ zip_error_strerror(zip_error_t *err) {
}
else if (error >= _zip_err_details_count) {
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);
system_error_buffer[128 - 1] = '\0'; /* make sure string is NUL-terminated */
system_error_string = system_error_buffer;
}
else if (_zip_err_details[error].type == ZIP_DETAIL_ET_ENTRY && index < MAX_DETAIL_INDEX) {
system_error_buffer = (char *)malloc(128);
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);
system_error_buffer[128 - 1] = '\0'; /* make sure string is NUL-terminated */
system_error_string = system_error_buffer;

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
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
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.
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);
return -1;
}
if (ZIP_WANT_TORRENTZIP(za)) {
zip_error_set(&za->error, ZIP_ER_NOT_ALLOWED, 0);
return -1;
}
if (_zip_file_extra_field_prepare_for_change(za, idx) < 0)
return -1;

View File

@@ -1,6 +1,6 @@
/*
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.
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
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
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
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.
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.
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
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;
}
/* 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;
* needed for a double add of the same file name */
_zip_unchange_data(za->entry + idx);

View File

@@ -1,6 +1,6 @@
/*
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.
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
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.
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
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.
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.
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.
The authors can be contacted at <info@libzip.org>
@@ -33,19 +33,12 @@
#include "zipint.h"
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) {
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) {
static int zip_file_set_time(zip_t *za, zip_uint64_t idx, zip_uint16_t dtime, zip_uint16_t ddate, zip_flags_t flags, time_t *mtime) {
zip_entry_t *e;
if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
if (_zip_get_dirent(za, idx, 0, NULL) == NULL) {
return -1;
}
if (ZIP_IS_RDONLY(za)) {
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
@@ -70,8 +63,31 @@ 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;
if (mtime != NULL) {
e->changes->last_mod_mtime = *mtime;
e->changes->last_mod_mtime_valid = true;
}
else {
e->changes->last_mod_mtime_valid = false;
}
e->changes->changed |= ZIP_DIRENT_LAST_MOD;
return 0;
}
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) {
return zip_file_set_time(za, idx, dtime, ddate, flags, NULL);
}
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_time(za, idx, dostime.time, dostime.date, flags, &mtime);
}

View File

@@ -1,6 +1,6 @@
/*
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.
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
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.
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
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.
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
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.
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
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
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_int64_t n;
if (!zf)
if (zf == NULL) {
return -1;
}
if (zf->error.zip_err != 0)
if (zf->error.zip_err != 0) {
return -1;
}
if (toread > ZIP_INT64_MAX) {
zip_error_set(&zf->error, ZIP_ER_INVAL, 0);

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>
@@ -36,11 +36,13 @@
ZIP_EXTERN zip_int8_t
zip_fseek(zip_file_t *zf, zip_int64_t offset, int whence) {
if (!zf)
if (zf == NULL) {
return -1;
}
if (zf->error.zip_err != 0)
if (zf->error.zip_err != 0) {
return -1;
}
if (zip_source_seek(zf->src, offset, whence) < 0) {
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_file_is_seekable(zip_file_t *zfile) {
if (!zfile) {
if (zfile == NULL) {
return -1;
}

View File

@@ -1,6 +1,6 @@
/*
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.
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_int64_t res;
if (!zf)
if (zf == NULL) {
return -1;
}
if (zf->error.zip_err != 0)
if (zf->error.zip_err != 0) {
return -1;
}
res = zip_source_tell(zf->src);
if (res < 0) {

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
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
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.
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
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.
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
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>
@@ -69,8 +69,14 @@ _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));
if (!r) {
#endif
if (r == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
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;
ret = malloc(len);
if (!ret) {
if (ret == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>
@@ -46,7 +46,7 @@ _zip_new(zip_error_t *error) {
zip_t *za;
za = (zip_t *)malloc(sizeof(struct zip));
if (!za) {
if (za == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
@@ -68,6 +68,7 @@ _zip_new(zip_error_t *error) {
za->nopen_source = za->nopen_source_alloc = 0;
za->open_source = NULL;
za->progress = NULL;
za->torrent_mtime = 0;
return za;
}

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>
@@ -31,7 +31,6 @@
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
@@ -39,17 +38,30 @@
#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_int64_t _zip_checkcons(zip_t *za, zip_cdir_t *cdir, zip_error_t *error);
static void zip_check_torrentzip(zip_t *za, const zip_cdir_t *cdir);
static zip_cdir_t *_zip_find_central_dir(zip_t *za, zip_uint64_t len);
static exists_t _zip_file_exists(zip_source_t *src, zip_error_t *error);
static int _zip_headercomp(const zip_dirent_t *, const zip_dirent_t *);
static const unsigned char *_zip_memmem(const unsigned char *, size_t, const unsigned char *, size_t);
static zip_cdir_t *_zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_error_t *error);
static zip_cdir_t *_zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error);
static zip_cdir_t *_zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error);
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_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, 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 const unsigned char *find_eocd(zip_buffer_t *buffer, const unsigned char *last);
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_open(zip_source_t *src, unsigned int flags, zip_error_t *error) {
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) {
_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 */
zip_source_keep(src);
zip_discard(za);
@@ -228,14 +267,14 @@ void
_zip_set_open_error(int *zep, const zip_error_t *err, int ze) {
if (err) {
ze = zip_error_code_zip(err);
switch (zip_error_system_type(err)) {
case ZIP_ET_SYS:
case ZIP_ET_LIBZIP:
errno = zip_error_code_system(err);
break;
default:
break;
switch (zip_error_system_type(err)) {
case ZIP_ET_SYS:
case ZIP_ET_LIBZIP:
errno = zip_error_code_system(err);
break;
default:
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
entries, or NULL if unsuccessful. */
static zip_cdir_t *
_zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_error_t *error) {
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_cdir_t *cd;
zip_uint16_t comment_len;
zip_uint64_t i, left;
zip_uint64_t eocd_offset = _zip_buffer_offset(buffer);
zip_buffer_t *cd_buffer;
bool eocd64_found = false;
if (_zip_buffer_left(buffer) < EOCDLEN) {
/* not enough bytes left for comment */
zip_error_set(error, ZIP_ER_NOZIP, 0);
return NULL;
}
*cdirp = NULL;
/* check for end-of-central-dir magic */
if (memcmp(_zip_buffer_get(buffer, 4), EOCD_MAGIC, 4) != 0) {
zip_error_set(error, ZIP_ER_NOZIP, 0);
return NULL;
if ((cd = _zip_read_eocd(buffer, buf_offset, error)) == NULL) {
return false;
}
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);
cd = _zip_read_eocd64(za->src, buffer, buf_offset, za->flags, error);
}
else {
_zip_buffer_set_offset(buffer, eocd_offset);
cd = _zip_read_eocd(buffer, buf_offset, za->flags, error);
switch (_zip_read_eocd64(cd, za->src, buffer, buf_offset, za->flags, error)) {
case CDIR_OK:
break;
case CDIR_INVALID:
_zip_cdir_free(cd);
return true;
case CDIR_NOT_FOUND:
_zip_cdir_free(cd);
return false;
}
}
if (cd == NULL)
return NULL;
if ((cd->eocd_disk != 0 || cd->this_disk != 0) && !eocd64_found && cd->eocd_disk != cd->this_disk) {
/* 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);
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 */
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_OVERLAPS_EOCD);
_zip_cdir_free(cd);
return NULL;
return true;
}
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);
tail_len = _zip_buffer_left(buffer);
if (tail_len < comment_len || ((za->open_flags & ZIP_CHECKCONS) && tail_len != comment_len)) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_COMMENT_LENGTH_INVALID);
_zip_cdir_free(cd);
return NULL;
if (tail_len != comment_len) {
if (za->open_flags & ZIP_CHECKCONS) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_COMMENT_LENGTH_INVALID);
_zip_cdir_free(cd);
return true;
}
if (tail_len < comment_len) {
comment_len = tail_len;
}
}
if (comment_len) {
if ((cd->comment = _zip_string_new(_zip_buffer_get(buffer, comment_len), comment_len, ZIP_FL_ENC_GUESS, error)) == NULL) {
_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) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_LENGTH_INVALID);
_zip_cdir_free(cd);
return NULL;
return true;
}
if ((cd_buffer = _zip_buffer_new(data, cd->size)) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
_zip_cdir_free(cd);
return NULL;
return true;
}
}
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) {
zip_error_set_from_source(error, za->src);
_zip_cdir_free(cd);
return NULL;
return true;
}
/* possible consistency check: cd->offset = len-(cd->size+cd->comment_len+EOCDLEN) ? */
if (zip_source_tell(za->src) != (zip_int64_t)cd->offset) {
zip_error_set(error, ZIP_ER_NOZIP, 0);
_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;
i = 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)) {
_zip_cdir_free(cd);
_zip_buffer_free(cd_buffer);
return NULL;
return 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 (zip_error_code_zip(error) == ZIP_ER_INCONS) {
zip_error_set(error, ZIP_ER_INCONS, ADD_INDEX_TO_DETAIL(zip_error_code_system(error), i));
}
else if (grown && zip_error_code_zip(error) == ZIP_ER_NOZIP) {
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) {
zip_error_set(error, ZIP_ER_INCONS, ADD_INDEX_TO_DETAIL(zip_error_code_system(error), i));
}
else if (grown && zip_error_code_zip(error) == ZIP_ER_NOZIP) {
zip_error_set(error, ZIP_ER_INCONS, MAKE_DETAIL_WITH_INDEX(ZIP_ER_DETAIL_CDIR_ENTRY_INVALID, i));
}
_zip_cdir_free(cd);
_zip_buffer_free(cd_buffer);
return NULL;
return true;
}
i++;
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) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_WRONG_ENTRIES_COUNT);
_zip_buffer_free(cd_buffer);
_zip_cdir_free(cd);
return NULL;
return true;
}
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) {
zip_error_set_from_source(error, za->src);
_zip_cdir_free(cd);
return NULL;
return true;
}
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_buffer_free(cd_buffer);
_zip_cdir_free(cd);
return NULL;
return true;
}
}
_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 min, max, j;
struct zip_dirent temp;
int detail;
_zip_dirent_init(&temp);
if (cd->nentry) {
@@ -460,10 +561,10 @@ _zip_checkcons(zip_t *za, zip_cdir_t *cd, zip_error_t *error) {
return -1;
}
if (_zip_dirent_read(&temp, za->src, NULL, true, error) == -1) {
if (zip_error_code_zip(error) == ZIP_ER_INCONS) {
zip_error_set(error, ZIP_ER_INCONS, ADD_INDEX_TO_DETAIL(zip_error_code_system(error), i));
}
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) {
zip_error_set(error, ZIP_ER_INCONS, ADD_INDEX_TO_DETAIL(zip_error_code_system(error), i));
}
_zip_dirent_finalize(&temp);
return -1;
}
@@ -479,6 +580,11 @@ _zip_checkcons(zip_t *za, zip_cdir_t *cd, zip_error_t *error) {
temp.extra_fields = NULL;
_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;
@@ -497,25 +603,23 @@ _zip_headercomp(const zip_dirent_t *central, const zip_dirent_t *local) {
and global headers for the bitflags */
|| (central->bitflags != local->bitflags)
#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;
if ((central->crc != local->crc) || (central->comp_size != local->comp_size) || (central->uncomp_size != local->uncomp_size)) {
/* InfoZip stores valid values in local header even when data descriptor is used.
This is in violation of the appnote.
macOS Archive sets the compressed size even when data descriptor is used ( but not the others),
also in violation of the appnote.
*/
/* if data descriptor is not used, the values must match */
macOS Archive sets the compressed size even when data descriptor is used ( but not the others),
also in violation of the appnote.
*/
/* if data descriptor is not used, the values must match */
if ((local->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0) {
return -1;
}
/* when using a data descriptor, the local header value must be zero or match */
if ((local->crc != 0 && central->crc != local->crc) ||
(local->comp_size != 0 && central->comp_size != local->comp_size) ||
(local->uncomp_size != 0 && central->uncomp_size != local->uncomp_size)) {
return -1;
}
}
/* when using a data descriptor, the local header value must be zero or match */
if ((local->crc != 0 && central->crc != local->crc) || (local->comp_size != 0 && central->comp_size != local->comp_size) || (local->uncomp_size != 0 && central->uncomp_size != local->uncomp_size)) {
return -1;
}
}
return 0;
@@ -568,12 +672,10 @@ _zip_file_exists(zip_source_t *src, zip_error_t *error) {
static zip_cdir_t *
_zip_find_central_dir(zip_t *za, zip_uint64_t len) {
zip_cdir_t *cdir, *cdirnew;
zip_cdir_t *cdir;
const zip_uint8_t *match;
zip_int64_t buf_offset;
zip_uint64_t buflen;
zip_int64_t a;
zip_int64_t best;
zip_error_t error;
zip_buffer_t *buffer;
@@ -600,7 +702,6 @@ _zip_find_central_dir(zip_t *za, zip_uint64_t len) {
return NULL;
}
best = -1;
cdir = NULL;
if (buflen >= CDBUFSIZE) {
/* 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);
match = _zip_buffer_get(buffer, 0);
/* The size of buffer never greater than CDBUFSIZE. */
while (_zip_buffer_left(buffer) >= EOCDLEN && (match = _zip_memmem(match, (size_t)_zip_buffer_left(buffer) - (EOCDLEN - 4), (const unsigned char *)EOCD_MAGIC, 4)) != NULL) {
match = NULL;
while ((match = find_eocd(buffer, match)) != NULL) {
_zip_buffer_set_offset(buffer, (zip_uint64_t)(match - _zip_buffer_data(buffer)));
if ((cdirnew = _zip_read_cdir(za, buffer, (zip_uint64_t)buf_offset, &error)) != NULL) {
if (cdir) {
if (best <= 0) {
best = _zip_checkcons(za, cdir, &error);
}
a = _zip_checkcons(za, cdirnew, &error);
if (best < a) {
_zip_cdir_free(cdir);
cdir = cdirnew;
best = a;
}
else {
_zip_cdir_free(cdirnew);
}
if (_zip_read_cdir(za, buffer, (zip_uint64_t)buf_offset, &cdir, &error)) {
if (cdir != NULL && (za->open_flags & ZIP_CHECKCONS) && _zip_checkcons(za, cdir, &error) < 0) {
_zip_cdir_free(cdir);
cdir = NULL;
}
else {
cdir = cdirnew;
if (za->open_flags & ZIP_CHECKCONS)
best = _zip_checkcons(za, cdir, &error);
else {
best = 0;
}
}
cdirnew = NULL;
break;
}
match++;
_zip_buffer_set_offset(buffer, (zip_uint64_t)(match - _zip_buffer_data(buffer)));
}
_zip_buffer_free(buffer);
if (best < 0) {
if (cdir == NULL) {
_zip_error_copy(&za->error, &error);
_zip_cdir_free(cdir);
return NULL;
}
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;
if (littlelen == 0) {
return big;
if (last == NULL) {
last = data + _zip_buffer_size(buffer) - MAGIC_LEN;
}
if (biglen < littlelen) {
else if (last == _zip_buffer_data(buffer)) {
return NULL;
}
p = big;
while (true) {
p = (const unsigned char *)memchr(p, little[0], biglen - (littlelen - 1) - (size_t)(p - big));
if (p == NULL) {
return NULL;
}
if (memcmp(p + 1, little + 1, littlelen - 1) == 0) {
return p;
}
p += 1;
else {
last -= 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 *
_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_uint64_t i, nentry, size, offset, eocd_offset;
if (_zip_buffer_left(buffer) < EOCDLEN) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EOCD_LENGTH_INVALID);
return NULL;
}
eocd_offset = _zip_buffer_offset(buffer);
_zip_buffer_get(buffer, 4); /* magic already verified */
if (_zip_buffer_get_32(buffer) != 0) {
zip_error_set(error, ZIP_ER_MULTIDISK, 0);
if ((cd = _zip_cdir_new(error)) == 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 */
i = _zip_buffer_get_16(buffer);
cd->disk_entries = _zip_buffer_get_16(buffer);
/* number of cdir-entries */
nentry = _zip_buffer_get_16(buffer);
if (nentry != i) {
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;
cd->num_entries = _zip_buffer_get_16(buffer);
cd->size = _zip_buffer_get_32(buffer);
cd->offset = _zip_buffer_get_32(buffer);
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 *
_zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error) {
zip_cdir_t *cd;
if (cd->offset + cd->size < cd->offset) {
zip_error_set(error, ZIP_ER_SEEK, EFBIG);
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_uint8_t eocd[EOCD64LEN];
zip_uint64_t eocd_offset;
zip_uint64_t size, nentry, i, eocdloc_offset;
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);
_zip_buffer_get(buffer, 4); /* magic already verified */
num_disks = _zip_buffer_get_16(buffer);
eocd_disk = _zip_buffer_get_16(buffer);
eocd_disk = _zip_buffer_get_32(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 */
if (eocd_offset > ZIP_INT64_MAX) {
zip_error_set(error, ZIP_ER_SEEK, EFBIG);
return NULL;
return CDIR_INVALID;
}
/* does EOCD fit before EOCD locator? */
if (eocd_offset + EOCD64LEN > eocdloc_offset + buf_offset) {
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 */
@@ -777,10 +852,10 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse
else {
if (zip_source_seek(src, (zip_int64_t)eocd_offset, SEEK_SET) < 0) {
zip_error_set_from_source(error, src);
return NULL;
return CDIR_INVALID;
}
if ((buffer = _zip_buffer_new_from_source(src, EOCD64LEN, eocd, error)) == NULL) {
return NULL;
return CDIR_INVALID;
}
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) {
_zip_buffer_free(buffer);
}
return NULL;
return CDIR_INVALID;
}
/* 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) {
_zip_buffer_free(buffer);
}
return NULL;
return CDIR_INVALID;
}
_zip_buffer_get(buffer, 4); /* skip version made by/needed */
num_disks64 = _zip_buffer_get_32(buffer);
eocd_disk64 = _zip_buffer_get_32(buffer);
/* 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);
this_disk = _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 (free_buffer) {
_zip_buffer_free(buffer);
}
return NULL;
}
if (num_disks != 0 || eocd_disk != 0) {
zip_error_set(error, ZIP_ER_MULTIDISK, 0);
if (free_buffer) {
_zip_buffer_free(buffer);
}
return NULL;
return CDIR_INVALID;
}
nentry = _zip_buffer_get_64(buffer);
i = _zip_buffer_get_64(buffer);
nentry = _zip_buffer_get_64(buffer);
if (nentry != i) {
zip_error_set(error, ZIP_ER_MULTIDISK, 0);
if (free_buffer) {
_zip_buffer_free(buffer);
}
return NULL;
return CDIR_INVALID;
}
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) {
_zip_buffer_free(buffer);
}
return NULL;
return CDIR_INVALID;
}
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) {
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_OVERLAPS_EOCD);
return NULL;
return CDIR_INVALID;
}
if (nentry > size / CDENTRYSIZE) {
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)
return 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)) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EOCD64_MISMATCH);
return CDIR_INVALID;
}
cd->is_zip64 = true;
cd->size = size;
cd->offset = offset;
cdir->is_zip64 = true;
cdir->size = size;
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') {
return c - '0';
}
@@ -906,17 +961,17 @@ static int decode_hex(char c) {
/* _zip_check_torrentzip:
check whether ZA has a valid TORRENTZIP comment, i.e. is torrentzipped */
static void zip_check_torrentzip(zip_t *za, const zip_cdir_t *cdir) {
static void
zip_check_torrentzip(zip_t *za, const zip_cdir_t *cdir) {
zip_uint32_t crc_should;
char buf[8+1];
char buf[8 + 1];
size_t i;
if (cdir == NULL) {
return;
}
if (_zip_string_length(cdir->comment) != TORRENTZIP_SIGNATURE_LENGTH + TORRENTZIP_CRC_LENGTH
|| strncmp((const char *)cdir->comment->raw, TORRENTZIP_SIGNATURE, TORRENTZIP_SIGNATURE_LENGTH) != 0)
if (_zip_string_length(cdir->comment) != TORRENTZIP_SIGNATURE_LENGTH + TORRENTZIP_CRC_LENGTH || strncmp((const char *)cdir->comment->raw, TORRENTZIP_SIGNATURE, TORRENTZIP_SIGNATURE_LENGTH) != 0)
return;
memcpy(buf, cdir->comment->raw + TORRENTZIP_SIGNATURE_LENGTH, TORRENTZIP_CRC_LENGTH);
@@ -934,8 +989,8 @@ static void zip_check_torrentzip(zip_t *za, const zip_cdir_t *cdir) {
{
zip_stat_t st;
zip_source_t* src_window;
zip_source_t* src_crc;
zip_source_t *src_window;
zip_source_t *src_crc;
zip_uint8_t buffer[512];
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.size = cdir->size;
st.crc = crc_should;
if ((src_window = _zip_source_window_new(za->src, cdir->offset, cdir->size, &st, 0, NULL, NULL, 0, false, NULL)) == NULL) {
if ((src_window = _zip_source_window_new(za->src, cdir->offset, cdir->size, &st, 0, NULL, NULL, NULL, 0, false, NULL)) == NULL) {
return;
}
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
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
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) {
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->last_update = current;
}

View File

@@ -1,6 +1,6 @@
/*
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.
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)
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.
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)
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
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
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.
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
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.
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
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
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
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.
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
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.
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
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.
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
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.
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
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
The authors can be contacted at <info@libzip.org>

View File

@@ -1,6 +1,6 @@
/*
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.
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
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.
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
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.
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
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.
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);
#endif /* _HAD_ZIP_SOURCE_FILE_H */

View File

@@ -1,6 +1,6 @@
/*
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.
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
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.
The authors can be contacted at <info@libzip.org>
@@ -120,7 +120,7 @@ _zip_stdio_op_seek(zip_source_file_context_t *ctx, void *f, zip_int64_t offset,
}
#endif
if (fseeko((FILE *)f, (off_t)offset, whence) < 0) {
if (zip_os_fseek((FILE *)f, (zip_off_t)offset, whence) < 0) {
zip_error_set(&ctx->error, ZIP_ER_SEEK, errno);
return false;
}
@@ -130,15 +130,15 @@ _zip_stdio_op_seek(zip_source_file_context_t *ctx, void *f, zip_int64_t offset,
bool
_zip_stdio_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st) {
struct stat sb;
zip_os_stat_t sb;
int ret;
if (ctx->fname) {
ret = stat(ctx->fname, &sb);
ret = zip_os_stat(ctx->fname, &sb);
}
else {
ret = fstat(fileno((FILE *)ctx->f), &sb);
ret = zip_os_fstat(fileno((FILE *)ctx->f), &sb);
}
if (ret < 0) {
@@ -168,7 +168,7 @@ _zip_stdio_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st) {
zip_int64_t
_zip_stdio_op_tell(zip_source_file_context_t *ctx, void *f) {
off_t offset = ftello((FILE *)f);
zip_off_t offset = zip_os_ftell((FILE *)f);
if (offset < 0) {
zip_error_set(&ctx->error, ZIP_ER_SEEK, errno);

View File

@@ -3,7 +3,7 @@
/*
zip_source_file_stdio.h -- common header for stdio file implementation
Copyright (C) 2020 Dieter Baron and Thomas Klausner
Copyright (C) 2020-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>

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