2 Commits

Author SHA1 Message Date
SaraP 107796758b libzip 1.11.4 :
- aggiornamento alla versione 1.11.4.
2025-08-25 11:06:55 +02:00
Dario Sassi c30ad70301 libzip :
- ricompilazione per Win32 senza più limite a Windows XP.
2025-01-09 17:49:42 +01:00
134 changed files with 1566 additions and 888 deletions
+53 -24
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>
@@ -123,14 +123,64 @@ 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__SEEK64)
/* Windows API using int64 */
typedef zip_int64_t zip_off_t;
typedef struct _stat64 zip_os_stat_t;
#define zip_os_stat _stat64
#define zip_os_fstat _fstat64
#define zip_os_seek _fseeki64
#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! */
@@ -179,27 +229,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
+5 -2
View File
@@ -10,10 +10,13 @@
#define HAVE__DUP
#define HAVE__FDOPEN
#define HAVE__FILENO
#define HAVE__FSEEKI64
#define HAVE__FSTAT64
#define HAVE__SETMODE
#define HAVE__SNPRINTF
#define HAVE__SNPRINTF_S
#define HAVE__SNWPRINTF_S
#define HAVE__STAT64
#define HAVE__STRDUP
#define HAVE__STRICMP
#define HAVE__STRTOI64
@@ -29,6 +32,7 @@
/* #undef HAVE_FSEEKO */
/* #undef HAVE_FTELLO */
/* #undef HAVE_GETPROGNAME */
/* #undef HAVE_GETSECURITYINFO */
/* #undef HAVE_GNUTLS */
/* #undef HAVE_LIBBZ2 */
/* #undef HAVE_LIBLZMA */
@@ -38,7 +42,6 @@
#define HAVE_MEMCPY_S
/* #undef HAVE_MBEDTLS */
/* #undef HAVE_MKSTEMP */
/* #undef HAVE_NULLABLE */
/* #undef HAVE_OPENSSL */
#define HAVE_SETMODE
#define HAVE_SNPRINTF
@@ -67,6 +70,6 @@
#define HAVE_SHARED
/* END DEFINES */
#define PACKAGE "libzip"
#define VERSION "1.10.0"
#define VERSION "1.11.4"
#endif /* HAD_CONFIG_H */
+5 -2
View File
@@ -10,10 +10,13 @@
#define HAVE__DUP
#define HAVE__FDOPEN
#define HAVE__FILENO
#define HAVE__FSEEKI64
#define HAVE__FSTAT64
#define HAVE__SETMODE
#define HAVE__SNPRINTF
#define HAVE__SNPRINTF_S
#define HAVE__SNWPRINTF_S
#define HAVE__STAT64
#define HAVE__STRDUP
#define HAVE__STRICMP
#define HAVE__STRTOI64
@@ -29,6 +32,7 @@
/* #undef HAVE_FSEEKO */
/* #undef HAVE_FTELLO */
/* #undef HAVE_GETPROGNAME */
#define HAVE_GETSECURITYINFO
/* #undef HAVE_GNUTLS */
/* #undef HAVE_LIBBZ2 */
/* #undef HAVE_LIBLZMA */
@@ -38,7 +42,6 @@
#define HAVE_MEMCPY_S
/* #undef HAVE_MBEDTLS */
/* #undef HAVE_MKSTEMP */
/* #undef HAVE_NULLABLE */
/* #undef HAVE_OPENSSL */
#define HAVE_SETMODE
#define HAVE_SNPRINTF
@@ -67,6 +70,6 @@
#define HAVE_SHARED
/* END DEFINES */
#define PACKAGE "libzip"
#define VERSION "1.10.0"
#define VERSION "1.11.4"
#endif /* HAD_CONFIG_H */
+16 -16
View File
@@ -56,8 +56,8 @@ VS_VERSION_INFO$(NDEB64) VERSIONINFO
#else
VS_VERSION_INFO VERSIONINFO
#endif
FILEVERSION 1,10,0,0
PRODUCTVERSION 1,10,0,0
FILEVERSION 1,11,4,0
PRODUCTVERSION 1,11,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -73,12 +73,12 @@ BEGIN
BLOCK "040904b0"
BEGIN
VALUE "FileDescription", "Libzip Release Version"
VALUE "FileVersion", "1.10.0.0"
VALUE "FileVersion", "1.11.4.0"
VALUE "InternalName", "zipR64.dll"
VALUE "LegalCopyright", "Copyright (C) 2021"
VALUE "OriginalFilename", "zipR64.dll"
VALUE "ProductName", "libzip"
VALUE "ProductVersion", "1.10.0.0"
VALUE "ProductVersion", "1.11.0.0"
END
END
BLOCK "VarFileInfo"
@@ -94,8 +94,8 @@ VS_VERSION_INFO$(NDEB32) VERSIONINFO
#else
VS_VERSION_INFO VERSIONINFO
#endif
FILEVERSION 1,10,0,0
PRODUCTVERSION 1,10,0,0
FILEVERSION 1,11,4,0
PRODUCTVERSION 1,11,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -111,11 +111,11 @@ BEGIN
BLOCK "040904b0"
BEGIN
VALUE "FileDescription", "Libzip Release Version"
VALUE "FileVersion", "1.10.0.0"
VALUE "FileVersion", "1.11.4.0"
VALUE "InternalName", "zipR32.dll"
VALUE "OriginalFilename", "zipR32.dll"
VALUE "ProductName", "libzip"
VALUE "ProductVersion", "1.10.0.0"
VALUE "ProductVersion", "1.11.0.0"
END
END
BLOCK "VarFileInfo"
@@ -131,8 +131,8 @@ VS_VERSION_INFO$(_DEB64) VERSIONINFO
#else
VS_VERSION_INFO VERSIONINFO
#endif
FILEVERSION 1,10,0,0
PRODUCTVERSION 1,10,0,0
FILEVERSION 1,11,4,0
PRODUCTVERSION 1,11,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -148,11 +148,11 @@ BEGIN
BLOCK "040904b0"
BEGIN
VALUE "FileDescription", "Libzip Debug Version"
VALUE "FileVersion", "1.10.0.0"
VALUE "FileVersion", "1.11.4.0"
VALUE "InternalName", "zipD64.dll"
VALUE "OriginalFilename", "zipD64.dll"
VALUE "ProductName", "libzip"
VALUE "ProductVersion", "1.10.0.0"
VALUE "ProductVersion", "1.11.0.0"
END
END
BLOCK "VarFileInfo"
@@ -168,8 +168,8 @@ VS_VERSION_INFO$(_DEB32) VERSIONINFO
#else
VS_VERSION_INFO VERSIONINFO
#endif
FILEVERSION 1,10,0,0
PRODUCTVERSION 1,10,0,0
FILEVERSION 1,11,4,0
PRODUCTVERSION 1,11,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -185,11 +185,11 @@ BEGIN
BLOCK "040904b0"
BEGIN
VALUE "FileDescription", "Libzip Debug Version"
VALUE "FileVersion", "1.10.0.0"
VALUE "FileVersion", "1.11.4.0"
VALUE "InternalName", "zipD32.dll"
VALUE "OriginalFilename", "zipD32.dll"
VALUE "ProductName", "libzip"
VALUE "ProductVersion", "1.10.0.0"
VALUE "ProductVersion", "1.11.0.0"
END
END
BLOCK "VarFileInfo"
+4 -2
View File
@@ -29,13 +29,13 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141_xp</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141_xp</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
@@ -284,6 +284,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClCompile Include="zip_pkware.c" />
<ClCompile Include="zip_progress.c" />
<ClCompile Include="zip_random_win32.c" />
<ClCompile Include="zip_realloc.c" />
<ClCompile Include="zip_rename.c" />
<ClCompile Include="zip_replace.c" />
<ClCompile Include="zip_set_archive_comment.c" />
@@ -311,6 +312,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClCompile Include="zip_source_file_win32_utf8.c" />
<ClCompile Include="zip_source_free.c" />
<ClCompile Include="zip_source_function.c" />
<ClCompile Include="zip_source_get_dostime.c" />
<ClCompile Include="zip_source_get_file_attributes.c" />
<ClCompile Include="zip_source_is_deleted.c" />
<ClCompile Include="zip_source_layered.c" />
+1 -1
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>
+1 -1
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>
+3 -17
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>
@@ -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) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1;
}
za->entry = rentries;
za->nentry_alloc = nalloc;
}
idx = za->nentry++;
+3 -3
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>
@@ -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;
}
+2 -3
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;
+109 -51
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>
@@ -42,9 +42,9 @@
#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_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);
@@ -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;
}
@@ -396,6 +423,11 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
src_final = src;
zip_source_keep(src_final);
if (!needs_decrypt && st.encryption_method == ZIP_EM_TRAD_PKWARE && (de->changed & ZIP_DIRENT_LAST_MOD)) {
/* PKWare encryption uses the last modification time for password verification, therefore we can't change it without re-encrypting. Ignoring the requested modification time change seems more sensible than failing to close the archive. */
de->changed &= ~ZIP_DIRENT_LAST_MOD;
}
if (needs_decrypt) {
zip_encryption_implementation impl;
@@ -463,11 +495,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;
}
@@ -484,22 +512,39 @@ 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);
}
if ((offdata = zip_source_tell_write(za->src)) < 0) {
zip_error_set_from_source(&za->error, za->src);
/* 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;
}
ret = copy_source(za, src_final, data_length);
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;
}
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);
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);
@@ -513,44 +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) {
if (st.valid & ZIP_STAT_MTIME)
de->last_mod = st.mtime;
else
time(&de->last_mod);
}
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) {
@@ -600,7 +652,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;
@@ -623,7 +675,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;
@@ -737,4 +795,4 @@ static int torrentzip_compare_names(const void *a, const void *b) {
}
return strcasecmp(aname, bname);
}
}
+1 -1
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>
+1 -1
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>
+1 -1
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>
+1 -1
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>
+1 -1
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>
+1 -4
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>
+1 -1
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>
+1 -1
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>
+1 -1
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>
+254 -101
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,43 +77,27 @@ _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;
}
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;
}
@@ -126,8 +111,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 +119,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 +127,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 +141,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);
@@ -287,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;
@@ -294,11 +320,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 +364,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 +375,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 +418,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 +486,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 +530,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 +547,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 +579,7 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
return -1;
}
}
is_zip64 = true;
}
@@ -545,10 +590,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 +639,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 +701,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 +724,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 +772,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 +871,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;
@@ -922,18 +1006,18 @@ _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)) {
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 +1118,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 +1126,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,72 +1203,101 @@ _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;
}
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;
}
@@ -1192,10 +1305,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 +1317,44 @@ 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) {
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) {
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;
}
+1 -1
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>
+1 -1
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>
+9
View File
@@ -47,6 +47,9 @@ const struct _zip_err_info _zip_err_str[] = {
{ S, "Tell error" },
{ N, "Compressed data invalid" },
{ 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]);
@@ -72,6 +75,12 @@ 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" },
{ G, "garbage at end of compressed data" },
};
const int _zip_err_details_count = sizeof(_zip_err_details)/sizeof(_zip_err_details[0]);
+1 -1
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>
+1 -1
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>
+1 -1
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>
+1 -1
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>
+13 -1
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;
+1 -1
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>
+1 -1
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>
+1 -5
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;
+4 -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>
@@ -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);
+1 -1
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>
+1 -1
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>
+1 -1
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>
+1 -1
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>
+1 -1
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>
+1 -1
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>
+1 -1
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>
+1 -1
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>
+7 -1
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);
+1 -1
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>
+25 -48
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>
@@ -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;
}
}
+1 -1
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>
+28 -12
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);
}
+1 -1
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>
+1 -1
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>
+1 -1
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>
+1 -1
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>
+1 -1
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>
+5 -3
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);
+6 -4
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;
}
+5 -3
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) {
+1 -1
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>
+1 -1
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>
+1 -1
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>
+1 -1
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>
+1 -1
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>
+1 -1
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>
+1 -1
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>
+1 -1
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>
+2 -2
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>
@@ -70,7 +70,7 @@ _zip_read_data(zip_buffer_t *buffer, zip_source_t *src, size_t length, bool nulp
}
r = (zip_uint8_t *)malloc(length + (nulp ? 1 : 0));
if (!r) {
if (r == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
+1 -1
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>
+2 -2
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;
}
+3 -2
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;
}
+282 -227
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(&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);
}
}
/* 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) {
+1 -1
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>
+2 -2
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;
}
+2 -1
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>
@@ -74,6 +74,7 @@ zip_random_uint32(void) {
if (!seeded) {
srand((unsigned int)time(NULL));
seeded = true;
}
return (zip_uint32_t)rand();
+62
View File
@@ -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 <info@libzip.org>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#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;
}
+1 -1
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>
+1 -1
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>
+1 -1
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>
+3 -2
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>
@@ -57,7 +57,8 @@ zip_set_archive_flag(zip_t *za, zip_flags_t flag, int value) {
return 0;
}
if (ZIP_IS_RDONLY(za)) {
/* Allow removing ZIP_AFL_RDONLY if manually set, not if archive was opened read-only. */
if (za->flags & ZIP_AFL_RDONLY) {
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
+1 -1
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>
+1 -1
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>
+8 -23
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>
@@ -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;
}
+1 -1
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>
+1 -1
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>
+1 -1
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>
+1 -1
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>
+10 -18
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>
@@ -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;
}
+1 -1
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>
+1 -1
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>
+1 -1
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>
+27 -14
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>
@@ -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) {
+1 -1
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>
+1 -1
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>
+6 -1
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 */
+17 -7
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>
@@ -54,6 +54,7 @@ zip_source_file_common_new(const char *fname, void *file, zip_uint64_t start, zi
zip_source_file_context_t *ctx;
zip_source_t *zs;
zip_source_file_stat_t sb;
zip_uint64_t length;
if (ops == NULL) {
zip_error_set(error, ZIP_ER_INVAL, 0);
@@ -82,10 +83,17 @@ zip_source_file_common_new(const char *fname, void *file, zip_uint64_t start, zi
}
if (len < 0) {
len = 0;
if (len == -1) {
len = ZIP_LENGTH_TO_END;
}
// TODO: return ZIP_ER_INVAL if len != ZIP_LENGTH_UNCHECKED?
length = 0;
}
else {
length = (zip_uint64_t)len;
}
if (start > ZIP_INT64_MAX || start + (zip_uint64_t)len < start) {
if (start > ZIP_INT64_MAX || start + length < start) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
@@ -107,7 +115,7 @@ zip_source_file_common_new(const char *fname, void *file, zip_uint64_t start, zi
}
ctx->f = file;
ctx->start = start;
ctx->len = (zip_uint64_t)len;
ctx->len = length;
if (st) {
(void)memcpy_s(&ctx->st, sizeof(ctx->st), st, sizeof(*st));
ctx->st.name = NULL;
@@ -169,9 +177,11 @@ zip_source_file_common_new(const char *fname, void *file, zip_uint64_t start, zi
}
if (ctx->len == 0) {
ctx->len = sb.size - ctx->start;
ctx->st.size = ctx->len;
ctx->st.valid |= ZIP_STAT_SIZE;
if (len != ZIP_LENGTH_UNCHECKED) {
ctx->len = sb.size - ctx->start;
ctx->st.size = ctx->len;
ctx->st.valid |= ZIP_STAT_SIZE;
}
/* when using a partial file, don't allow writing */
if (ctx->fname && start == 0 && ops->write != NULL) {
+9 -8
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>
@@ -39,7 +39,6 @@
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#ifdef _WIN32
#ifndef S_IWUSR
@@ -78,7 +77,7 @@ zip_source_filep(zip_t *za, FILE *file, zip_uint64_t start, zip_int64_t len) {
ZIP_EXTERN zip_source_t *
zip_source_filep_create(FILE *file, zip_uint64_t start, zip_int64_t length, zip_error_t *error) {
if (file == NULL || length < -1) {
if (file == NULL || length < ZIP_LENGTH_UNCHECKED) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
@@ -96,9 +95,11 @@ _zip_stdio_op_close(zip_source_file_context_t *ctx) {
zip_int64_t
_zip_stdio_op_read(zip_source_file_context_t *ctx, void *buf, zip_uint64_t len) {
size_t i;
#if SIZE_MAX < ZIP_UINT64_MAX
if (len > SIZE_MAX) {
len = SIZE_MAX;
}
#endif
if ((i = fread(buf, 1, (size_t)len, ctx->f)) == 0) {
if (ferror((FILE *)ctx->f)) {
@@ -120,7 +121,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 +131,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 +169,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);
+1 -1
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>
+2 -2
View File
@@ -1,6 +1,6 @@
/*
zip_source_file_win32.c -- read-only Windows file source implementation
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>
@@ -69,7 +69,7 @@ zip_source_win32handle(zip_t *za, HANDLE h, zip_uint64_t start, zip_int64_t len)
ZIP_EXTERN zip_source_t *
zip_source_win32handle_create(HANDLE h, zip_uint64_t start, zip_int64_t length, zip_error_t *error) {
if (h == INVALID_HANDLE_VALUE || length < -1) {
if (h == INVALID_HANDLE_VALUE || length < ZIP_LENGTH_UNCHECKED) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
+2 -9
View File
@@ -3,7 +3,7 @@
/*
zip_source_file_win32.h -- common header for Windows file implementation
Copyright (C) 2020 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>
@@ -59,6 +59,7 @@ struct zip_win32_file_operations {
BOOL(__stdcall *move_file)(const void *from, const void *to, DWORD flags);
BOOL(__stdcall *set_file_attributes)(const void *name, DWORD attributes);
char *(*string_duplicate)(const char *string);
HANDLE(__stdcall *find_first_file)(const void *name, void *data);
};
typedef struct zip_win32_file_operations zip_win32_file_operations_t;
@@ -73,12 +74,4 @@ zip_int64_t _zip_win32_op_tell(zip_source_file_context_t *ctx, void *f);
bool _zip_filetime_to_time_t(FILETIME ft, time_t *t);
int _zip_win32_error_to_errno(DWORD win32err);
#ifdef __clang__
#define DONT_WARN_INCOMPATIBLE_FN_PTR_BEGIN _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wincompatible-function-pointer-types\"")
#define DONT_WARN_INCOMPATIBLE_FN_PTR_END _Pragma("GCC diagnostic pop")
#else
#define DONT_WARN_INCOMPATIBLE_FN_PTR_BEGIN
#define DONT_WARN_INCOMPATIBLE_FN_PTR_END
#endif
#endif /* _HAD_ZIP_SOURCE_FILE_WIN32_H */
+58 -13
View File
@@ -1,6 +1,6 @@
/*
zip_source_file_win32_ansi.c -- source for Windows file opened by ANSI name
Copyright (C) 1999-2020 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>
@@ -34,24 +34,28 @@
#include "zip_source_file_win32.h"
static char *ansi_allocate_tempname(const char *name, size_t extra_chars, size_t *lengthp);
static HANDLE __stdcall ansi_create_file(const void *name, DWORD access, DWORD share_mode, PSECURITY_ATTRIBUTES security_attributes, DWORD creation_disposition, DWORD file_attributes, HANDLE template_file);
static BOOL __stdcall ansi_delete_file(const void *name);
static DWORD __stdcall ansi_get_file_attributes(const void *name);
static BOOL __stdcall ansi_get_file_attributes_ex(const void *name, GET_FILEEX_INFO_LEVELS info_level, void *information);
static void ansi_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i);
static BOOL __stdcall ansi_move_file(const void *from, const void *to, DWORD flags);
static BOOL __stdcall ansi_set_file_attributes(const void *name, DWORD attributes);
static HANDLE __stdcall ansi_find_first_file(const void *name, void* data);
/* clang-format off */
DONT_WARN_INCOMPATIBLE_FN_PTR_BEGIN
zip_win32_file_operations_t ops_ansi = {
ansi_allocate_tempname,
CreateFileA,
DeleteFileA,
GetFileAttributesA,
GetFileAttributesExA,
ansi_create_file,
ansi_delete_file,
ansi_get_file_attributes,
ansi_get_file_attributes_ex,
ansi_make_tempname,
MoveFileExA,
SetFileAttributesA,
strdup
ansi_move_file,
ansi_set_file_attributes,
strdup,
ansi_find_first_file,
};
DONT_WARN_INCOMPATIBLE_FN_PTR_END
/* clang-format on */
ZIP_EXTERN zip_source_t *
@@ -65,7 +69,7 @@ zip_source_win32a(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t
ZIP_EXTERN zip_source_t *
zip_source_win32a_create(const char *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error) {
if (fname == NULL || length < -1) {
if (fname == NULL || length < ZIP_LENGTH_UNCHECKED) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
@@ -80,8 +84,49 @@ ansi_allocate_tempname(const char *name, size_t extra_chars, size_t *lengthp) {
return (char *)malloc(*lengthp);
}
static HANDLE __stdcall
ansi_create_file(const void *name, DWORD access, DWORD share_mode, PSECURITY_ATTRIBUTES security_attributes, DWORD creation_disposition, DWORD file_attributes, HANDLE template_file)
{
return CreateFileA((const char *)name, access, share_mode, security_attributes, creation_disposition, file_attributes, template_file);
}
static BOOL __stdcall
ansi_delete_file(const void *name)
{
return DeleteFileA((const char *)name);
}
static DWORD __stdcall
ansi_get_file_attributes(const void *name)
{
return GetFileAttributesA((const char *)name);
}
static BOOL __stdcall
ansi_get_file_attributes_ex(const void *name, GET_FILEEX_INFO_LEVELS info_level, void *information)
{
return GetFileAttributesExA((const char *)name, info_level, information);
}
static void
ansi_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i) {
snprintf_s(buf, len, "%s.%08x", name, i);
}
static BOOL __stdcall
ansi_move_file(const void *from, const void *to, DWORD flags)
{
return MoveFileExA((const char *)from, (const char *)to, flags);
}
static BOOL __stdcall
ansi_set_file_attributes(const void *name, DWORD attributes)
{
return SetFileAttributesA((const char *)name, attributes);
}
static HANDLE __stdcall
ansi_find_first_file(const void *name, void *data)
{
return FindFirstFileA((const char *)name, data);
}
+19 -10
View File
@@ -1,6 +1,6 @@
/*
zip_source_file_win32_named.c -- source for Windows file opened by name
Copyright (C) 1999-2020 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>
@@ -99,25 +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;
success = GetSecurityInfo((HANDLE)ctx->f, SE_FILE_OBJECT, si, NULL, NULL, &dacl, NULL, &psd);
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();
@@ -210,8 +209,18 @@ _zip_win32_named_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t
st->regular_file = false;
if (file_attributes.dwFileAttributes != INVALID_FILE_ATTRIBUTES) {
if ((file_attributes.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE | FILE_ATTRIBUTE_REPARSE_POINT)) == 0) {
st->regular_file = true;
if ((file_attributes.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE)) == 0) {
if (file_attributes.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
WIN32_FIND_DATA find_data;
/* Deduplication on Windows replaces files with reparse points;
* accept them as regular files. */
if (file_ops->find_first_file(ctx->fname, &find_data) != INVALID_HANDLE_VALUE) {
st->regular_file = (find_data.dwReserved0 == IO_REPARSE_TAG_DEDUP);
}
}
else {
st->regular_file = true;
}
}
}
+53 -14
View File
@@ -1,6 +1,6 @@
/*
zip_source_file_win32_utf16.c -- source for Windows file opened by UTF-16 name
Copyright (C) 1999-2020 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>
@@ -34,26 +34,30 @@
#include "zip_source_file_win32.h"
static char *utf16_allocate_tempname(const char *name, size_t extra_chars, size_t *lengthp);
static HANDLE __stdcall utf16_create_file(const char *name, DWORD access, DWORD share_mode, PSECURITY_ATTRIBUTES security_attributes, DWORD creation_disposition, DWORD file_attributes, HANDLE template_file);
static HANDLE __stdcall utf16_create_file(const void *name, DWORD access, DWORD share_mode, PSECURITY_ATTRIBUTES security_attributes, DWORD creation_disposition, DWORD file_attributes, HANDLE template_file);
static BOOL __stdcall utf16_delete_file(const void *name);
static DWORD __stdcall utf16_get_file_attributes(const void *name);
static BOOL __stdcall utf16_get_file_attributes_ex(const void *name, GET_FILEEX_INFO_LEVELS info_level, void *information);
static void utf16_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i);
static BOOL __stdcall utf16_move_file(const void *from, const void *to, DWORD flags);
static BOOL __stdcall utf16_set_file_attributes(const void *name, DWORD attributes);
static char *utf16_strdup(const char *string);
static HANDLE __stdcall utf16_find_first_file(const void *name, void* data);
/* clang-format off */
DONT_WARN_INCOMPATIBLE_FN_PTR_BEGIN
zip_win32_file_operations_t ops_utf16 = {
utf16_allocate_tempname,
utf16_create_file,
DeleteFileW,
GetFileAttributesW,
GetFileAttributesExW,
utf16_delete_file,
utf16_get_file_attributes,
utf16_get_file_attributes_ex,
utf16_make_tempname,
MoveFileExW,
SetFileAttributesW,
utf16_strdup
utf16_move_file,
utf16_set_file_attributes,
utf16_strdup,
utf16_find_first_file
};
DONT_WARN_INCOMPATIBLE_FN_PTR_END
/* clang-format on */
ZIP_EXTERN zip_source_t *
@@ -67,7 +71,7 @@ zip_source_win32w(zip_t *za, const wchar_t *fname, zip_uint64_t start, zip_int64
ZIP_EXTERN zip_source_t *
zip_source_win32w_create(const wchar_t *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error) {
if (fname == NULL || length < -1) {
if (fname == NULL || length < ZIP_LENGTH_UNCHECKED) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
@@ -84,7 +88,7 @@ utf16_allocate_tempname(const char *name, size_t extra_chars, size_t *lengthp) {
}
static HANDLE __stdcall utf16_create_file(const char *name, DWORD access, DWORD share_mode, PSECURITY_ATTRIBUTES security_attributes, DWORD creation_disposition, DWORD file_attributes, HANDLE template_file) {
static HANDLE __stdcall utf16_create_file(const void *name, DWORD access, DWORD share_mode, PSECURITY_ATTRIBUTES security_attributes, DWORD creation_disposition, DWORD file_attributes, HANDLE template_file) {
#ifdef MS_UWP
CREATEFILE2_EXTENDED_PARAMETERS extParams = {0};
extParams.dwFileAttributes = file_attributes;
@@ -100,14 +104,49 @@ static HANDLE __stdcall utf16_create_file(const char *name, DWORD access, DWORD
#endif
}
static BOOL __stdcall
utf16_delete_file(const void *name)
{
return DeleteFileW((const wchar_t *)name);
}
static DWORD __stdcall
utf16_get_file_attributes(const void *name)
{
return GetFileAttributesW((const wchar_t *)name);
}
static BOOL __stdcall
utf16_get_file_attributes_ex(const void *name, GET_FILEEX_INFO_LEVELS info_level, void *information)
{
return GetFileAttributesExW((const wchar_t *)name, info_level, information);
}
static void
utf16_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i) {
_snwprintf_s((wchar_t *)buf, len, len, L"%s.%08x", (const wchar_t *)name, i);
}
static BOOL __stdcall
utf16_move_file(const void *from, const void *to, DWORD flags)
{
return MoveFileExW((const wchar_t *)from, (const wchar_t *)to, flags);
}
static BOOL __stdcall
utf16_set_file_attributes(const void *name, DWORD attributes)
{
return SetFileAttributesW((const wchar_t *)name, attributes);
}
static char *
utf16_strdup(const char *string) {
return (char *)_wcsdup((const wchar_t *)string);
}
static HANDLE __stdcall
utf16_find_first_file(const void *name, void* data)
{
return FindFirstFileW((const wchar_t *)name, data);
}
+2 -2
View File
@@ -1,6 +1,6 @@
/*
zip_source_file_win32_ansi.c -- source for Windows file opened by UTF-8 name
Copyright (C) 1999-2020 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,7 +49,7 @@ zip_source_file_create(const char *fname, zip_uint64_t start, zip_int64_t length
wchar_t *wfname;
zip_source_t *source;
if (fname == NULL || length < -1) {
if (fname == NULL || length < ZIP_LENGTH_UNCHECKED) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
+1 -1
View File
@@ -1,6 +1,6 @@
/*
zip_source_free.c -- free zip data source
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>

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