zlib/minizip: Update to version 1.3.1.2

This commit is contained in:
Rémi Verschelde
2025-12-12 15:31:04 +01:00
parent 08e6cd181f
commit 88fd9d7073
23 changed files with 1069 additions and 308 deletions

57
thirdparty/minizip/ints.h vendored Normal file
View File

@@ -0,0 +1,57 @@
/* ints.h -- create integer types for 8, 16, 32, and 64 bits
* Copyright (C) 2024 Mark Adler
* For conditions of distribution and use, see the copyright notice in zlib.h
*
* There exist compilers with limits.h, but not stdint.h or inttypes.h.
*/
#ifndef INTS_H
#define INTS_H
#include <limits.h>
#if defined(UCHAR_MAX) && UCHAR_MAX == 0xff
typedef signed char i8_t;
typedef unsigned char ui8_t;
#else
# error "no 8-bit integer"
#endif
#if defined(USHRT_MAX) && USHRT_MAX == 0xffff
typedef short i16_t;
typedef unsigned short ui16_t;
#elif defined(UINT_MAX) && UINT_MAX == 0xffff
typedef int i16_t;
typedef unsigned ui16_t;
#else
# error "no 16-bit integer"
#endif
#if defined(UINT_MAX) && UINT_MAX == 0xffffffff
typedef int i32_t;
typedef unsigned ui32_t;
# define PI32 "d"
# define PUI32 "u"
#elif defined(ULONG_MAX) && ULONG_MAX == 0xffffffff
typedef long i32_t;
typedef unsigned long ui32_t;
# define PI32 "ld"
# define PUI32 "lu"
#else
# error "no 32-bit integer"
#endif
#if defined(ULONG_MAX) && ULONG_MAX == 0xffffffffffffffff
typedef long i64_t;
typedef unsigned long ui64_t;
# define PI64 "ld"
# define PUI64 "lu"
#elif defined(ULLONG_MAX) && ULLONG_MAX == 0xffffffffffffffff
typedef long long i64_t;
typedef unsigned long long ui64_t;
# define PI64 "lld"
# define PUI64 "llu"
#elif defined(ULONG_LONG_MAX) && ULONG_LONG_MAX == 0xffffffffffffffff
typedef long long i64_t;
typedef unsigned long long ui64_t;
# define PI64 "lld"
# define PUI64 "llu"
#else
# error "no 64-bit integer"
#endif
#endif

View File

@@ -15,7 +15,7 @@
#endif
#if defined(__APPLE__) || defined(IOAPI_NO_64) || defined(__HAIKU__) || defined(MINIZIP_FOPEN_NO_64)
// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
/* In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions */
#define FOPEN_FUNC(filename, mode) fopen(filename, mode)
#define FTELLO_FUNC(stream) ftello(stream)
#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)

View File

@@ -18,13 +18,13 @@
*/
#ifndef _ZLIBIOAPI64_H
#define _ZLIBIOAPI64_H
#ifndef ZLIBIOAPI64_H
#define ZLIBIOAPI64_H
#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
// Linux needs this to support file operation on files larger then 4+GB
// But might need better if/def to select just the platforms that needs them.
/* Linux needs this to support file operation on files larger then 4+GB */
/* But might need better if/def to select just the platforms that needs them.*/
#ifndef __USE_FILE_OFFSET64
#define __USE_FILE_OFFSET64
@@ -67,39 +67,12 @@
#endif
#endif
/*
#ifndef ZPOS64_T
#ifdef _WIN32
#define ZPOS64_T fpos_t
#else
#include <stdint.h>
#define ZPOS64_T uint64_t
#endif
#endif
*/
#ifdef HAVE_MINIZIP64_CONF_H
#include "mz64conf.h"
#endif
/* a type chosen by DEFINE */
#ifdef HAVE_64BIT_INT_CUSTOM
typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T;
#else
#ifdef HAS_STDINT_H
#include "stdint.h"
typedef uint64_t ZPOS64_T;
#else
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef unsigned __int64 ZPOS64_T;
#else
typedef unsigned long long int ZPOS64_T;
#endif
#endif
#endif
#include "ints.h"
typedef ui64_t ZPOS64_T;
/* Maximum unsigned 32-bit value used as placeholder for zip64 */
#ifndef MAXU32
@@ -192,8 +165,8 @@ typedef struct zlib_filefunc64_32_def_s
#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream))
//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode))
/*#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) */
/*#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode)) */
#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream))
#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream))

View File

