Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 107796758b | |||
| c30ad70301 |
@@ -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
@@ -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
@@ -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 */
|
||||
|
||||
@@ -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
@@ -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,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
@@ -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
@@ -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++;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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,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
@@ -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,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,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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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>
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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,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
@@ -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
@@ -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
@@ -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,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
@@ -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
@@ -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
@@ -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,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,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,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,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,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
@@ -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
@@ -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,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
@@ -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,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
@@ -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
@@ -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
@@ -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,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
@@ -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,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
@@ -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
@@ -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
@@ -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,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,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,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,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
@@ -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,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
@@ -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
@@ -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
@@ -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,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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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();
|
||||
|
||||
@@ -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
@@ -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
@@ -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,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>
|
||||
|
||||
@@ -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,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,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>
|
||||
|
||||
@@ -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
@@ -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,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,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,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
@@ -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
@@ -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
@@ -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,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
@@ -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
@@ -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
@@ -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
@@ -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 */
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
Reference in New Issue
Block a user