mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2026-01-07 14:18:12 -06:00
Windows: update libzip to version 1.2.0
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
zip_open.c -- open zip archive by name
|
||||
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
|
||||
Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
@@ -17,7 +17,7 @@
|
||||
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
|
||||
@@ -88,17 +88,17 @@ zip_open_from_source(zip_source_t *src, int _flags, zip_error_t *error)
|
||||
{
|
||||
static zip_int64_t needed_support_read = -1;
|
||||
static zip_int64_t needed_support_write = -1;
|
||||
|
||||
|
||||
unsigned int flags;
|
||||
zip_int64_t supported;
|
||||
exists_t exists;
|
||||
|
||||
|
||||
if (_flags < 0 || src == NULL) {
|
||||
zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||
return NULL;
|
||||
}
|
||||
flags = (unsigned int)_flags;
|
||||
|
||||
|
||||
supported = zip_source_supports(src);
|
||||
if (needed_support_read == -1) {
|
||||
needed_support_read = zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_SEEK, ZIP_SOURCE_TELL, ZIP_SOURCE_STAT, -1);
|
||||
@@ -118,7 +118,7 @@ zip_open_from_source(zip_source_t *src, int _flags, zip_error_t *error)
|
||||
}
|
||||
|
||||
exists = _zip_file_exists(src, error);
|
||||
switch (exists) {
|
||||
switch (exists) {
|
||||
case EXISTS_ERROR:
|
||||
return NULL;
|
||||
|
||||
@@ -157,26 +157,13 @@ zip_open_from_source(zip_source_t *src, int _flags, zip_error_t *error)
|
||||
}
|
||||
}
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_archive_set_tempdir(zip_t *za, const char *tempdir)
|
||||
ZIP_EXTERN void
|
||||
zip_register_progress_callback(zip_t *za, zip_progress_callback_t progress_callback)
|
||||
{
|
||||
char *new_tempdir;
|
||||
|
||||
if (tempdir) {
|
||||
if ((new_tempdir = strdup(tempdir)) == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_MEMORY, errno);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
new_tempdir = NULL;
|
||||
|
||||
free(za->tempdir);
|
||||
za->tempdir = new_tempdir;
|
||||
|
||||
return 0;
|
||||
za->progress_callback = progress_callback;
|
||||
}
|
||||
|
||||
|
||||
zip_t *
|
||||
_zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error)
|
||||
{
|
||||
@@ -209,7 +196,7 @@ _zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error)
|
||||
if ((za=_zip_allocate_new(src, flags, error)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if ((cdir = _zip_find_central_dir(za, len)) == NULL) {
|
||||
_zip_error_copy(error, &za->error);
|
||||
/* keep src so discard does not get rid of it */
|
||||
@@ -233,7 +220,7 @@ _zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error)
|
||||
zip_discard(za);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if (_zip_hash_add(za->names, name, idx, ZIP_FL_UNCHANGED, &za->error) == false) {
|
||||
if (za->error.zip_err != ZIP_ER_EXISTS || (flags & ZIP_CHECKCONS)) {
|
||||
_zip_error_copy(error, &za->error);
|
||||
@@ -244,7 +231,7 @@ _zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
za->ch_flags = za->flags;
|
||||
|
||||
return za;
|
||||
@@ -269,7 +256,7 @@ _zip_set_open_error(int *zep, const zip_error_t *err, int ze)
|
||||
/* _zip_readcdir:
|
||||
tries to find a valid end-of-central-directory at the beginning of
|
||||
buf, and then the corresponding central directory entries.
|
||||
Returns a struct zip_cdir which contains the central directory
|
||||
Returns a struct zip_cdir which contains the central directory
|
||||
entries, or NULL if unsuccessful. */
|
||||
|
||||
static zip_cdir_t *
|
||||
@@ -286,7 +273,7 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
|
||||
zip_error_set(error, ZIP_ER_NOZIP, 0);
|
||||
return 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);
|
||||
@@ -317,10 +304,10 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
|
||||
|
||||
if (comment_len || (za->open_flags & ZIP_CHECKCONS)) {
|
||||
zip_uint64_t tail_len;
|
||||
|
||||
|
||||
_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, 0);
|
||||
_zip_cdir_free(cd);
|
||||
@@ -339,7 +326,7 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
|
||||
zip_uint8_t *data;
|
||||
/* if buffer already read in, use it */
|
||||
_zip_buffer_set_offset(buffer, cd->offset - buf_offset);
|
||||
|
||||
|
||||
if ((data = _zip_buffer_get(buffer, cd->size)) == NULL) {
|
||||
zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
_zip_cdir_free(cd);
|
||||
@@ -353,7 +340,7 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
|
||||
}
|
||||
else {
|
||||
cd_buffer = NULL;
|
||||
|
||||
|
||||
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);
|
||||
@@ -370,9 +357,30 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
|
||||
|
||||
left = (zip_uint64_t)cd->size;
|
||||
i=0;
|
||||
while (i<cd->nentry && left > 0) {
|
||||
while (left > 0) {
|
||||
bool grown = false;
|
||||
zip_int64_t entry_size;
|
||||
|
||||
if (i == cd->nentry) {
|
||||
/* InfoZIP has a hack to avoid using Zip64: it stores nentries % 0x10000 */
|
||||
/* This hack isn't applicable if we're using Zip64, or if there is no central directory entry following. */
|
||||
|
||||
if (cd->is_zip64 || left < CDENTRYSIZE) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!_zip_cdir_grow(cd, 0x10000, error)) {
|
||||
_zip_cdir_free(cd);
|
||||
_zip_buffer_free(cd_buffer);
|
||||
return NULL;
|
||||
}
|
||||
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 (grown && zip_error_code_zip(error) == ZIP_ER_NOZIP) {
|
||||
zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
}
|
||||
_zip_cdir_free(cd);
|
||||
_zip_buffer_free(cd_buffer);
|
||||
return NULL;
|
||||
@@ -380,23 +388,23 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
|
||||
i++;
|
||||
left -= (zip_uint64_t)entry_size;
|
||||
}
|
||||
|
||||
if (i != cd->nentry) {
|
||||
|
||||
if (i != cd->nentry || left > 0) {
|
||||
zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
_zip_buffer_free(cd_buffer);
|
||||
_zip_cdir_free(cd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if (za->open_flags & ZIP_CHECKCONS) {
|
||||
bool ok;
|
||||
|
||||
|
||||
if (cd_buffer) {
|
||||
ok = _zip_buffer_eof(cd_buffer);
|
||||
}
|
||||
else {
|
||||
zip_int64_t offset = zip_source_tell(za->src);
|
||||
|
||||
|
||||
if (offset < 0) {
|
||||
_zip_error_set_from_source(error, za->src);
|
||||
_zip_buffer_free(cd_buffer);
|
||||
@@ -405,7 +413,7 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
|
||||
}
|
||||
ok = ((zip_uint64_t)offset == cd->offset + cd->size);
|
||||
}
|
||||
|
||||
|
||||
if (!ok) {
|
||||
zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
_zip_buffer_free(cd_buffer);
|
||||
@@ -447,7 +455,7 @@ _zip_checkcons(zip_t *za, zip_cdir_t *cd, zip_error_t *error)
|
||||
zip_error_set(error, ZIP_ER_NOZIP, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
j = cd->entry[i].orig->offset + cd->entry[i].orig->comp_size
|
||||
+ _zip_string_length(cd->entry[i].orig->filename) + LENTRYSIZE;
|
||||
if (j > max)
|
||||
@@ -456,27 +464,27 @@ _zip_checkcons(zip_t *za, zip_cdir_t *cd, zip_error_t *error)
|
||||
zip_error_set(error, ZIP_ER_NOZIP, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (zip_source_seek(za->src, (zip_int64_t)cd->entry[i].orig->offset, SEEK_SET) < 0) {
|
||||
_zip_error_set_from_source(error, za->src);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (_zip_dirent_read(&temp, za->src, NULL, true, error) == -1) {
|
||||
_zip_dirent_finalize(&temp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (_zip_headercomp(cd->entry[i].orig, &temp) != 0) {
|
||||
zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
_zip_dirent_finalize(&temp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
cd->entry[i].orig->extra_fields = _zip_ef_merge(cd->entry[i].orig->extra_fields, temp.extra_fields);
|
||||
cd->entry[i].orig->local_extra_fields_read = 1;
|
||||
temp.extra_fields = NULL;
|
||||
|
||||
|
||||
_zip_dirent_finalize(&temp);
|
||||
}
|
||||
|
||||
@@ -491,7 +499,7 @@ _zip_checkcons(zip_t *za, zip_cdir_t *cd, zip_error_t *error)
|
||||
static int
|
||||
_zip_headercomp(const zip_dirent_t *central, const zip_dirent_t *local)
|
||||
{
|
||||
if ((central->version_needed != local->version_needed)
|
||||
if ((central->version_needed < local->version_needed)
|
||||
#if 0
|
||||
/* some zip-files have different values in local
|
||||
and global headers for the bitflags */
|
||||
@@ -586,7 +594,7 @@ _zip_find_central_dir(zip_t *za, zip_uint64_t len)
|
||||
_zip_error_set_from_source(&za->error, za->src);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if ((buffer = _zip_buffer_new_from_source(za->src, buflen, NULL, &za->error)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -607,7 +615,7 @@ _zip_find_central_dir(zip_t *za, zip_uint64_t len)
|
||||
if (best <= 0) {
|
||||
best = _zip_checkcons(za, cdir, &error);
|
||||
}
|
||||
|
||||
|
||||
a = _zip_checkcons(za, cdirnew, &error);
|
||||
if (best < a) {
|
||||
_zip_cdir_free(cdir);
|
||||
@@ -628,13 +636,13 @@ _zip_find_central_dir(zip_t *za, zip_uint64_t len)
|
||||
}
|
||||
cdirnew = NULL;
|
||||
}
|
||||
|
||||
|
||||
match++;
|
||||
_zip_buffer_set_offset(buffer, (zip_uint64_t)(match - _zip_buffer_data(buffer)));
|
||||
}
|
||||
|
||||
_zip_buffer_free(buffer);
|
||||
|
||||
|
||||
if (best < 0) {
|
||||
_zip_error_copy(&za->error, &error);
|
||||
_zip_cdir_free(cdir);
|
||||
@@ -649,7 +657,7 @@ static unsigned char *
|
||||
_zip_memmem(const unsigned char *big, size_t biglen, const unsigned char *little, size_t littlelen)
|
||||
{
|
||||
const unsigned char *p;
|
||||
|
||||
|
||||
if ((biglen < littlelen) || (littlelen == 0))
|
||||
return NULL;
|
||||
p = big-1;
|
||||
@@ -673,7 +681,7 @@ _zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags
|
||||
zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
eocd_offset = _zip_buffer_offset(buffer);
|
||||
|
||||
_zip_buffer_get(buffer, 4); /* magic already verified */
|
||||
@@ -700,7 +708,7 @@ _zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags
|
||||
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, 0);
|
||||
@@ -715,9 +723,10 @@ _zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags
|
||||
if ((cd=_zip_cdir_new(nentry, error)) == NULL)
|
||||
return NULL;
|
||||
|
||||
cd->is_zip64 = false;
|
||||
cd->size = size;
|
||||
cd->offset = offset;
|
||||
|
||||
|
||||
return cd;
|
||||
}
|
||||
|
||||
@@ -734,13 +743,13 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse
|
||||
zip_uint32_t num_disks, num_disks64, eocd_disk, eocd_disk64;
|
||||
|
||||
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_offset = _zip_buffer_get_64(buffer);
|
||||
|
||||
|
||||
if (eocd_offset > ZIP_INT64_MAX || eocd_offset + EOCD64LEN < eocd_offset) {
|
||||
zip_error_set(error, ZIP_ER_SEEK, EFBIG);
|
||||
return NULL;
|
||||
@@ -773,7 +782,7 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
size = _zip_buffer_get_64(buffer);
|
||||
|
||||
if ((flags & ZIP_CHECKCONS) && size + eocd_offset + 12 != buf_offset + eocdloc_offset) {
|
||||
@@ -820,7 +829,7 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse
|
||||
|
||||
size = _zip_buffer_get_64(buffer);
|
||||
offset = _zip_buffer_get_64(buffer);
|
||||
|
||||
|
||||
if (!_zip_buffer_ok(buffer)) {
|
||||
zip_error_set(error, ZIP_ER_INTERNAL, 0);
|
||||
if (free_buffer) {
|
||||
@@ -845,7 +854,7 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse
|
||||
if ((cd=_zip_cdir_new(nentry, error)) == NULL)
|
||||
return NULL;
|
||||
|
||||
|
||||
cd->is_zip64 = true;
|
||||
cd->size = size;
|
||||
cd->offset = offset;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user