@@ -1,5 +1,5 @@
diff --git a/thirdparty/minizip/ioapi.c b/thirdparty/minizip/ioapi.c
index 782d32469a..2e393aca2d 100644
index 3dbefe48c2..b072ecdcc2 100644
--- a/thirdparty/minizip/ioapi.c
+++ b/thirdparty/minizip/ioapi.c
@@ -75,9 +75,12 @@ void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filef
@@ -22,10 +22,10 @@ index 782d32469a..2e393aca2d 100644
+
+#endif
diff --git a/thirdparty/minizip/ioapi.h b/thirdparty/minizip/ioapi.h
index a2d2e6e60d..556dd8ad18 100644
index 6b9968c732..be64d7db45 100644
--- a/thirdparty/minizip/ioapi.h
+++ b/thirdparty/minizip/ioapi.h
@@ -155,6 +155,8 @@ typedef struct zlib_filefunc_def_s
@@ -128,6 +128,8 @@ typedef struct zlib_filefunc_def_s
close_file_func zclose_file;
testerror_file_func zerror_file;
voidpf opaque;
@@ -34,7 +34,7 @@ index a2d2e6e60d..556dd8ad18 100644
} zlib_filefunc_def;
typedef ZPOS64_T (ZCALLBACK *tell64_file_func) (voidpf opaque, voidpf stream);
@@ -171,6 +173,8 @@ typedef struct zlib_filefunc64_def_s
@@ -144,6 +146,8 @@ typedef struct zlib_filefunc64_def_s
close_file_func zclose_file;
testerror_file_func zerror_file;
voidpf opaque;
@@ -44,10 +44,10 @@ index a2d2e6e60d..556dd8ad18 100644
void fill_fopen64_filefunc(zlib_filefunc64_def* pzlib_filefunc_def);
diff --git a/thirdparty/minizip/unzip.c b/thirdparty/minizip/unzip.c
index ea05b7d62a..7e8a6ac2d3 100644
index e9088bd542..98a568e098 100644
--- a/thirdparty/minizip/unzip.c
+++ b/thirdparty/minizip/unzip.c
@@ -152,6 +152,7 @@ typedef struct
@@ -148,6 +148,7 @@ typedef struct
uLong compression_method; /* compression method (0==store) */
ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
int raw;
@@ -55,7 +55,7 @@ index ea05b7d62a..7e8a6ac2d3 100644
} file_in_zip64_read_info_s;
@@ -513,9 +514,9 @@ local unzFile unzOpenInternal(const void *path,
@@ -509,9 +510,9 @@ local unzFile unzOpenInternal(const void *path,
us.z_filefunc.zseek32_file = NULL;
us.z_filefunc.ztell32_file = NULL;
if (pzlib_filefunc64_32_def==NULL)
@@ -68,7 +68,7 @@ index ea05b7d62a..7e8a6ac2d3 100644
us.is64bitOpenFunction = is64bitOpenFunction;
@@ -703,6 +704,15 @@ extern unzFile ZEXPORT unzOpen64(const void *path) {
@@ -699,6 +700,15 @@ extern unzFile ZEXPORT unzOpen64(const void *path) {
return unzOpenInternal(path, NULL, 1);
}
@@ -84,7 +84,7 @@ index ea05b7d62a..7e8a6ac2d3 100644
/*
Close a ZipFile opened with unzOpen.
If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
@@ -905,10 +915,19 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file,
@@ -901,10 +911,19 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file,
if (lSeek!=0)
{
@@ -108,7 +108,7 @@ index ea05b7d62a..7e8a6ac2d3 100644
}
while(acc < file_info.size_file_extra)
@@ -1446,8 +1465,8 @@ extern int ZEXPORT unzOpenCurrentFile3(unzFile file, int* method,
@@ -1442,8 +1461,8 @@ extern int ZEXPORT unzOpenCurrentFile3(unzFile file, int* method,
}
else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw))
{
@@ -119,7 +119,7 @@ index ea05b7d62a..7e8a6ac2d3 100644
pfile_in_zip_read_info->stream.opaque = (voidpf)0;
pfile_in_zip_read_info->stream.next_in = 0;
pfile_in_zip_read_info->stream.avail_in = 0;
@@ -1480,6 +1499,7 @@ extern int ZEXPORT unzOpenCurrentFile3(unzFile file, int* method,
@@ -1476,6 +1495,7 @@ extern int ZEXPORT unzOpenCurrentFile3(unzFile file, int* method,
iSizeVar;
pfile_in_zip_read_info->stream.avail_in = (uInt)0;
@@ -127,7 +127,7 @@ index ea05b7d62a..7e8a6ac2d3 100644
s->pfile_in_zip_read = pfile_in_zip_read_info;
s->encrypted = 0;
@@ -1510,6 +1530,84 @@ extern int ZEXPORT unzOpenCurrentFile3(unzFile file, int* method,
@@ -1506,6 +1526,84 @@ extern int ZEXPORT unzOpenCurrentFile3(unzFile file, int* method,
return UNZ_OK;
}
@@ -213,7 +213,7 @@ index ea05b7d62a..7e8a6ac2d3 100644
return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
}
diff --git a/thirdparty/minizip/unzip.h b/thirdparty/minizip/unzip.h
index 5cfc9c6274..37ff29b22a 100644
index ceb614e783..d515cdafce 100644
--- a/thirdparty/minizip/unzip.h
+++ b/thirdparty/minizip/unzip.h
@@ -202,6 +202,8 @@ extern int ZEXPORT unzClose(unzFile file);
@@ -225,7 +225,7 @@ index 5cfc9c6274..37ff29b22a 100644
extern int ZEXPORT unzGetGlobalInfo(unzFile file,
unz_global_info *pglobal_info);
@@ -390,6 +392,11 @@ extern int ZEXPORT unzReadCurrentFile(unzFile file,
@@ -394,6 +396,11 @@ extern int ZEXPORT unzReadCurrentFile(unzFile file,
(UNZ_ERRNO for IO error, or zLib error for uncompress error)
*/
@@ -238,10 +238,10 @@ index 5cfc9c6274..37ff29b22a 100644
extern ZPOS64_T ZEXPORT unztell64(unzFile file);
diff --git a/thirdparty/minizip/zip.c b/thirdparty/minizip/zip.c
index 60bdffac34..078a0a82ec 100644
index 103f325d37..4fd193e1f3 100644
--- a/thirdparty/minizip/zip.c
+++ b/thirdparty/minizip/zip.c
@@ -820,9 +820,9 @@ extern zipFile ZEXPORT zipOpen3(const void *pathname, int append, zipcharpc* glo
@@ -1061,9 +1061,9 @@ extern zipFile ZEXPORT zipOpen3(const void *pathname, int append, zipcharpc* glo
ziinit.z_filefunc.zseek32_file = NULL;
ziinit.z_filefunc.ztell32_file = NULL;
@@ -254,7 +254,7 @@ index 60bdffac34..078a0a82ec 100644
ziinit.z_filefunc = *pzlib_filefunc64_32_def;
ziinit.filestream = ZOPEN64(ziinit.z_filefunc,
@@ -1182,8 +1182,8 @@ extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char* filename, c
@@ -1423,8 +1423,8 @@ extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char* filename, c
{
if(zi->ci.method == Z_DEFLATED)
{

361
thirdparty/minizip/skipset.h vendored Normal file
View File

@@ -0,0 +1,361 @@
/* skipset.h -- set operations using a skiplist
// Copyright (C) 2024 Mark Adler
// See MiniZip_info.txt for the license.
// This implements a skiplist set, i.e. just keys, no data, with ~O(log n) time
// insert and search operations. The application defines the type of a key, and
// provides a function to compare two keys.
// This header is not definitions of functions found in another source file --
// it creates the set functions, with the application's key type, right where
// the #include is. Before this header is #included, these must be defined:
//
// 1. A macro or typedef for set_key_t, the type of a key.
// 2. A macro or function set_cmp(a, b) to compare two keys. The return values
// are < 0 for a < b, 0 for a == b, and > 0 for a > b.
// 3. A macro or function set_drop(s, k) to release the key k's resources, if
// any, when doing a set_end() or set_clear(). s is a pointer to the set
// that key is in, for use with set_free() if desired.
//
// Example usage:
//
// typedef int set_key_t;
// #define set_cmp(a, b) ((a) < (b) ? -1 : (a) == (b) ? 0 : 1)
// #define set_drop(s, k)
// #include "skipset.h"
//
// int test(void) { // return 0: good, 1: bad, -1: out of memory
// set_t set;
// if (setjmp(set.env))
// return -1;
// set_start(&set);
// set_insert(&set, 2);
// set_insert(&set, 1);
// set_insert(&set, 7);
// int bad = !set_found(&set, 2);
// bad = bad || set_found(&set, 5);
// set_end(&set);
// return bad;
// }
//
// Interface summary (see more details below):
// - set_t is the type of the set being operated on (a set_t pointer is passed)
// - set_start() initializes a new, empty set (initialize set.env first)
// - set_insert() inserts a new key into the set, or not if it's already there
// - set_found() determines whether or not a key is in the set
// - set_end() ends the use of the set, freeing all memory
// - set_clear() empties the set, equivalent to set_end() and then set_start()
// - set_ok() checks if set appears to be usable, i.e. started and not ended
//
// Auxiliary functions available to the application:
// - set_alloc() allocates memory with optional tracking (#define SET_TRACK)
// - set_free() deallocates memory allocated by set_alloc()
// - set_rand() returns 32 random bits (seeded by set_start()) */
#ifndef SKIPSET_H
#define SKIPSET_H
#include <stdlib.h> /* realloc(), free(), NULL, size_t */
#include <stddef.h> /* ptrdiff_t */
#include <setjmp.h> /* jmp_buf, longjmp() */
#include <errno.h> /* ENOMEM */
#include <time.h> /* time(), clock() */
#include <assert.h> /* assert.h */
#include "ints.h" /* i16_t, ui32_t, ui64_t */
/* Structures and functions below noted as "--private--" should not be used by
// the application. set_t is partially private and partially public -- see the
// comments there.
// There is no POSIX random() in MSVC, and rand() is awful. For portability, we
// cannot rely on a library function for random numbers. Instead we use the
// fast and effective algorithm below, invented by Melissa O'Neill.
// *Really* minimal PCG32 code / (c) 2014 M.E. O'Neill / www.pcg-random.org
// Licensed under Apache License 2.0 (NO WARRANTY, etc. see website)
// --private-- Random number generator state. */
typedef struct {
ui64_t state; /* 64-bit generator state */
ui64_t inc; /* 63-bit sequence id */
} set_rand_t;
/* --private-- Initialize the state *gen using seed and seq. seed seeds the
// advancing 64-bit state. seq is a sequence selection constant. */
void set_seed(set_rand_t *gen, ui64_t seed, ui64_t seq) {
gen->inc = (seq << 1) | 1;
gen->state = (seed + gen->inc) * 6364136223846793005ULL + gen->inc;
}
/* Return 32 random bits, advancing the state *gen. */
ui32_t set_rand(set_rand_t *gen) {
ui64_t state = gen->state;
gen->state = state * 6364136223846793005ULL + gen->inc;
ui32_t mix = (ui32_t)(((state >> 18) ^ state) >> 27);
int rot = state >> 59;
return (mix >> rot) | (mix << ((-rot) & 31));
}
/* End of PCG32 code. */
/* --private-- Linked-list node. */
typedef struct set_node_s set_node_t;
struct set_node_s {
set_key_t key; /* the key (not used for head or path) */
i16_t size; /* number of allocated pointers in right[] */
i16_t fill; /* number of pointers in right[] filled in */
set_node_t **right; /* pointer for each level, each to the right */
};
/* A set. The application sets env, may use gen with set_rand(), and may read
// allocs and memory. The remaining variables are --private-- . */
typedef struct set_s {
set_node_t *head; /* skiplist head -- no key, just links */
set_node_t *path; /* right[] is path to key from set_found() */
set_node_t *node; /* node under construction, in case of longjmp() */
i16_t depth; /* maximum depth of the skiplist */
ui64_t ran; /* a precious trove of random bits */
set_rand_t gen; /* random number generator state */
jmp_buf env; /* setjmp() environment for allocation errors */
#ifdef SET_TRACK
size_t allocs; /* number of allocations */
size_t memory; /* total amount of allocated memory (>= requests) */
#endif
} set_t;
/* Memory allocation and deallocation. set_alloc(set, ptr, size) returns a
// pointer to an allocation of size bytes if ptr is NULL, or the previous
// allocation ptr resized to size bytes. set_alloc() will never return NULL.
// set_free(set, ptr) frees an allocation created by set_alloc(). These may be
// used by the application. e.g. if allocation tracking is desired. */
#ifdef SET_TRACK
/* Track the number of allocations and the total backing memory size. */
# if defined(_WIN32)
# include <malloc.h>
# define SET_ALLOC_SIZE(ptr) _msize(ptr)
# elif defined(__MACH__)
# include <malloc/malloc.h>
# define SET_ALLOC_SIZE(ptr) malloc_size(ptr)
# elif defined(__linux__)
# include <malloc.h>
# define SET_ALLOC_SIZE(ptr) malloc_usable_size(ptr)
# elif defined(__FreeBSD__)
# include <malloc_np.h>
# define SET_ALLOC_SIZE(ptr) malloc_usable_size(ptr)
# elif defined(__NetBSD__)
# include <jemalloc/jemalloc.h>
# define SET_ALLOC_SIZE(ptr) malloc_usable_size(ptr)
# else // e.g. OpenBSD
# define SET_ALLOC_SIZE(ptr) 0
# endif
// With tracking.
void *set_alloc(set_t *set, void *ptr, size_t size) {
size_t had = ptr == NULL ? 0 : SET_ALLOC_SIZE(ptr);
void *mem = realloc(ptr, size);
if (mem == NULL)
longjmp(set->env, ENOMEM);
set->allocs += ptr == NULL;
set->memory += SET_ALLOC_SIZE(mem) - had;
return mem;
}
void set_free(set_t *set, void *ptr) {
if (ptr != NULL) {
set->allocs--;
set->memory -= SET_ALLOC_SIZE(ptr);
free(ptr);
}
}
#else
/* Without tracking. */
void *set_alloc(set_t *set, void *ptr, size_t size) {
void *mem = realloc(ptr, size);
if (mem == NULL)
longjmp(set->env, ENOMEM);
return mem;
}
void set_free(set_t *set, void *ptr) {
(void)set;
free(ptr);
}
#endif
/* --private-- Grow node's array right[] as needed to be able to hold at least
// want links. If fill is true, assure that the first want links are filled in,
// setting them to set->head if not previously filled in. Otherwise it is
// assumed that the first want links are about to be filled in. */
void set_grow(set_t *set, set_node_t *node, int want, int fill) {
if (node->size < want) {
int more = node->size ? node->size : 1;
while (more < want)
more <<= 1;
node->right = set_alloc(set, node->right, more * sizeof(set_node_t *));
node->size = (i16_t)more;
}
int i;
if (fill)
for (i = node->fill; i < want; i++)
node->right[i] = set->head;
node->fill = (i16_t)want;
}
/* --private-- Return a new node. key is left uninitialized. */
set_node_t *set_node(set_t *set) {
set_node_t *node = set_alloc(set, NULL, sizeof(set_node_t));
node->size = 0;
node->fill = 0;
node->right = NULL;
return node;
}
/* --private-- Free the list linked from head, along with the keys. */
void set_sweep(set_t *set) {
set_node_t *step = set->head->right[0];
while (step != set->head) {
set_node_t *next = step->right[0]; /* save link to next node */
set_drop(set, step->key);
set_free(set, step->right);
set_free(set, step);
step = next;
}
}
/* Initialize a new set. set->env must be initialized using setjmp() before
// set_start() is called. A longjmp(set->env, ENOMEM) will be used to handle a
// memory allocation failure during any of the operations. (See setjmp.h and
// errno.h.) The set can still be used if this happens, assuming that it didn't
// happen during set_start(). Whether set_start() completed or not, set_end()
// can be used to free the set's memory after a longjmp(). */
void set_start(set_t *set) {
#ifdef SET_TRACK
set->allocs = 0;
set->memory = 0;
#endif
set->head = set->path = set->node = NULL; /* in case set_node() fails */
set->path = set_node(set);
set->head = set_node(set);
set_grow(set, set->head, 1, 1); /* one link back to head for an empty set */
*(unsigned char *)&set->head->key = 137; /* set id */
set->depth = 0;
set_seed(&set->gen, ((ui64_t)(ptrdiff_t)set << 32) ^
((ui64_t)time(NULL) << 12) ^ clock(), 0);
set->ran = 1;
}
/* Return true if *set appears to be in a usable state. If *set has been zeroed
// out, then set_ok(set) will be false and set_end(set) will be safe. */
int set_ok(set_t *set) {
return set->head != NULL &&
set->head->right != NULL &&
*(unsigned char *)&set->head->key == 137;
}
/* Empty the set. This frees the memory used for the previous set contents.
// After set_clear(), *set is ready for use, as if after a set_start(). */
void set_clear(set_t *set) {
assert(set_ok(set) && "improper use");
/* Free all the keys and their nodes. */
set_sweep(set);
/* Leave the head and path allocations as is. Clear their contents, with
// head pointing to itself and setting depth to zero, for an empty set. */
set->head->right[0] = set->head;
set->head->fill = 1;
set->path->fill = 0;
set->depth = 0;
}
/* Done using the set -- free all allocations. The only operation on *set
// permitted after this is set_start(). Though another set_end() would do no
// harm. This can be done at any time after a set_start(), or after a longjmp()
// on any allocation failure, including during a set_start(). */
void set_end(set_t *set) {
if (set->head != NULL) {
/* Empty the set and free the head node. */
if (set->head->right != NULL) {
set_sweep(set);
set_free(set, set->head->right);
}
set_free(set, set->head);
set->head = NULL;
}
if (set->path != NULL) {
/* Free the path work area. */
set_free(set, set->path->right);
set_free(set, set->path);
set->path = NULL;
}
if (set->node != NULL) {
/* Free the node that was under construction when longjmp() hit. */
set_drop(set, set->node->key);
set_free(set, set->node->right);
set_free(set, set->node);
set->node = NULL;
}
}
/* Look for key. Return 1 if found or 0 if not. This also puts the path to get
// there in set->path, for use by set_insert(). */
int set_found(set_t *set, set_key_t key) {
assert(set_ok(set) && "improper use");
/* Start at depth and work down and right as determined by key comparisons. */
set_node_t *head = set->head, *here = head;
int i = set->depth;
set_grow(set, set->path, i + 1, 0);
do {
while (here->right[i] != head &&
set_cmp(here->right[i]->key, key) < 0)
here = here->right[i];
set->path->right[i] = here;
} while (i--);
/* See if the key matches. */
here = here->right[0];
return here != head && set_cmp(here->key, key) == 0;
}
/* Insert the key key. Return 0 on success, or 1 if key is already in the set. */
int set_insert(set_t *set, set_key_t key) {
assert(set_ok(set) && "improper use");
if (set_found(set, key))
/* That key is already in the set. */
return 1;
/* Randomly generate a new level-- level 0 with probability 1/2, 1 with
// probability 1/4, 2 with probability 1/8, etc. */
int level = 0;
for (;;) {
if (set->ran == 1)
/* Ran out. Get another 32 random bits. */
set->ran = set_rand(&set->gen) | (1ULL << 32);
int bit = set->ran & 1;
set->ran >>= 1;
if (bit)
break;
assert(level < 32767 &&
"Overhead, without any fuss, the stars were going out.");
level++;
}
if (level > set->depth) {
/* The maximum depth is now deeper. Update the structures. */
set_grow(set, set->path, level + 1, 1);
set_grow(set, set->head, level + 1, 1);
set->depth = (i16_t)level;
}
/* Make a new node for the provided key, and insert it in the lists up to
// and including level. */
set->node = set_node(set);
set->node->key = key;
set_grow(set, set->node, level + 1, 0);
int i;
for (i = 0; i <= level; i++) {
set->node->right[i] = set->path->right[i]->right[i];
set->path->right[i]->right[i] = set->node;
}
set->node = NULL;
return 0;
}
#else
#error ** another skiplist set already created here
/* Would need to implement a prefix in order to support multiple sets. */
#endif

View File

@@ -68,10 +68,6 @@
#include <stdlib.h>
#include <string.h>
#ifndef NOUNCRYPT
#define NOUNCRYPT
#endif
#include "zlib.h"
#include "unzip.h"
@@ -92,7 +88,7 @@
#ifndef CASESENSITIVITYDEFAULT_NO
# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
# if (!defined(__unix__) && !defined(__unix) || defined(__CYGWIN__)) && !defined(CASESENSITIVITYDEFAULT_YES)
# define CASESENSITIVITYDEFAULT_NO
# endif
#endif
@@ -856,7 +852,7 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file,
if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
err=UNZ_ERRNO;
// relative offset of local header
/* relative offset of local header */
if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
err=UNZ_ERRNO;
file_info_internal.offset_curfile = uL;
@@ -879,7 +875,7 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file,
lSeek -= uSizeRead;
}
// Read extrafield
/* Read extrafield */
if ((err==UNZ_OK) && (extraField!=NULL))
{
ZPOS64_T uSizeRead ;
@@ -910,7 +906,7 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file,
{
uLong acc = 0;
// since lSeek now points to after the extra field we need to move back
/* since lSeek now points to after the extra field we need to move back */
lSeek -= file_info.size_file_extra;
if (lSeek!=0)
@@ -1627,10 +1623,10 @@ extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64(unzFile file) {
file_in_zip64_read_info_s* pfile_in_zip_read_info;
s=(unz64_s*)file;
if (file==NULL)
return 0; //UNZ_PARAMERROR;
return 0; /* UNZ_PARAMERROR; */
pfile_in_zip_read_info=s->pfile_in_zip_read;
if (pfile_in_zip_read_info==NULL)
return 0; //UNZ_PARAMERROR;
return 0; /* UNZ_PARAMERROR; */
return pfile_in_zip_read_info->pos_in_zipfile +
pfile_in_zip_read_info->byte_before_the_zipfile;
}
@@ -1711,7 +1707,7 @@ extern int ZEXPORT unzReadCurrentFile(unzFile file, voidp buf, unsigned len) {
uInt i;
for(i=0;i<uReadThis;i++)
pfile_in_zip_read_info->read_buffer[i] =
zdecode(s->keys,s->pcrc_32_tab,
(char)zdecode(s->keys,s->pcrc_32_tab,
pfile_in_zip_read_info->read_buffer[i]);
}
# endif
@@ -1799,7 +1795,7 @@ extern int ZEXPORT unzReadCurrentFile(unzFile file, voidp buf, unsigned len) {
if (err!=BZ_OK)
break;
#endif
} // end Z_BZIP2ED
} /* end Z_BZIP2ED */
else
{
ZPOS64_T uTotalOutBefore,uTotalOutAfter;
@@ -2042,7 +2038,7 @@ extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) {
unz64_s* s;
if (file==NULL)
return 0; //UNZ_PARAMERROR;
return 0; /* UNZ_PARAMERROR; */
s=(unz64_s*)file;
if (!s->current_file_ok)
return 0;
@@ -2056,7 +2052,7 @@ extern uLong ZEXPORT unzGetOffset(unzFile file) {
ZPOS64_T offset64;
if (file==NULL)
return 0; //UNZ_PARAMERROR;
return 0; /* UNZ_PARAMERROR; */
offset64 = unzGetOffset64(file);
return (uLong)offset64;
}

View File

@@ -315,6 +315,10 @@ extern int ZEXPORT unzGetCurrentFileInfo(unzFile file,
This is the Central-header version of the extra field
if szComment!=NULL, the comment string of the file will be copied in szComment
(commentBufferSize is the size of the buffer)
The file name and comment will be zero-terminated if there is room in the
provided buffer. Otherwise the buffer will contain as much as will fit. If at
least 65537 bytes of room is provided, then the result will always be
complete and zero-terminated.
*/

View File

@@ -25,8 +25,10 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <time.h>
#ifndef ZLIB_CONST
# define ZLIB_CONST
#endif
#include "zlib.h"
#include "zip.h"
@@ -50,7 +52,7 @@
#endif
#ifndef Z_BUFSIZE
#define Z_BUFSIZE (64*1024) //(16384)
#define Z_BUFSIZE (64*1024) /* (16384) */
#endif
#ifndef Z_MAXFILENAMEINZIP
@@ -69,7 +71,7 @@
/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
// NOT sure that this work on ALL platform
/* NOT sure that this work on ALL platform */
#define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32))
#ifndef SEEK_CUR
@@ -123,6 +125,19 @@ typedef struct linkedlist_data_s
} linkedlist_data;
/* zipAlreadyThere() set functions for a set of zero-terminated strings, and
// a block_t type for reading the central directory datablocks. */
typedef char *set_key_t;
#define set_cmp(a, b) strcmp(a, b)
#define set_drop(s, k) set_free(s, k)
#include "skipset.h"
typedef struct {
unsigned char *next; /* next byte in datablock data */
size_t left; /* number of bytes left in data (at least) */
linkedlist_datablock_internal *node; /* current datablock */
} block_t;
typedef struct
{
z_stream stream; /* zLib stream structure for inflate */
@@ -174,6 +189,10 @@ typedef struct
char *globalcomment;
#endif
/* Support for zipAlreadyThere(). */
set_t set; /* set for detecting name collisions */
block_t block; /* block for reading the central directory */
} zip64_internal;
@@ -264,6 +283,228 @@ local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len)
return ZIP_OK;
}
/* zipAlreadyThere() operations. "set" in the zip internal structure keeps the
// set of names that are in the under-construction central directory so far. A
// skipset provides ~O(log n) time insertion and searching. Central directory
// records, stored in a linked list of allocated memory datablocks, is read
// through "block" in the zip internal structure.
// The block_*() functions support extracting the central directory file names
// from the datablocks. They are designed to support a growing directory by
// automatically continuing once more data has been appended to the linked
// datablocks.
// Initialize *block to the head of list. This should only be called once the
// list has at least some data in it, i.e. list->first_block is not NULL. */
local void block_init(block_t *block, linkedlist_data *list) {
block->node = list->first_block;
block->next = block->node->data;
block->left = block->node->filled_in_this_block;
}
/* Mark *block as bad, with all subsequent reads returning end, even if more
// data is added to the datablocks. This is invoked if the central directory is
// invalid, so there is no longer any point in attempting to interpret it. */
local void block_stop(block_t *block) {
block->left = 0;
block->next = NULL;
}
/* Return true if *block has reached the end of the data in the datablocks. */
local int block_end(block_t *block) {
linkedlist_datablock_internal *node = block->node;
if (node == NULL)
/* This block was previously terminated with extreme prejudice. */
return 1;
if (block->next < node->data + node->filled_in_this_block)
/* There are more bytes to read in the current datablock. */
return 0;
while (node->next_datablock != NULL) {
if (node->filled_in_this_block != 0)
/* There are some bytes in a later datablock. */
return 0;
node = node->next_datablock;
}
/* Reached the end of the list of datablocks. There's nothing. */
return 1;
}
/* Return one byte from *block, or -1 if the end is reached. */
local int block_get(block_t *block) {
while (block->left == 0) {
if (block->node == NULL)
/* We've been marked bad. Return end. */
return -1;
/* Update left in case more was filled in since we were last here. */
block->left = block->node->filled_in_this_block -
(block->next - block->node->data);
if (block->left != 0)
/* There was indeed more data appended in the current datablock. */
break;
if (block->node->next_datablock == NULL)
/* No more data here, and there is no next datablock. At the end. */
return -1;
/* Try the next datablock for more data. */
block->node = block->node->next_datablock;
block->next = block->node->data;
block->left = block->node->filled_in_this_block;
}
/* We have a byte to return. */
block->left--;
return *block->next++;
}
/* Return a 16-bit unsigned little-endian value from block, or a negative value
// if the end is reached. */
local long block_get2(block_t *block) {
long got = block_get(block);
return got | ((unsigned long)block_get(block) << 8);
}
/* Read up to len bytes from block into buf. Return the number of bytes read. */
local size_t block_read(block_t *block, unsigned char *buf, size_t len) {
size_t need = len;
while (need) {
if (block->left == 0) {
/* Get a byte to update and step through the linked list as needed. */
int got = block_get(block);
if (got == -1)
/* Reached the end. */
break;
*buf++ = (unsigned char)got;
need--;
continue;
}
size_t take = need > block->left ? block->left : need;
memcpy(buf, block->next, take);
block->next += take;
block->left -= take;
buf += take;
need -= take;
}
return len - need; /* return the number of bytes copied */
}
/* Skip n bytes in block. Return 0 on success or -1 if there are less than n
// bytes to the end. */
local int block_skip(block_t *block, size_t n) {
while (n > block->left) {
n -= block->left;
block->next += block->left;
block->left = 0;
if (block_get(block) == -1)
return -1;
n--;
}
block->next += n;
block->left -= n;
return 0;
}
/* Process the next central directory record at *block. Return the allocated,
// zero-terminated file name, or NULL for end of input or invalid data. If
// invalid, *block is marked bad. This uses *set for the allocation of memory. */
local char *block_central_name(block_t *block, set_t *set) {
char *name = NULL;
for (;;) {
if (block_end(block))
/* At the end of the central directory (so far). */
return NULL;
/* Check for a central directory record signature. */
if (block_get2(block) != (CENTRALHEADERMAGIC & 0xffff) ||
block_get2(block) != (CENTRALHEADERMAGIC >> 16))
/* Incorrect signature. */
break;
/* Go through the remaining fixed-length portion of the record,
// extracting the lengths of the three variable-length fields. */
block_skip(block, 24);
unsigned flen = block_get2(block); /* file name length */
unsigned xlen = block_get2(block); /* extra field length */
unsigned clen = block_get2(block); /* comment field length */
if (block_skip(block, 12) == -1)
/* Premature end of the record. */
break;
/* Extract the name and skip over the extra and comment fields. */
name = set_alloc(set, NULL, flen + 1);
if (block_read(block, (unsigned char *)name, flen) < flen ||
block_skip(block, xlen + clen) == -1)
/* Premature end of the record. */
break;
/* Check for embedded nuls in the name. */
if (memchr(name, 0, flen) != NULL) {
/* This name can never match the zero-terminated name provided to
// zipAlreadyThere(), so we discard it and go back to get another
// name. (Who the heck is putting nuls inside their zip file entry
// names anyway?) */
set_free(set, name);
continue;
}
/* All good. Return the zero-terminated file name. */
name[flen] = 0;
return name;
}
/* Invalid signature or premature end of the central directory record.
// Abandon trying to process the central directory. */
set_free(set, name);
block_stop(block);
return NULL;
}
/* Return 0 if name is not in the central directory so far, 1 if it is, -1 if
// the central directory is invalid, -2 if out of memory, or ZIP_PARAMERROR if
// file is NULL. */
extern int ZEXPORT zipAlreadyThere(zipFile file, char const *name) {
zip64_internal *zip = file;
if (zip == NULL)
return ZIP_PARAMERROR;
if (zip->central_dir.first_block == NULL)
/* No central directory yet, so no, name isn't there. */
return 0;
if (setjmp(zip->set.env)) {
/* Memory allocation failure. */
set_end(&zip->set);
return -2;
}
if (!set_ok(&zip->set)) {
/* This is the first time here with some central directory content. We
// construct this set of names only on demand. Prepare set and block. */
set_start(&zip->set);
block_init(&zip->block, &zip->central_dir);
}
/* Update the set of names from the current central directory contents.
// This reads any new central directory records since the last time we were
// here. */
for (;;) {
char *there = block_central_name(&zip->block, &zip->set);
if (there == NULL) {
if (zip->block.next == NULL)
/* The central directory is invalid. */
return -1;
break;
}
/* Add there to the set. */
if (set_insert(&zip->set, there))
/* There's already a duplicate in the central directory! We'll just
// let this be and carry on. */
set_free(&zip->set, there);
}
/* Return true if name is in the central directory. */
size_t len = strlen(name);
char *copy = set_alloc(&zip->set, NULL, len + 1);
strcpy(copy, name);
int found = set_found(&zip->set, copy);
set_free(&zip->set, copy);
return found;
}
/****************************************************************************/
@@ -551,7 +792,7 @@ local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib
for (i=(int)uReadSize-3; (i--)>0;)
{
// Signature "0x07064b50" Zip64 end of central directory locater
/* Signature "0x07064b50" Zip64 end of central directory locator */
if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
{
uPosFound = uReadPos+(unsigned)i;
@@ -599,7 +840,7 @@ local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib
if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
return 0;
if (uL != 0x06064b50) // signature of 'Zip64 end of central directory'
if (uL != 0x06064b50) /* signature of 'Zip64 end of central directory' */
return 0;
return relativeOffset;
@@ -628,7 +869,7 @@ local int LoadCentralDirectoryRecord(zip64_internal* pziinit) {
int hasZIP64Record = 0;
// check first if we find a ZIP64 record
/* check first if we find a ZIP64 record */
central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream);
if(central_pos > 0)
{
@@ -694,13 +935,13 @@ local int LoadCentralDirectoryRecord(zip64_internal* pziinit) {
if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK)
err=ZIP_ERRNO;
// TODO..
// read the comment from the standard central header.
/* TODO..
// read the comment from the standard central header. */
size_comment = 0;
}
else
{
// Read End of central Directory info
/* Read End of central Directory info */
if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
err=ZIP_ERRNO;
@@ -843,6 +1084,7 @@ extern zipFile ZEXPORT zipOpen3(const void *pathname, int append, zipcharpc* glo
ziinit.number_entry = 0;
ziinit.add_position_when_writing_offset = 0;
init_linkedlist(&(ziinit.central_dir));
memset(&ziinit.set, 0, sizeof(set_t)); /* make sure set appears dormant */
@@ -858,7 +1100,7 @@ extern zipFile ZEXPORT zipOpen3(const void *pathname, int append, zipcharpc* glo
ziinit.globalcomment = NULL;
if (append == APPEND_STATUS_ADDINZIP)
{
// Read and Cache Central Directory Records
/* Read and Cache Central Directory Records */
err = LoadCentralDirectoryRecord(&ziinit);
}
@@ -942,7 +1184,7 @@ local int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt s
if (err==ZIP_OK)
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
// CRC / Compressed size / Uncompressed size will be filled in later and rewritten later
/* CRC / Compressed size / Uncompressed size will be filled in later and rewritten later */
if (err==ZIP_OK)
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
if (err==ZIP_OK)
@@ -986,13 +1228,13 @@ local int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt s
if ((err==ZIP_OK) && (zi->ci.zip64))
{
// write the Zip64 extended info
/* write the Zip64 extended info */
short HeaderID = 1;
short DataSize = 16;
ZPOS64_T CompressedSize = 0;
ZPOS64_T UncompressedSize = 0;
// Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file)
/* Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file) */
zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream);
err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)HeaderID,2);
@@ -1027,7 +1269,6 @@ extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char* filename, c
int err = ZIP_OK;
# ifdef NOCRYPT
(crcForCrypting);
if (password != NULL)
return ZIP_PARAMERROR;
# endif
@@ -1043,14 +1284,14 @@ extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char* filename, c
return ZIP_PARAMERROR;
#endif
// The filename and comment length must fit in 16 bits.
/* The filename and comment length must fit in 16 bits. */
if ((filename!=NULL) && (strlen(filename)>0xffff))
return ZIP_PARAMERROR;
if ((comment!=NULL) && (strlen(comment)>0xffff))
return ZIP_PARAMERROR;
// The extra field length must fit in 16 bits. If the member also requires
/* The extra field length must fit in 16 bits. If the member also requires
// a Zip64 extra block, that will also need to fit within that 16-bit
// length, but that will be checked for later.
// length, but that will be checked for later. */
if ((size_extrafield_local>0xffff) || (size_extrafield_global>0xffff))
return ZIP_PARAMERROR;
@@ -1102,7 +1343,7 @@ extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char* filename, c
zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream);
zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment;
zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data
zi->ci.size_centralExtraFree = 32; /* Extra space we have reserved in case we need to add ZIP64 extra info data */
zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree);
@@ -1197,7 +1438,7 @@ extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char* filename, c
else if(zi->ci.method == Z_BZIP2ED)
{
#ifdef HAVE_BZIP2
// Init BZip stuff here
/* Init BZip stuff here */
zi->ci.bstream.bzalloc = 0;
zi->ci.bstream.bzfree = 0;
zi->ci.bstream.opaque = (voidpf)0;
@@ -1399,7 +1640,7 @@ extern int ZEXPORT zipWriteInFileInZip(zipFile file, const void* buf, unsigned i
if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
{
uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32;
// uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32;
/* uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32; */
err=BZ2_bzCompress(&zi->ci.bstream, BZ_RUN);
zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ;
@@ -1412,7 +1653,7 @@ extern int ZEXPORT zipWriteInFileInZip(zipFile file, const void* buf, unsigned i
else
#endif
{
zi->ci.stream.next_in = (Bytef*)(uintptr_t)buf;
zi->ci.stream.next_in = buf;
zi->ci.stream.avail_in = len;
while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
@@ -1457,7 +1698,7 @@ extern int ZEXPORT zipWriteInFileInZip(zipFile file, const void* buf, unsigned i
zi->ci.pos_in_buffered_data += copy_this;
}
}
}// while(...)
}/* while(...) */
}
return err;
@@ -1563,7 +1804,7 @@ extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_si
compressed_size += zi->ci.crypt_header_size;
# endif
// update Current Item crc and sizes,
/* update Current Item crc and sizes, */
if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff)
{
/*version Made by*/
@@ -1581,7 +1822,7 @@ extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_si
else
zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/
/// set internal file attributes field
/* set internal file attributes field */
if (zi->ci.stream.data_type == Z_ASCII)
zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
@@ -1590,15 +1831,15 @@ extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_si
else
zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/
// Add ZIP64 extra info field for uncompressed size
/* Add ZIP64 extra info field for uncompressed size */
if(uncompressed_size >= 0xffffffff)
datasize += 8;
// Add ZIP64 extra info field for compressed size
/* Add ZIP64 extra info field for compressed size */
if(compressed_size >= 0xffffffff)
datasize += 8;
// Add ZIP64 extra info field for relative offset to local file header of current file
/* Add ZIP64 extra info field for relative offset to local file header of current file */
if(zi->ci.pos_local_header >= 0xffffffff)
datasize += 8;
@@ -1608,16 +1849,16 @@ extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_si
if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree)
{
// we cannot write more data to the buffer that we have room for.
/* we cannot write more data to the buffer that we have room for. */
return ZIP_BADZIPFILE;
}
p = zi->ci.central_header + zi->ci.size_centralheader;
// Add Extra Information Header for 'ZIP64 information'
zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID
/* Add Extra Information Header for 'ZIP64 information' */
zip64local_putValue_inmemory(p, 0x0001, 2); /* HeaderID */
p += 2;
zip64local_putValue_inmemory(p, datasize, 2); // DataSize
zip64local_putValue_inmemory(p, datasize, 2); /* DataSize */
p += 2;
if(uncompressed_size >= 0xffffffff)
@@ -1638,13 +1879,13 @@ extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_si
p += 8;
}
// Update how much extra free space we got in the memory buffer
/* Update how much extra free space we got in the memory buffer
// and increase the centralheader size so the new ZIP64 fields are included
// ( 4 below is the size of HeaderID and DataSize field )
// ( 4 below is the size of HeaderID and DataSize field ) */
zi->ci.size_centralExtraFree -= datasize + 4;
zi->ci.size_centralheader += datasize + 4;
// Update the extra info size field
/* Update the extra info size field */
zi->ci.size_centralExtra += datasize + 4;
zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2);
}
@@ -1656,7 +1897,7 @@ extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_si
if (err==ZIP_OK)
{
// Update the LocalFileHeader with the new values.
/* Update the LocalFileHeader with the new values. */
ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
@@ -1670,7 +1911,7 @@ extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_si
{
if(zi->ci.pos_zip64extrainfo > 0)
{
// Update the size in the ZIP64 extended field.
/* Update the size in the ZIP64 extended field. */
if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0)
err = ZIP_ERRNO;
@@ -1681,7 +1922,7 @@ extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_si
err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8);
}
else
err = ZIP_BADZIPFILE; // Caller passed zip64 = 0, so no room for zip64 info -> fatal
err = ZIP_BADZIPFILE; /* Caller passed zip64 = 0, so no room for zip64 info -> fatal */
}
else
{
@@ -1735,7 +1976,7 @@ local int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4);
if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ?
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); /* why ZPOS64_T of this ? */
if (err==ZIP_OK) /* version made by */
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
@@ -1782,7 +2023,7 @@ local int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centr
{
{
if(zi->number_entry >= 0xFFFF)
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); /* use value in ZIP64 record */
else
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
}
@@ -1791,7 +2032,7 @@ local int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centr
if (err==ZIP_OK) /* total number of entries in the central dir */
{
if(zi->number_entry >= 0xFFFF)
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); /* use value in ZIP64 record */
else
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
}
@@ -1871,6 +2112,8 @@ extern int ZEXPORT zipClose(zipFile file, const char* global_comment) {
}
free_linkedlist(&(zi->central_dir));
set_end(&zi->set); /* set was zeroed, so this is safe */
pos = centraldir_pos_inzip - zi->add_position_when_writing_offset;
if(pos >= 0xffffffff || zi->number_entry >= 0xFFFF)
{
@@ -1919,13 +2162,13 @@ extern int ZEXPORT zipRemoveExtraInfoBlock(char* pData, int* dataLen, short sHea
header = *(short*)p;
dataSize = *(((short*)p)+1);
if( header == sHeader ) // Header found.
if( header == sHeader ) /* Header found. */
{
p += dataSize + 4; // skip it. do not copy to temp buffer
p += dataSize + 4; /* skip it. do not copy to temp buffer */
}
else
{
// Extra Info block should not be removed, So copy it to the temp buffer.
/* Extra Info block should not be removed, So copy it to the temp buffer. */
memcpy(pTmp, p, dataSize + 4);
p += dataSize + 4;
size += dataSize + 4;
@@ -1935,14 +2178,14 @@ extern int ZEXPORT zipRemoveExtraInfoBlock(char* pData, int* dataLen, short sHea
if(size < *dataLen)
{
// clean old extra info block.
/* clean old extra info block. */
memset(pData,0, *dataLen);
// copy the new extra info block over the old
/* copy the new extra info block over the old */
if(size > 0)
memcpy(pData, pNewHeader, size);
// set the new extra info size
/* set the new extra info size */
*dataLen = size;
retVal = ZIP_OK;

View File

@@ -35,7 +35,7 @@
See header of zip.h
*/
*/
#ifndef _zip12_H
#define _zip12_H
@@ -44,7 +44,7 @@
extern "C" {
#endif
//#define HAVE_BZIP2
/* #define HAVE_BZIP2 */
#ifndef _ZLIB_H
#include "zlib.h"
@@ -127,12 +127,12 @@ extern zipFile ZEXPORT zipOpen64(const void *pathname, int append);
If the zipfile cannot be opened, the return value is NULL.
Else, the return value is a zipFile Handle, usable with other function
of this zip package.
*/
*/
/* Note : there is no delete function into a zipfile.
If you want delete file into a zipfile, you must open a zipfile, and create another
Of course, you can use RAW reading and writing to copy the file you did not want delete
*/
*/
extern zipFile ZEXPORT zipOpen2(const char *pathname,
int append,
@@ -186,7 +186,7 @@ extern int ZEXPORT zipOpenNewFileInZip64(zipFile file,
zip64 is set to 1 if a zip64 extended information block should be added to the local file header.
this MUST be '1' if the uncompressed size is >= 0xffffffff.
*/
*/
extern int ZEXPORT zipOpenNewFileInZip2(zipFile file,
@@ -311,12 +311,12 @@ extern int ZEXPORT zipWriteInFileInZip(zipFile file,
unsigned len);
/*
Write data in the zipfile
*/
*/
extern int ZEXPORT zipCloseFileInZip(zipFile file);
/*
Close the current file in the zipfile
*/
*/
extern int ZEXPORT zipCloseFileInZipRaw(zipFile file,
uLong uncompressed_size,
@@ -326,17 +326,23 @@ extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file,
ZPOS64_T uncompressed_size,
uLong crc32);
extern int ZEXPORT zipAlreadyThere(zipFile file,
char const* name);
/*
See if name is already in file's central directory.
*/
/*
Close the current file in the zipfile, for file opened with
parameter raw=1 in zipOpenNewFileInZip2
uncompressed_size and crc32 are value for the uncompressed size
*/
*/
extern int ZEXPORT zipClose(zipFile file,
const char* global_comment);
/*
Close the zipfile
*/
*/
extern int ZEXPORT zipRemoveExtraInfoBlock(char* pData, int* dataLen, short sHeader);
@@ -355,7 +361,7 @@ extern int ZEXPORT zipRemoveExtraInfoBlock(char* pData, int* dataLen, short sHea
Remove ZIP64 Extra information from a Local File Header extra field data
zipRemoveExtraInfoBlock(pLocalHeaderExtraFieldData, &nLocalHeaderExtraFieldDataLen, 0x0001);
*/
*/
#ifdef __cplusplus
}