diff --git a/.github/workflows/scripts/linux/build-dependencies-qt.sh b/.github/workflows/scripts/linux/build-dependencies-qt.sh old mode 100644 new mode 100755 diff --git a/3rdparty/libzip/CMakeLists.txt b/3rdparty/libzip/CMakeLists.txt index 8e3516af67..a11c92a61f 100644 --- a/3rdparty/libzip/CMakeLists.txt +++ b/3rdparty/libzip/CMakeLists.txt @@ -196,6 +196,7 @@ add_library(zip STATIC lib/zip_name_locate.c lib/zip_new.c lib/zip_open.c + lib/zip_realloc.c lib/zip_pkware.c lib/zip_progress.c lib/zip_rename.c diff --git a/3rdparty/libzip/lib/zip.h b/3rdparty/libzip/lib/zip.h index 14064062f5..c2a8a8b469 100644 --- a/3rdparty/libzip/lib/zip.h +++ b/3rdparty/libzip/lib/zip.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" { diff --git a/3rdparty/libzip/lib/zip_add_entry.c b/3rdparty/libzip/lib/zip_add_entry.c index e8beaa819a..ccb4bf3775 100644 --- a/3rdparty/libzip/lib/zip_add_entry.c +++ b/3rdparty/libzip/lib/zip_add_entry.c @@ -44,10 +44,7 @@ _zip_add_entry(zip_t *za) { zip_uint64_t idx; if (za->nentry + 1 >= za->nentry_alloc) { - zip_entry_t *rentries; - zip_uint64_t nalloc = za->nentry_alloc; - zip_uint64_t additional_entries = 2 * nalloc; - zip_uint64_t realloc_size; + zip_uint64_t additional_entries = 2 * za->nentry_alloc; if (additional_entries < 16) { additional_entries = 16; @@ -55,21 +52,10 @@ _zip_add_entry(zip_t *za) { else if (additional_entries > 1024) { additional_entries = 1024; } - /* neither + nor * overflows can happen: nentry_alloc * sizeof(struct zip_entry) < UINT64_MAX */ - nalloc += additional_entries; - realloc_size = sizeof(struct zip_entry) * (size_t)nalloc; - if (sizeof(struct zip_entry) * (size_t)za->nentry_alloc > realloc_size) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + if (!ZIP_REALLOC(za->entry, za->nentry_alloc, additional_entries, &za->error)) { return -1; } - rentries = (zip_entry_t *)realloc(za->entry, sizeof(struct zip_entry) * (size_t)nalloc); - if (rentries == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; - } - za->entry = rentries; - za->nentry_alloc = nalloc; } idx = za->nentry++; diff --git a/3rdparty/libzip/lib/zip_algorithm_bzip2.c b/3rdparty/libzip/lib/zip_algorithm_bzip2.c index 1818039e84..d5311a7218 100644 --- a/3rdparty/libzip/lib/zip_algorithm_bzip2.c +++ b/3rdparty/libzip/lib/zip_algorithm_bzip2.c @@ -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; } diff --git a/3rdparty/libzip/lib/zip_algorithm_deflate.c b/3rdparty/libzip/lib/zip_algorithm_deflate.c index 5ab879dfef..402b7e8bc5 100644 --- a/3rdparty/libzip/lib/zip_algorithm_deflate.c +++ b/3rdparty/libzip/lib/zip_algorithm_deflate.c @@ -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; } diff --git a/3rdparty/libzip/lib/zip_algorithm_xz.c b/3rdparty/libzip/lib/zip_algorithm_xz.c index b0413e013c..adadc1cb5a 100644 --- a/3rdparty/libzip/lib/zip_algorithm_xz.c +++ b/3rdparty/libzip/lib/zip_algorithm_xz.c @@ -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; } diff --git a/3rdparty/libzip/lib/zip_algorithm_zstd.c b/3rdparty/libzip/lib/zip_algorithm_zstd.c index b2aa2132d0..21bb2498bb 100644 --- a/3rdparty/libzip/lib/zip_algorithm_zstd.c +++ b/3rdparty/libzip/lib/zip_algorithm_zstd.c @@ -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; } diff --git a/3rdparty/libzip/lib/zip_close.c b/3rdparty/libzip/lib/zip_close.c index 4313592cda..08692ef33f 100644 --- a/3rdparty/libzip/lib/zip_close.c +++ b/3rdparty/libzip/lib/zip_close.c @@ -42,7 +42,7 @@ #endif -static int add_data(zip_t *, zip_source_t *, zip_dirent_t *, zip_uint32_t); +static int add_data(zip_t *, zip_source_t *, zip_dirent_t *); static int copy_data(zip_t *, zip_uint64_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); @@ -195,6 +195,12 @@ zip_close(zip_t *za) { break; } } + else if (entry->orig != NULL) { + if (!_zip_dirent_merge(entry->changes, entry->orig, ZIP_ENTRY_DATA_CHANGED(entry), &za->error)) { + error = 1; + break; + } + } de = entry->changes; if (_zip_read_local_ef(za, i) < 0) { @@ -225,7 +231,7 @@ zip_close(zip_t *za) { } /* add_data writes dirent */ - if (add_data(za, zs ? zs : entry->source, de, entry->changes ? entry->changes->changed : 0) < 0) { + if (add_data(za, zs ? zs : entry->source, de) < 0) { error = 1; if (zs) zip_source_free(zs); @@ -295,8 +301,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_int64_t offstart, offdata, offend, data_length; zip_stat_t st; zip_file_attributes_t attributes; @@ -305,19 +310,25 @@ 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 dirent_changed; + bool have_dos_time = false; + 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 +383,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 +512,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); + } + + /* 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 +540,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 +558,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); + + 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) { diff --git a/3rdparty/libzip/lib/zip_dirent.c b/3rdparty/libzip/lib/zip_dirent.c index 24bc6abf9c..5ea8d6d784 100644 --- a/3rdparty/libzip/lib/zip_dirent.c +++ b/3rdparty/libzip/lib/zip_dirent.c @@ -83,32 +83,21 @@ _zip_cdir_new(zip_error_t *error) { bool _zip_cdir_grow(zip_cdir_t *cd, zip_uint64_t additional_entries, zip_error_t *error) { - zip_uint64_t i, new_alloc; - zip_entry_t *new_entry; + zip_uint64_t i; if (additional_entries == 0) { return true; } - new_alloc = cd->nentry_alloc + additional_entries; - - if (new_alloc < additional_entries || new_alloc > SIZE_MAX / sizeof(*(cd->entry))) { - zip_error_set(error, ZIP_ER_MEMORY, 0); + if (!ZIP_REALLOC(cd->entry, cd->nentry_alloc, additional_entries, error)) { return false; } - if ((new_entry = (zip_entry_t *)realloc(cd->entry, sizeof(*(cd->entry)) * (size_t)new_alloc)) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return false; - } - - cd->entry = new_entry; - - for (i = cd->nentry; i < new_alloc; i++) { + for (i = cd->nentry; i < cd->nentry_alloc; i++) { _zip_entry_init(cd->entry + i); } - cd->nentry = cd->nentry_alloc = new_alloc; + cd->nentry = cd->nentry_alloc; return true; } @@ -275,6 +264,55 @@ _zip_dirent_free(zip_dirent_t *zde) { } +bool +_zip_dirent_merge(zip_dirent_t *de, zip_dirent_t *de_orig, bool replacing_data, zip_error_t *error) { + if (!de->cloned) { + zip_error_set(error, ZIP_ER_INTERNAL, 0); + return false; + } + + if (!(de->changed & ZIP_DIRENT_ATTRIBUTES)) { + de->ext_attrib = de_orig->ext_attrib; + de->int_attrib = de_orig->int_attrib; + } + if (!(de->changed & ZIP_DIRENT_COMMENT)) { + de->comment = de_orig->comment; + } + if (!(de->changed & ZIP_DIRENT_COMP_METHOD)) { + if (replacing_data) { + de->comp_method = ZIP_CM_DEFAULT; + de->compression_level = 0; + } + else { + de->comp_method = de_orig->comp_method; + de->compression_level = de_orig->compression_level; + } + } + if (!(de->changed & ZIP_DIRENT_ENCRYPTION_METHOD)) { + if (replacing_data) { + de->encryption_method = ZIP_EM_NONE; + } + else { + de->encryption_method = de_orig->encryption_method; + } + } + if (!(de->changed & ZIP_DIRENT_EXTRA_FIELD)) { + de->extra_fields = de_orig->extra_fields; + } + if (!(de->changed & ZIP_DIRENT_FILENAME)) { + de->filename = de_orig->filename; + } + if (!(de->changed & ZIP_DIRENT_LAST_MOD)) { + de->last_mod = de_orig->last_mod; + } + if (!(de->changed & ZIP_DIRENT_PASSWORD)) { + de->password = de_orig->password; + } + + return true; +} + + void _zip_dirent_init(zip_dirent_t *de) { de->changed = 0; @@ -968,7 +1006,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 +1228,76 @@ _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_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->changed & ZIP_DIRENT_ATTRIBUTES) == 0 && (attributes->valid & ZIP_FILE_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 ((de->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; } @@ -1259,13 +1321,36 @@ zip_dirent_torrentzip_normalize(zip_dirent_t *de) { 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; + 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; diff --git a/3rdparty/libzip/lib/zip_fclose.c b/3rdparty/libzip/lib/zip_fclose.c index 2ef579a094..4dd29941ab 100644 --- a/3rdparty/libzip/lib/zip_fclose.c +++ b/3rdparty/libzip/lib/zip_fclose.c @@ -41,6 +41,9 @@ ZIP_EXTERN int zip_fclose(zip_file_t *zf) { int ret; + if (zf == NULL) + return ZIP_ER_INVAL; + if (zf->src) zip_source_free(zf->src); diff --git a/3rdparty/libzip/lib/zip_file_set_encryption.c b/3rdparty/libzip/lib/zip_file_set_encryption.c index 7bb6cdc7e9..2af55d6949 100644 --- a/3rdparty/libzip/lib/zip_file_set_encryption.c +++ b/3rdparty/libzip/lib/zip_file_set_encryption.c @@ -40,7 +40,7 @@ ZIP_EXTERN int zip_file_set_encryption(zip_t *za, zip_uint64_t idx, zip_uint16_t method, const char *password) { zip_entry_t *e; - zip_uint16_t old_method; + char *our_password = NULL; if (idx >= za->nentry) { zip_error_set(&za->error, ZIP_ER_INVAL, 0); @@ -63,56 +63,33 @@ zip_file_set_encryption(zip_t *za, zip_uint64_t idx, zip_uint16_t method, const e = za->entry + idx; - old_method = (e->orig == NULL ? ZIP_EM_NONE : e->orig->encryption_method); - if (method == old_method && password == NULL) { - if (e->changes) { - if (e->changes->changed & ZIP_DIRENT_PASSWORD) { - _zip_crypto_clear(e->changes->password, strlen(e->changes->password)); - free(e->changes->password); - e->changes->password = (e->orig == NULL ? NULL : e->orig->password); - } - e->changes->changed &= ~(ZIP_DIRENT_ENCRYPTION_METHOD | ZIP_DIRENT_PASSWORD); - if (e->changes->changed == 0) { - _zip_dirent_free(e->changes); - e->changes = NULL; - } + if (e->changes == NULL) { + if ((e->changes = _zip_dirent_clone(e->orig)) == NULL) { + zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; } } + + if (password) { + if ((our_password = strdup(password)) == NULL) { + zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; + } + } + + e->changes->encryption_method = method; + e->changes->changed |= ZIP_DIRENT_ENCRYPTION_METHOD; + if (password) { + e->changes->password = our_password; + e->changes->changed |= ZIP_DIRENT_PASSWORD; + } else { - char *our_password = NULL; - - if (password) { - if ((our_password = strdup(password)) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; - } - } - - if (e->changes == NULL) { - if ((e->changes = _zip_dirent_clone(e->orig)) == NULL) { - if (our_password) { - _zip_crypto_clear(our_password, strlen(our_password)); - } - free(our_password); - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; - } - } - - e->changes->encryption_method = method; - e->changes->changed |= ZIP_DIRENT_ENCRYPTION_METHOD; - if (password) { - e->changes->password = our_password; - e->changes->changed |= ZIP_DIRENT_PASSWORD; - } - else { - if (e->changes->changed & ZIP_DIRENT_PASSWORD) { - _zip_crypto_clear(e->changes->password, strlen(e->changes->password)); - free(e->changes->password); - e->changes->password = e->orig ? e->orig->password : NULL; - e->changes->changed &= ~ZIP_DIRENT_PASSWORD; - } + if (e->changes->changed & ZIP_DIRENT_PASSWORD) { + _zip_crypto_clear(e->changes->password, strlen(e->changes->password)); + free(e->changes->password); + e->changes->password = e->orig ? e->orig->password : NULL; + e->changes->changed &= ~ZIP_DIRENT_PASSWORD; } } diff --git a/3rdparty/libzip/lib/zip_open.c b/3rdparty/libzip/lib/zip_open.c index 9dccad6190..aee0da0d2e 100644 --- a/3rdparty/libzip/lib/zip_open.c +++ b/3rdparty/libzip/lib/zip_open.c @@ -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); diff --git a/3rdparty/libzip/lib/zip_realloc.c b/3rdparty/libzip/lib/zip_realloc.c new file mode 100644 index 0000000000..81948de619 --- /dev/null +++ b/3rdparty/libzip/lib/zip_realloc.c @@ -0,0 +1,62 @@ +/* + zip_realloc.c -- reallocate with additional elements + Copyright (C) 2009-2025 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include + +#include "zipint.h" + +bool zip_realloc(void **memory, zip_uint64_t *alloced_elements, zip_uint64_t element_size, zip_uint64_t additional_elements, zip_error_t *error) { + zip_uint64_t new_alloced_elements; + void *new_memory; + + if (additional_elements == 0) { + return true; + } + + new_alloced_elements = *alloced_elements + additional_elements; + + if (new_alloced_elements < additional_elements || new_alloced_elements > SIZE_MAX / element_size) { + zip_error_set(error, ZIP_ER_MEMORY, 0); + return false; + } + + if ((new_memory = realloc(*memory, (size_t)(new_alloced_elements * element_size))) == NULL) { + zip_error_set(error, ZIP_ER_MEMORY, 0); + return false; + } + + *memory = new_memory; + *alloced_elements = new_alloced_elements; + + return true; +} diff --git a/3rdparty/libzip/lib/zip_set_file_compression.c b/3rdparty/libzip/lib/zip_set_file_compression.c index cee099d5fe..45924d65ae 100644 --- a/3rdparty/libzip/lib/zip_set_file_compression.c +++ b/3rdparty/libzip/lib/zip_set_file_compression.c @@ -38,7 +38,6 @@ ZIP_EXTERN int zip_set_file_compression(zip_t *za, zip_uint64_t idx, zip_int32_t method, zip_uint32_t flags) { zip_entry_t *e; - zip_int32_t old_method; if (idx >= za->nentry) { zip_error_set(&za->error, ZIP_ER_INVAL, 0); @@ -61,35 +60,21 @@ zip_set_file_compression(zip_t *za, zip_uint64_t idx, zip_int32_t method, zip_ui e = za->entry + idx; - old_method = (e->orig == NULL ? ZIP_CM_DEFAULT : e->orig->comp_method); - /* TODO: do we want to recompress if level is set? Only if it's * different than what bit flags tell us, but those are not * defined for all compression methods, or not directly mappable * to levels */ - if (method == old_method) { - if (e->changes) { - e->changes->changed &= ~ZIP_DIRENT_COMP_METHOD; - e->changes->compression_level = 0; - if (e->changes->changed == 0) { - _zip_dirent_free(e->changes); - e->changes = NULL; - } + if (e->changes == NULL) { + if ((e->changes = _zip_dirent_clone(e->orig)) == NULL) { + zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; } } - else { - if (e->changes == NULL) { - if ((e->changes = _zip_dirent_clone(e->orig)) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; - } - } - e->changes->comp_method = method; - e->changes->compression_level = (zip_uint16_t)flags; - e->changes->changed |= ZIP_DIRENT_COMP_METHOD; - } + e->changes->comp_method = method; + e->changes->compression_level = (zip_uint16_t)flags; + e->changes->changed |= ZIP_DIRENT_COMP_METHOD; return 0; } diff --git a/3rdparty/libzip/lib/zip_source_buffer.c b/3rdparty/libzip/lib/zip_source_buffer.c index a680214a14..0464cb01fe 100644 --- a/3rdparty/libzip/lib/zip_source_buffer.c +++ b/3rdparty/libzip/lib/zip_source_buffer.c @@ -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; } @@ -427,32 +428,23 @@ buffer_free(buffer_t *buffer) { 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 additional_fragments; + zip_uint64_t offset_capacity = buffer->fragments_capacity + 1; - if (capacity < buffer->fragments_capacity) { + if (capacity <= buffer->fragments_capacity) { return true; } - zip_uint64_t fragments_size = sizeof(buffer->fragments[0]) * capacity; - zip_uint64_t offsets_size = sizeof(buffer->fragment_offsets[0]) * (capacity + 1); + additional_fragments = capacity - buffer->fragments_capacity; - 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); + if (!ZIP_REALLOC(buffer->fragments, buffer->fragments_capacity, additional_fragments, error)) { return false; } - - if ((fragments = realloc(buffer->fragments, (size_t)fragments_size)) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); + /* The size of both buffer->fragments and buffer->fragment_offsets is stored in buffer->fragments_capacity, so use a temporary capacity variable here for reallocating buffer->fragment_offsets. */ + if (!ZIP_REALLOC(buffer->fragment_offsets, offset_capacity, additional_fragments, error)) { + buffer->fragments_capacity -= additional_fragments; return false; } - buffer->fragments = fragments; - if ((offsets = realloc(buffer->fragment_offsets, (size_t)offsets_size)) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return false; - } - buffer->fragment_offsets = offsets; - buffer->fragments_capacity = capacity; return true; } diff --git a/3rdparty/libzip/lib/zip_source_compress.c b/3rdparty/libzip/lib/zip_source_compress.c index 54387ecaf8..333079616e 100644 --- a/3rdparty/libzip/lib/zip_source_compress.c +++ b/3rdparty/libzip/lib/zip_source_compress.c @@ -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) { diff --git a/3rdparty/libzip/lib/zip_source_file_stdio.c b/3rdparty/libzip/lib/zip_source_file_stdio.c index 0fb858f122..6e98517a81 100644 --- a/3rdparty/libzip/lib/zip_source_file_stdio.c +++ b/3rdparty/libzip/lib/zip_source_file_stdio.c @@ -95,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)) { diff --git a/3rdparty/libzip/lib/zip_source_file_win32_named.c b/3rdparty/libzip/lib/zip_source_file_win32_named.c index 811174205e..5219d6ac28 100644 --- a/3rdparty/libzip/lib/zip_source_file_win32_named.c +++ b/3rdparty/libzip/lib/zip_source_file_win32_named.c @@ -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(); diff --git a/3rdparty/libzip/lib/zip_source_get_file_attributes.c b/3rdparty/libzip/lib/zip_source_get_file_attributes.c index 209e39f506..59c064fe0f 100644 --- a/3rdparty/libzip/lib/zip_source_get_file_attributes.c +++ b/3rdparty/libzip/lib/zip_source_get_file_attributes.c @@ -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; } diff --git a/3rdparty/libzip/lib/zip_source_pkware_encode.c b/3rdparty/libzip/lib/zip_source_pkware_encode.c index fed76115bf..26e1ce7940 100644 --- a/3rdparty/libzip/lib/zip_source_pkware_encode.c +++ b/3rdparty/libzip/lib/zip_source_pkware_encode.c @@ -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; } diff --git a/3rdparty/libzip/lib/zip_source_window.c b/3rdparty/libzip/lib/zip_source_window.c index eac27c39d5..8b47246493 100644 --- a/3rdparty/libzip/lib/zip_source_window.c +++ b/3rdparty/libzip/lib/zip_source_window.c @@ -345,7 +345,7 @@ window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_sou void _zip_deregister_source(zip_t *za, zip_source_t *src) { - unsigned int i; + zip_uint64_t i; for (i = 0; i < za->nopen_source; i++) { if (za->open_source[i] == src) { @@ -359,18 +359,10 @@ _zip_deregister_source(zip_t *za, zip_source_t *src) { int _zip_register_source(zip_t *za, zip_source_t *src) { - zip_source_t **open_source; - if (za->nopen_source + 1 >= za->nopen_source_alloc) { - unsigned int n; - n = za->nopen_source_alloc + 10; - open_source = (zip_source_t **)realloc(za->open_source, n * sizeof(zip_source_t *)); - if (open_source == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + if (!ZIP_REALLOC(za->open_source, za->nopen_source_alloc, 10, &za->error)) { return -1; } - za->nopen_source_alloc = n; - za->open_source = open_source; } za->open_source[za->nopen_source++] = src; diff --git a/3rdparty/libzip/lib/zipint.h b/3rdparty/libzip/lib/zipint.h index e22d74c21d..296f3ecf6e 100644 --- a/3rdparty/libzip/lib/zipint.h +++ b/3rdparty/libzip/lib/zipint.h @@ -102,11 +102,14 @@ /* 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)) +#define ZIP_REALLOC(memory, alloced_elements, additional_elements, error) zip_realloc((void **)&memory, &alloced_elements, sizeof(*memory), additional_elements, error) + /* This section contains API that won't materialize like this. It's placed in the internal section, pending cleanup. */ @@ -152,7 +155,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 +244,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 */ @@ -305,8 +309,8 @@ struct zip { zip_uint64_t nentry_alloc; /* number of entries allocated */ zip_entry_t *entry; /* entries */ - unsigned int nopen_source; /* number of open sources using archive */ - unsigned int nopen_source_alloc; /* number of sources allocated */ + zip_uint64_t nopen_source; /* number of open sources using archive */ + zip_uint64_t nopen_source_alloc; /* number of sources allocated */ zip_source_t **open_source; /* open sources using archive */ zip_hash_t *names; /* hash table for name lookup */ @@ -552,13 +556,14 @@ 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); 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 *); void _zip_dirent_finalize(zip_dirent_t *); time_t zip_dirent_get_last_mod_mtime(zip_dirent_t *de); void _zip_dirent_init(zip_dirent_t *); +bool _zip_dirent_merge(zip_dirent_t *de, zip_dirent_t *de_orig, bool replacing_data, zip_error_t *error); bool _zip_dirent_needs_zip64(const zip_dirent_t *, zip_flags_t); zip_dirent_t *_zip_dirent_new(void); bool zip_dirent_process_ef_zip64(zip_dirent_t * zde, const zip_uint8_t * ef, zip_uint64_t got_len, bool local, zip_error_t * error); @@ -618,6 +623,8 @@ int _zip_progress_start(zip_progress_t *progress); int _zip_progress_subrange(zip_progress_t *progress, double start, double end); int _zip_progress_update(zip_progress_t *progress, double value); +bool zip_realloc(void **memory, zip_uint64_t *alloced_elements, zip_uint64_t element_size, zip_uint64_t additional_elements, zip_error_t *error); + /* this symbol is extern so it can be overridden for regression testing */ ZIP_EXTERN bool zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length); zip_uint32_t zip_random_uint32(void); diff --git a/3rdparty/libzip/libzip.vcxproj b/3rdparty/libzip/libzip.vcxproj index 0b8308b242..553cc6fe97 100644 --- a/3rdparty/libzip/libzip.vcxproj +++ b/3rdparty/libzip/libzip.vcxproj @@ -86,6 +86,7 @@ +