Windows: update libzip to version 1.2.0

This commit is contained in:
Mounir IDRASSI 2017-04-26 00:10:55 +02:00
parent 9270952b3d
commit d081d6143e
No known key found for this signature in database
GPG Key ID: DD0C382D5FCFB8FC
44 changed files with 795 additions and 319 deletions

View File

@ -29,3 +29,38 @@ 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.
For AES encryption support, files under the following license are used:
---------------------------------------------------------------------------
Copyright (c) 2002, Dr Brian Gladman < >, Worcester, UK.
All rights reserved.
LICENSE TERMS
The free distribution and use of this software in both source and binary
form is allowed (with or without changes) provided that:
1. distributions of this source code include the above copyright
notice, this list of conditions and the following disclaimer;
2. distributions in binary form include the above copyright
notice, this list of conditions and the following disclaimer
in the documentation and/or other associated materials;
3. the copyright holder's name is not used to endorse products
built using this software without specific written permission.
ALTERNATIVELY, provided that this notice is retained in full, this product
may be distributed under the terms of the GNU General Public License (GPL),
in which case the provisions of the GPL apply INSTEAD OF those given above.
DISCLAIMER
This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.
---------------------------------------------------------------------------
Issue Date: 18th November 2008

View File

@ -1,3 +1,14 @@
1.2.0 [2017-02-19]
==================
* Support for AES encryption (Winzip version), both encryption
and decryption.
* Support legacy zip files with >64k entries.
* Fix seeking in zip_source_file if start > 0.
* Add zip_fseek() for seeking in uncompressed data.
* Add zip_ftell() for telling position in uncompressed data.
* Add zip_register_progress_callback() for UI updates during zip_close()
1.1.3 [2016-05-28]
==================

View File

@ -105,6 +105,12 @@ typedef char bool;
#if !defined(HAVE__SETMODE) && defined(HAVE_SETMODE)
#define _setmode setmode
#endif
#if !defined(HAVE_STRTOLL) && defined(HAVE__STRTOI64)
#define strtoll _strtoi64
#endif
#if !defined(HAVE_STRTOULL) && defined(HAVE__STRTOUI64)
#define strtoull _strtoui64
#endif
#endif
#ifndef HAVE_FSEEKO

View File

@ -14,6 +14,8 @@
#define HAVE__SNPRINTF
#define HAVE__STRDUP
#define HAVE__STRICMP
#define HAVE__STRTOI64
#define HAVE__STRTOUI64
#define HAVE_FILENO
/* #undef HAVE_FSEEKO */
/* #undef HAVE_FTELLO */
@ -26,6 +28,8 @@
/* #undef HAVE_STRCASECMP */
#define HAVE_STRDUP
#define HAVE_STRICMP
/* #undef HAVE_STRTOLL */
/* #undef HAVE_STRTOULL */
/* #undef HAVE_STRUCT_TM_TM_ZONE */
/* #undef HAVE_STDBOOL_H */
/* #undef HAVE_STRINGS_H */
@ -53,9 +57,10 @@
/* #undef HAVE_NDIR_H */
/* #undef HAVE_SYS_DIR_H */
/* #undef HAVE_SYS_NDIR_H */
/* #undef WORDS_BIGENDIAN */
/* END DEFINES */
#define PACKAGE "libzip"
#define VERSION "1.1.3"
#define VERSION "1.2.0"
#ifndef HAVE_SSIZE_T_LIBZIP
# if SIZE_T_LIBZIP == INT_LIBZIP

View File

@ -3,7 +3,7 @@
/*
zip.h -- exported declarations.
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>
@ -20,7 +20,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
@ -127,7 +127,7 @@ extern "C" {
#define ZIP_ER_REMOVE 22 /* S Can't remove file */
#define ZIP_ER_DELETED 23 /* N Entry has been deleted */
#define ZIP_ER_ENCRNOTSUPP 24 /* N Encryption method not supported */
#define ZIP_ER_RDONLY 25 /* N Read-only archive */
#define ZIP_ER_RDONLY 25 /* N Read-only archive */
#define ZIP_ER_NOPASSWD 26 /* N No password provided */
#define ZIP_ER_WRONGPASSWD 27 /* N Wrong password provided */
#define ZIP_ER_OPNOTSUPP 28 /* N Operation not supported */
@ -161,6 +161,8 @@ extern "C" {
/* 15-17 - Reserved by PKWARE */
#define ZIP_CM_TERSE 18 /* compressed using IBM TERSE (new) */
#define ZIP_CM_LZ77 19 /* IBM LZ77 z Architecture (PFS) */
#define ZIP_CM_XZ 95 /* XZ compressed data */
#define ZIP_CM_JPEG 96 /* Compressed Jpeg data */
#define ZIP_CM_WAVPACK 97 /* WavPack compressed data */
#define ZIP_CM_PPMD 98 /* PPMd version I, Rev 1 */
@ -173,12 +175,15 @@ extern "C" {
#define ZIP_EM_RC2_OLD 0x6602 /* strong encryption: RC2, version < 5.2 */
#define ZIP_EM_3DES_168 0x6603
#define ZIP_EM_3DES_112 0x6609
#define ZIP_EM_AES_128 0x660e
#define ZIP_EM_AES_192 0x660f
#define ZIP_EM_AES_256 0x6610
#define ZIP_EM_PKZIP_AES_128 0x660e
#define ZIP_EM_PKZIP_AES_192 0x660f
#define ZIP_EM_PKZIP_AES_256 0x6610
#define ZIP_EM_RC2 0x6702 /* strong encryption: RC2, version >= 5.2 */
#define ZIP_EM_RC4 0x6801
#endif
#define ZIP_EM_AES_128 0x0101 /* Winzip AES encryption */
#define ZIP_EM_AES_192 0x0102
#define ZIP_EM_AES_256 0x0103
#define ZIP_EM_UNKNOWN 0xffff /* unknown algorithm */
#define ZIP_OPSYS_DOS 0x00u
@ -299,9 +304,10 @@ typedef struct zip_file zip_file_t;
typedef struct zip_source zip_source_t;
typedef struct zip_stat zip_stat_t;
typedef zip_uint32_t zip_flags_t;
typedef zip_uint32_t zip_flags_t;
typedef zip_int64_t (*zip_source_callback)(void *, void *, zip_uint64_t, zip_source_cmd_t);
typedef void (*zip_progress_callback_t)(double);
#ifndef ZIP_DISABLE_DEPRECATED
@ -318,7 +324,6 @@ ZIP_EXTERN int zip_error_to_str(char *, zip_uint64_t, int, int);
ZIP_EXTERN void zip_file_error_get(zip_file_t *, int *, int *); /* use zip_file_get_error, zip_error_code_zip / zip_error_code_system */
#endif
ZIP_EXTERN int zip_archive_set_tempdir(zip_t *, const char *);
ZIP_EXTERN int zip_close(zip_t *);
ZIP_EXTERN int zip_delete(zip_t *, zip_uint64_t);
ZIP_EXTERN zip_int64_t zip_dir_add(zip_t *, const char *, zip_flags_t);
@ -353,6 +358,7 @@ ZIP_EXTERN int zip_file_get_external_attributes(zip_t *, zip_uint64_t, zip_flags
ZIP_EXTERN int zip_file_rename(zip_t *, zip_uint64_t, const char *, zip_flags_t);
ZIP_EXTERN int zip_file_replace(zip_t *, zip_uint64_t, zip_source_t *, zip_flags_t);
ZIP_EXTERN int zip_file_set_comment(zip_t *, zip_uint64_t, const char *, zip_uint16_t, zip_flags_t);
ZIP_EXTERN int zip_file_set_encryption(zip_t *, zip_uint64_t, zip_uint16_t, const char *);
ZIP_EXTERN int zip_file_set_external_attributes(zip_t *, zip_uint64_t, zip_flags_t, zip_uint8_t, zip_uint32_t);
ZIP_EXTERN int zip_file_set_mtime(zip_t *, zip_uint64_t, time_t, zip_flags_t);
ZIP_EXTERN const char *zip_file_strerror(zip_file_t *);
@ -361,6 +367,8 @@ ZIP_EXTERN zip_file_t *zip_fopen_encrypted(zip_t *, const char *, zip_flags_t, c
ZIP_EXTERN zip_file_t *zip_fopen_index(zip_t *, zip_uint64_t, zip_flags_t);
ZIP_EXTERN zip_file_t *zip_fopen_index_encrypted(zip_t *, zip_uint64_t, zip_flags_t, const char *);
ZIP_EXTERN zip_int64_t zip_fread(zip_file_t *, void *, zip_uint64_t);
ZIP_EXTERN zip_int8_t zip_fseek(zip_file_t *, zip_int64_t, int);
ZIP_EXTERN zip_int64_t zip_ftell(zip_file_t *);
ZIP_EXTERN const char *zip_get_archive_comment(zip_t *, int *, zip_flags_t);
ZIP_EXTERN int zip_get_archive_flag(zip_t *, zip_flags_t, zip_flags_t);
ZIP_EXTERN const char *zip_get_name(zip_t *, zip_uint64_t, zip_flags_t);
@ -368,6 +376,7 @@ ZIP_EXTERN zip_int64_t zip_get_num_entries(zip_t *, zip_flags_t);
ZIP_EXTERN zip_int64_t zip_name_locate(zip_t *, const char *, zip_flags_t);
ZIP_EXTERN zip_t *zip_open(const char *, int, int *);
ZIP_EXTERN zip_t *zip_open_from_source(zip_source_t *, int, zip_error_t *);
ZIP_EXTERN void zip_register_progress_callback(zip_t *, zip_progress_callback_t);
ZIP_EXTERN int zip_set_archive_comment(zip_t *, const char *, zip_uint16_t);
ZIP_EXTERN int zip_set_archive_flag(zip_t *, zip_flags_t, int);
ZIP_EXTERN int zip_set_default_password(zip_t *, const char *);
@ -377,7 +386,7 @@ ZIP_EXTERN zip_source_t *zip_source_buffer(zip_t *, const void *, zip_uint64_t,
ZIP_EXTERN zip_source_t *zip_source_buffer_create(const void *, zip_uint64_t, int, zip_error_t *);
ZIP_EXTERN int zip_source_close(zip_source_t *);
ZIP_EXTERN int zip_source_commit_write(zip_source_t *);
ZIP_EXTERN zip_error_t *zip_source_error(zip_source_t *src);
ZIP_EXTERN zip_error_t *zip_source_error(zip_source_t *);
ZIP_EXTERN zip_source_t *zip_source_file(zip_t *, const char *, zip_uint64_t, zip_int64_t);
ZIP_EXTERN zip_source_t *zip_source_file_create(const char *, zip_uint64_t, zip_int64_t, zip_error_t *);
ZIP_EXTERN zip_source_t *zip_source_filep(zip_t *, FILE *, zip_uint64_t, zip_int64_t);

View File

@ -1,6 +1,6 @@
/*
zip_add_entry.c -- create and init struct zip_entry
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>

View File

@ -1,10 +1,10 @@
/*
zip_buffer.c -- bounds checked access to memory buffer
Copyright (C) 2014 Dieter Baron and Thomas Klausner
Copyright (C) 2014-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>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
@ -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
@ -49,11 +49,11 @@ _zip_buffer_free(zip_buffer_t *buffer)
if (buffer == NULL) {
return;
}
if (buffer->free_data) {
free(buffer->data);
}
free(buffer);
}
@ -69,14 +69,13 @@ zip_uint8_t *
_zip_buffer_get(zip_buffer_t *buffer, zip_uint64_t length)
{
zip_uint8_t *data;
if (!buffer->ok || buffer->offset + length < length || buffer->offset + length > buffer->size) {
buffer->ok = false;
return NULL;
data = _zip_buffer_peek(buffer, length);
if (data != NULL) {
buffer->offset += length;
}
data = buffer->data + buffer->offset;
buffer->offset += length;
return data;
}
@ -85,11 +84,11 @@ zip_uint16_t
_zip_buffer_get_16(zip_buffer_t *buffer)
{
zip_uint8_t *data = _zip_buffer_get(buffer, 2);
if (data == NULL) {
return 0;
}
return (zip_uint16_t)(data[0] + (data[1] << 8));
}
@ -98,11 +97,11 @@ zip_uint32_t
_zip_buffer_get_32(zip_buffer_t *buffer)
{
zip_uint8_t *data = _zip_buffer_get(buffer, 4);
if (data == NULL) {
return 0;
}
return ((((((zip_uint32_t)data[3] << 8) + data[2]) << 8) + data[1]) << 8) + data[0];
}
@ -111,7 +110,7 @@ zip_uint64_t
_zip_buffer_get_64(zip_buffer_t *buffer)
{
zip_uint8_t *data = _zip_buffer_get(buffer, 8);
if (data == NULL) {
return 0;
}
@ -125,11 +124,11 @@ zip_uint8_t
_zip_buffer_get_8(zip_buffer_t *buffer)
{
zip_uint8_t *data = _zip_buffer_get(buffer, 1);
if (data == NULL) {
return 0;
}
return data[0];
}
@ -141,12 +140,25 @@ _zip_buffer_left(zip_buffer_t *buffer)
}
zip_uint64_t
_zip_buffer_read(zip_buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length)
{
if (_zip_buffer_left(buffer) < length) {
length = _zip_buffer_left(buffer);
}
memcpy(data, _zip_buffer_get(buffer, length), length);
return length;
}
zip_buffer_t *
_zip_buffer_new(zip_uint8_t *data, zip_uint64_t size)
{
bool free_data = (data == NULL);
zip_buffer_t *buffer;
if (data == NULL) {
if ((data = (zip_uint8_t *)malloc(size)) == NULL) {
return NULL;
@ -159,13 +171,13 @@ _zip_buffer_new(zip_uint8_t *data, zip_uint64_t size)
}
return NULL;
}
buffer->ok = true;
buffer->data = data;
buffer->size = size;
buffer->offset = 0;
buffer->free_data = free_data;
return buffer;
}
@ -174,17 +186,17 @@ zip_buffer_t *
_zip_buffer_new_from_source(zip_source_t *src, zip_uint64_t size, zip_uint8_t *buf, zip_error_t *error)
{
zip_buffer_t *buffer;
if ((buffer = _zip_buffer_new(buf, size)) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
if (_zip_read(src, buffer->data, size, error) < 0) {
_zip_buffer_free(buffer);
return NULL;
}
return buffer;
}
@ -203,15 +215,30 @@ _zip_buffer_ok(zip_buffer_t *buffer)
}
zip_uint8_t *
_zip_buffer_peek(zip_buffer_t *buffer, zip_uint64_t length)
{
zip_uint8_t *data;
if (!buffer->ok || buffer->offset + length < length || buffer->offset + length > buffer->size) {
buffer->ok = false;
return NULL;
}
data = buffer->data + buffer->offset;
return data;
}
int
_zip_buffer_put(zip_buffer_t *buffer, const void *src, size_t length)
{
zip_uint8_t *dst = _zip_buffer_get(buffer, length);
if (dst == NULL) {
return -1;
}
memcpy(dst, src, length);
return 0;
}
@ -221,14 +248,14 @@ int
_zip_buffer_put_16(zip_buffer_t *buffer, zip_uint16_t i)
{
zip_uint8_t *data = _zip_buffer_get(buffer, 2);
if (data == NULL) {
return -1;
}
data[0] = (zip_uint8_t)(i & 0xff);
data[1] = (zip_uint8_t)((i >> 8) & 0xff);
return 0;
}
@ -237,16 +264,16 @@ int
_zip_buffer_put_32(zip_buffer_t *buffer, zip_uint32_t i)
{
zip_uint8_t *data = _zip_buffer_get(buffer, 4);
if (data == NULL) {
return -1;
}
data[0] = (zip_uint8_t)(i & 0xff);
data[1] = (zip_uint8_t)((i >> 8) & 0xff);
data[2] = (zip_uint8_t)((i >> 16) & 0xff);
data[3] = (zip_uint8_t)((i >> 24) & 0xff);
return 0;
}
@ -255,11 +282,11 @@ int
_zip_buffer_put_64(zip_buffer_t *buffer, zip_uint64_t i)
{
zip_uint8_t *data = _zip_buffer_get(buffer, 8);
if (data == NULL) {
return -1;
}
data[0] = (zip_uint8_t)(i & 0xff);
data[1] = (zip_uint8_t)((i >> 8) & 0xff);
data[2] = (zip_uint8_t)((i >> 16) & 0xff);
@ -268,7 +295,7 @@ _zip_buffer_put_64(zip_buffer_t *buffer, zip_uint64_t i)
data[5] = (zip_uint8_t)((i >> 40) & 0xff);
data[6] = (zip_uint8_t)((i >> 48) & 0xff);
data[7] = (zip_uint8_t)((i >> 56) & 0xff);
return 0;
}
@ -277,13 +304,13 @@ int
_zip_buffer_put_8(zip_buffer_t *buffer, zip_uint8_t i)
{
zip_uint8_t *data = _zip_buffer_get(buffer, 1);
if (data == NULL) {
return -1;
}
data[0] = i;
return 0;
}
@ -295,10 +322,10 @@ _zip_buffer_set_offset(zip_buffer_t *buffer, zip_uint64_t offset)
buffer->ok = false;
return -1;
}
buffer->ok = true;
buffer->offset = offset;
return 0;
}
@ -306,7 +333,7 @@ _zip_buffer_set_offset(zip_buffer_t *buffer, zip_uint64_t offset)
int
_zip_buffer_skip(zip_buffer_t *buffer, zip_uint64_t length) {
zip_uint64_t offset = buffer->offset + length;
if (offset < buffer->offset) {
buffer->ok = false;
return -1;

View File

@ -1,6 +1,6 @@
/*
zip_close.c -- close zip archive and update changes
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>
@ -131,10 +131,14 @@ zip_close(zip_t *za)
zip_entry_t *entry;
zip_dirent_t *de;
if (za->progress_callback) {
za->progress_callback((double)j/survivors);
}
i = filelist[j].idx;
entry = za->entry+i;
new_data = (ZIP_ENTRY_DATA_CHANGED(entry) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_COMP_METHOD));
new_data = (ZIP_ENTRY_DATA_CHANGED(entry) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_COMP_METHOD) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_ENCRYPTION_METHOD));
/* create new local directory entry */
if (entry->changes == NULL) {
@ -222,6 +226,10 @@ zip_close(zip_t *za)
return -1;
}
if (za->progress_callback) {
za->progress_callback(1);
}
zip_discard(za);
return 0;
@ -233,10 +241,11 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de)
{
zip_int64_t offstart, offdata, offend;
struct zip_stat st;
zip_source_t *s2;
zip_source_t *src_final, *src_tmp;
int ret;
int is_zip64;
zip_flags_t flags;
bool needs_recompress, needs_decompress, needs_crc, needs_compress, needs_reencrypt, needs_decrypt, needs_encrypt;
if (zip_source_stat(src, &st) < 0) {
_zip_error_set_from_source(&za->error, src);
@ -259,6 +268,10 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de)
st.valid &= ~ZIP_STAT_COMP_SIZE;
}
if ((st.valid & ZIP_STAT_ENCRYPTION_METHOD) == 0) {
st.valid |= ZIP_STAT_ENCRYPTION_METHOD;
st.encryption_method = ZIP_EM_NONE;
}
flags = ZIP_EF_LOCAL;
@ -285,67 +298,123 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de)
if ((is_zip64=_zip_dirent_write(za, de, flags)) < 0)
return -1;
needs_recompress = !((st.comp_method == de->comp_method) || (ZIP_CM_IS_DEFAULT(de->comp_method) && st.comp_method == ZIP_CM_DEFLATE));
needs_decompress = needs_recompress && (st.comp_method != ZIP_CM_STORE);
needs_crc = (st.comp_method == ZIP_CM_STORE) || needs_decompress;
needs_compress = needs_recompress && (de->comp_method != ZIP_CM_STORE);
if (st.comp_method == ZIP_CM_STORE || (ZIP_CM_IS_DEFAULT(de->comp_method) && st.comp_method != de->comp_method)) {
zip_source_t *s_store, *s_crc;
zip_compression_implementation comp_impl;
needs_reencrypt = needs_recompress || (de->changed & ZIP_DIRENT_PASSWORD) || (de->encryption_method != st.encryption_method);
needs_decrypt = needs_reencrypt && (st.encryption_method != ZIP_EM_NONE);
needs_encrypt = needs_reencrypt && (de->encryption_method != ZIP_EM_NONE);
src_final = src;
zip_source_keep(src_final);
if (needs_decrypt) {
zip_encryption_implementation impl;
if (st.comp_method != ZIP_CM_STORE) {
if ((comp_impl=_zip_get_compression_implementation(st.comp_method)) == NULL) {
zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
return -1;
}
if ((s_store=comp_impl(za, src, st.comp_method, ZIP_CODEC_DECODE)) == NULL) {
/* error set by comp_impl */
return -1;
}
if ((impl = _zip_get_encryption_implementation(st.encryption_method, ZIP_CODEC_DECODE)) == NULL) {
zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
zip_source_free(src_final);
return -1;
}
else {
/* to have the same reference count to src as in the case where it's not stored */
zip_source_keep(src);
s_store = src;
}
s_crc = zip_source_crc(za, s_store, 0);
zip_source_free(s_store);
if (s_crc == NULL) {
if ((src_tmp = impl(za, src_final, st.encryption_method, ZIP_CODEC_DECODE, za->default_password)) == NULL) {
/* error set by impl */
zip_source_free(src_final);
return -1;
}
if (de->comp_method != ZIP_CM_STORE && ((st.valid & ZIP_STAT_SIZE) == 0 || st.size != 0)) {
if ((comp_impl=_zip_get_compression_implementation(de->comp_method)) == NULL) {
zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
zip_source_free(s_crc);
return -1;
}
s2 = comp_impl(za, s_crc, de->comp_method, ZIP_CODEC_ENCODE);
zip_source_free(s_crc);
if (s2 == NULL) {
return -1;
}
}
else {
s2 = s_crc;
}
zip_source_free(src_final);
src_final = src_tmp;
}
else {
zip_source_keep(src);
s2 = src;
if (needs_decompress) {
zip_compression_implementation comp_impl;
if ((comp_impl = _zip_get_compression_implementation(st.comp_method, ZIP_CODEC_DECODE)) == NULL) {
zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
zip_source_free(src_final);
return -1;
}
if ((src_tmp = comp_impl(za, src_final, st.comp_method, ZIP_CODEC_DECODE)) == NULL) {
/* error set by comp_impl */
zip_source_free(src_final);
return -1;
}
zip_source_free(src_final);
src_final = src_tmp;
}
if (needs_crc) {
if ((src_tmp = zip_source_crc(za, src_final, 0)) == NULL) {
zip_source_free(src_final);
return -1;
}
zip_source_free(src_final);
src_final = src_tmp;
}
if (needs_compress) {
zip_compression_implementation comp_impl;
if ((comp_impl = _zip_get_compression_implementation(de->comp_method, ZIP_CODEC_ENCODE)) == NULL) {
zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
zip_source_free(src_final);
return -1;
}
if ((src_tmp = comp_impl(za, src_final, de->comp_method, ZIP_CODEC_ENCODE)) == NULL) {
zip_source_free(src_final);
return -1;
}
zip_source_free(src_final);
src_final = src_tmp;
}
if (needs_encrypt) {
zip_encryption_implementation impl;
const char *password = NULL;
if (de->password) {
password = de->password;
} else if (za->default_password) {
password = za->default_password;
}
if ((impl = _zip_get_encryption_implementation(de->encryption_method, ZIP_CODEC_ENCODE)) == NULL) {
zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
zip_source_free(src_final);
return -1;
}
if ((src_tmp = impl(za, src_final, de->encryption_method, ZIP_CODEC_ENCODE, password)) == NULL) {
/* error set by impl */
zip_source_free(src_final);
return -1;
}
zip_source_free(src_final);
src_final = src_tmp;
}
if ((offdata = zip_source_tell_write(za->src)) < 0) {
return -1;
}
ret = copy_source(za, s2);
ret = copy_source(za, src_final);
if (zip_source_stat(s2, &st) < 0)
if (zip_source_stat(src_final, &st) < 0) {
ret = -1;
}
zip_source_free(s2);
zip_source_free(src_final);
if (ret < 0)
if (ret < 0) {
return -1;
}
if ((offend = zip_source_tell_write(za->src)) < 0) {
return -1;

View File

@ -1,6 +1,6 @@
/*
zip_delete.c -- delete file from zip archive
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>

View File

@ -44,6 +44,7 @@
static time_t _zip_d2u_time(zip_uint16_t, zip_uint16_t);
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_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);
void
@ -66,32 +67,61 @@ zip_cdir_t *
_zip_cdir_new(zip_uint64_t nentry, zip_error_t *error)
{
zip_cdir_t *cd;
zip_uint64_t i;
if ((cd=(zip_cdir_t *)malloc(sizeof(*cd))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
if (nentry == 0)
cd->entry = NULL;
else if ((nentry > SIZE_MAX/sizeof(*(cd->entry))) || (cd->entry=(zip_entry_t *)malloc(sizeof(*(cd->entry))*(size_t)nentry)) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
free(cd);
cd->entry = NULL;
cd->nentry = cd->nentry_alloc = 0;
cd->size = cd->offset = 0;
cd->comment = NULL;
cd->is_zip64 = false;
if (!_zip_cdir_grow(cd, nentry, error)) {
_zip_cdir_free(cd);
return NULL;
}
for (i=0; i<nentry; i++)
_zip_entry_init(cd->entry+i);
cd->nentry = cd->nentry_alloc = nentry;
cd->size = cd->offset = 0;
cd->comment = 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;
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);
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++) {
_zip_entry_init(cd->entry+i);
}
cd->nentry = cd->nentry_alloc = new_alloc;
return true;
}
zip_int64_t
_zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors)
{
@ -222,6 +252,13 @@ _zip_dirent_finalize(zip_dirent_t *zde)
_zip_string_free(zde->comment);
zde->comment = NULL;
}
if (!zde->cloned || zde->changed & ZIP_DIRENT_PASSWORD) {
if (zde->password) {
_zip_crypto_clear(zde->password, strlen(zde->password));
}
free(zde->password);
zde->password = NULL;
}
}
@ -243,6 +280,7 @@ _zip_dirent_init(zip_dirent_t *de)
de->local_extra_fields_read = 0;
de->cloned = 0;
de->crc_valid = true;
de->version_madeby = 20 | (ZIP_OPSYS_DEFAULT << 8);
de->version_needed = 20; /* 2.0 */
de->bitflags = 0;
@ -258,6 +296,8 @@ _zip_dirent_init(zip_dirent_t *de)
de->int_attrib = 0;
de->ext_attrib = ZIP_EXT_ATTRIB_DEFAULT;
de->offset = 0;
de->encryption_method = ZIP_EM_NONE;
de->password = NULL;
}
@ -372,6 +412,19 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
return -1;
}
if (zde->bitflags & ZIP_GPBF_ENCRYPTED) {
if (zde->bitflags & ZIP_GPBF_STRONG_ENCRYPTION) {
/* TODO */
zde->encryption_method = ZIP_EM_UNKNOWN;
}
else {
zde->encryption_method = ZIP_EM_TRAD_PKWARE;
}
}
else {
zde->encryption_method = ZIP_EM_NONE;
}
zde->filename = NULL;
zde->extra_fields = NULL;
zde->comment = NULL;
@ -524,6 +577,13 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
return -1;
}
if (!_zip_dirent_process_winzip_aes(zde, error)) {
if (!from_buffer) {
_zip_buffer_free(buffer);
}
return -1;
}
zde->extra_fields = _zip_ef_remove_internal(zde->extra_fields);
return (zip_int64_t)(size + variable_size);
@ -566,6 +626,90 @@ _zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string
}
static bool
_zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error)
{
zip_uint16_t ef_len;
zip_buffer_t *buffer;
const zip_uint8_t *ef;
bool crc_valid;
zip_uint16_t enc_method;
if (de->comp_method != ZIP_CM_WINZIP_AES) {
return true;
}
ef = _zip_ef_get_by_id(de->extra_fields, &ef_len, ZIP_EF_WINZIP_AES, 0, ZIP_EF_BOTH, NULL);
if (ef == NULL || ef_len < 7) {
zip_error_set(error, ZIP_ER_INCONS, 0);
return false;
}
if ((buffer = _zip_buffer_new((zip_uint8_t *)ef, ef_len)) == NULL) {
zip_error_set(error, ZIP_ER_INTERNAL, 0);
return false;
}
/* version */
crc_valid = true;
switch (_zip_buffer_get_16(buffer)) {
case 1:
break;
case 2:
if (de->uncomp_size < 20 /* TODO: constant */) {
crc_valid = false;
}
break;
default:
zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0);
_zip_buffer_free(buffer);
return false;
}
/* vendor */
if (memcmp(_zip_buffer_get(buffer, 2), "AE", 2) != 0) {
zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0);
_zip_buffer_free(buffer);
return false;
}
/* mode */
switch (_zip_buffer_get_8(buffer)) {
case 1:
enc_method = ZIP_EM_AES_128;
break;
case 2:
enc_method = ZIP_EM_AES_192;
break;
case 3:
enc_method = ZIP_EM_AES_256;
break;
default:
zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0);
_zip_buffer_free(buffer);
return false;
}
if (ef_len != 7) {
zip_error_set(error, ZIP_ER_INCONS, 0);
_zip_buffer_free(buffer);
return false;
}
de->crc_valid = crc_valid;
de->encryption_method = enc_method;
de->comp_method = _zip_buffer_get_16(buffer);
_zip_buffer_free(buffer);
return true;
}
zip_int32_t
_zip_dirent_size(zip_source_t *src, zip_uint16_t flags, zip_error_t *error)
{
@ -621,6 +765,7 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags)
zip_uint32_t ef_total_size;
bool is_zip64;
bool is_really_zip64;
bool is_winzip_aes;
zip_uint8_t buf[CDENTRYSIZE];
zip_buffer_t *buffer;
@ -651,8 +796,16 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags)
}
}
if (de->encryption_method == ZIP_EM_NONE) {
de->bitflags &= ~ZIP_GPBF_ENCRYPTED;
}
else {
de->bitflags |= ZIP_GPBF_ENCRYPTED;
}
is_really_zip64 = _zip_dirent_needs_zip64(de, flags);
is_zip64 = (flags & (ZIP_FL_LOCAL|ZIP_FL_FORCE_ZIP64)) == (ZIP_FL_LOCAL|ZIP_FL_FORCE_ZIP64) || is_really_zip64;
is_winzip_aes = de->encryption_method == ZIP_EM_AES_128 || de->encryption_method == ZIP_EM_AES_192 || de->encryption_method == ZIP_EM_AES_256;
if (is_zip64) {
zip_uint8_t ef_zip64[EFZIP64SIZE];
@ -696,6 +849,35 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags)
ef = ef64;
}
if (is_winzip_aes) {
zip_uint8_t data[EF_WINZIP_AES_SIZE];
zip_buffer_t *ef_buffer = _zip_buffer_new(data, sizeof(data));
zip_extra_field_t *ef_winzip;
if (ef_buffer == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
_zip_ef_free(ef);
return -1;
}
_zip_buffer_put_16(ef_buffer, 2);
_zip_buffer_put(ef_buffer, "AE", 2);
_zip_buffer_put_8(ef_buffer, (de->encryption_method & 0xff));
_zip_buffer_put_16(ef_buffer, (zip_uint16_t)de->comp_method);
if (!_zip_buffer_ok(ef_buffer)) {
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
_zip_buffer_free(ef_buffer);
_zip_ef_free(ef);
return -1;
}
ef_winzip = _zip_ef_new(ZIP_EF_WINZIP_AES, EF_WINZIP_AES_SIZE, data, ZIP_EF_BOTH);
_zip_buffer_free(ef_buffer);
ef_winzip->next = ef;
ef = ef_winzip;
}
if ((buffer = _zip_buffer_new(buf, sizeof(buf))) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
_zip_ef_free(ef);
@ -709,13 +891,23 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags)
}
_zip_buffer_put_16(buffer, (zip_uint16_t)(is_really_zip64 ? 45 : de->version_needed));
_zip_buffer_put_16(buffer, de->bitflags&0xfff9); /* clear compression method specific flags */
_zip_buffer_put_16(buffer, (zip_uint16_t)de->comp_method);
if (is_winzip_aes) {
_zip_buffer_put_16(buffer, ZIP_CM_WINZIP_AES);
}
else {
_zip_buffer_put_16(buffer, (zip_uint16_t)de->comp_method);
}
_zip_u2d_time(de->last_mod, &dostime, &dosdate);
_zip_buffer_put_16(buffer, dostime);
_zip_buffer_put_16(buffer, dosdate);
_zip_buffer_put_32(buffer, de->crc);
if (is_winzip_aes && de->uncomp_size < 20) {
_zip_buffer_put_32(buffer, 0);
}
else {
_zip_buffer_put_32(buffer, de->crc);
}
if (((flags & ZIP_FL_LOCAL) == ZIP_FL_LOCAL) && ((de->comp_size >= ZIP_UINT32_MAX) || (de->uncomp_size >= ZIP_UINT32_MAX))) {
/* In local headers, if a ZIP64 EF is written, it MUST contain

View File

@ -1,6 +1,6 @@
/*
zip_discard.c -- discard and free struct zip
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>

View File

@ -31,7 +31,7 @@ const char * const _zip_err_str[] = {
"Can't remove file",
"Entry has been deleted",
"Encryption method not supported",
"Read-only archive",
"Read-only archive",
"No password provided",
"Wrong password provided",
"Operation not supported",
@ -71,7 +71,7 @@ const int _zip_err_type[] = {
S,
N,
N,
N,
N,
N,
N,
N,

View File

@ -1,6 +1,6 @@
/*
zip_error.c -- zip_error_t helper functions
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>

View File

@ -1,6 +1,6 @@
/*
zip_error_sterror.c -- get string representation of struct zip_error
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>

View File

@ -1,6 +1,6 @@
/*
zip_error_to_str.c -- get string representation of zip error code
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>

View File

@ -1,6 +1,6 @@
/*
zip_extra_field.c -- manipulate extra fields
Copyright (C) 2012-2015 Dieter Baron and Thomas Klausner
Copyright (C) 2012-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>

View File

@ -1,6 +1,6 @@
/*
zip_fdopen.c -- open read-only archive from file descriptor
Copyright (C) 2009-2014 Dieter Baron and Thomas Klausner
Copyright (C) 2009-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>

View File

@ -1,6 +1,6 @@
/*
zip_file_get_offset.c -- get offset of file data in archive.
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>

View File

@ -1,6 +1,6 @@
/*
zip_filerange_crc.c -- compute CRC32 for a range of a file
Copyright (C) 2008-2015 Dieter Baron and Thomas Klausner
Copyright (C) 2008-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>

View File

@ -1,6 +1,6 @@
/*
zip_fopen_index.c -- open file in zip archive for reading by index
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>

View File

@ -1,6 +1,6 @@
/*
zip_fopen_index_encrypted.c -- open file for reading by index w/ password
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>

View File

@ -1,6 +1,6 @@
/*
zip_get_compression_implementation.c -- get compression implementation
Copyright (C) 2009-2014 Dieter Baron and Thomas Klausner
Copyright (C) 2009-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>
@ -36,7 +36,7 @@
zip_compression_implementation
_zip_get_compression_implementation(zip_int32_t cm)
_zip_get_compression_implementation(zip_int32_t cm, int operation)
{
if (cm == ZIP_CM_DEFLATE || ZIP_CM_IS_DEFAULT(cm))
return zip_source_deflate;

View File

@ -1,6 +1,6 @@
/*
zip_get_encryption_implementation.c -- get encryption implementation
Copyright (C) 2009-2014 Dieter Baron and Thomas Klausner
Copyright (C) 2009-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>
@ -36,9 +36,21 @@
zip_encryption_implementation
_zip_get_encryption_implementation(zip_uint16_t em)
_zip_get_encryption_implementation(zip_uint16_t em, int operation)
{
if (em == ZIP_EM_TRAD_PKWARE)
switch (em) {
case ZIP_EM_TRAD_PKWARE:
if (operation == ZIP_CODEC_ENCODE) {
return NULL;
}
return zip_source_pkware;
return NULL;
case ZIP_EM_AES_128:
case ZIP_EM_AES_192:
case ZIP_EM_AES_256:
return operation == ZIP_CODEC_DECODE ? zip_source_winzip_aes_decode : zip_source_winzip_aes_encode;
default:
return NULL;
}
}

View File

@ -1,6 +1,6 @@
/*
zip_io_util.c -- I/O helper functions
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>

View File

@ -1,6 +1,6 @@
/*
zip_name_locate.c -- get index 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>

View File

@ -1,6 +1,6 @@
/*
zip_new.c -- create and init struct zip
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>
@ -68,7 +68,7 @@ _zip_new(zip_error_t *error)
za->entry = NULL;
za->nopen_source = za->nopen_source_alloc = 0;
za->open_source = NULL;
za->tempdir = NULL;
za->progress_callback = NULL;
return za;
}

View File

@ -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;

View File

@ -1,6 +1,6 @@
/*
zip_set_default_password.c -- set default password for decryption
Copyright (C) 2009-2014 Dieter Baron and Thomas Klausner
Copyright (C) 2009-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>

View File

@ -1,6 +1,6 @@
/*
zip_set_name.c -- rename helper function
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>

View File

@ -1,6 +1,6 @@
/*
zip_source_error.c -- get last error from zip_source
Copyright (C) 2009-2014 Dieter Baron and Thomas Klausner
Copyright (C) 2009-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>
@ -40,3 +40,9 @@ zip_source_error(zip_source_t *src)
{
return &src->error;
}
bool
_zip_source_had_error(zip_source_t *src)
{
return zip_source_error(src)->zip_err != ZIP_ER_OK;
}

View File

@ -1,6 +1,6 @@
/*
zip_source_file.c -- create data source from file
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
@ -46,7 +46,7 @@ zip_source_file(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t le
{
if (za == NULL)
return NULL;
return zip_source_file_create(fname, start, len, &za->error);
}

View File

@ -1,6 +1,6 @@
/*
zip_source_filep.c -- create data source from FILE *
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
@ -72,10 +72,11 @@ struct read_file {
char *fname; /* name of file to read from */
FILE *f; /* file to read from */
struct zip_stat st; /* stat information passed in */
zip_error_t stat_error; /* error returned for stat */
zip_uint64_t start; /* start offset of data to read */
zip_uint64_t end; /* end offset of data to read, 0 for up to EOF */
zip_uint64_t current; /* current offset */
zip_uint64_t end; /* end offset of data to read relative to start, 0 for up to EOF */
zip_uint64_t current; /* current offset relative to start (0 is beginning of part we read) */
/* writing */
char *tmpname;
FILE *fout;
@ -92,7 +93,7 @@ zip_source_filep(zip_t *za, FILE *file, zip_uint64_t start, zip_int64_t len)
{
if (za == NULL)
return NULL;
return zip_source_filep_create(file, start, len, &za->error);
}
@ -114,12 +115,21 @@ _zip_source_file_or_p(const char *fname, FILE *file, zip_uint64_t start, zip_int
{
struct read_file *ctx;
zip_source_t *zs;
if (file == NULL && fname == NULL) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
if (len < 0) {
len = 0;
}
if (start > ZIP_INT64_MAX || start + (zip_uint64_t)len < start) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
if ((ctx=(struct read_file *)malloc(sizeof(struct read_file))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
@ -135,7 +145,7 @@ _zip_source_file_or_p(const char *fname, FILE *file, zip_uint64_t start, zip_int
}
ctx->f = file;
ctx->start = start;
ctx->end = (len < 0 ? 0 : start+(zip_uint64_t)len);
ctx->end = (zip_uint64_t)len;
if (st) {
memcpy(&ctx->st, st, sizeof(ctx->st));
ctx->st.name = NULL;
@ -144,18 +154,53 @@ _zip_source_file_or_p(const char *fname, FILE *file, zip_uint64_t start, zip_int
else {
zip_stat_init(&ctx->st);
}
if (ctx->end > 0) {
ctx->st.size = ctx->end;
ctx->st.valid |= ZIP_STAT_SIZE;
}
zip_error_init(&ctx->stat_error);
ctx->tmpname = NULL;
ctx->fout = NULL;
zip_error_init(&ctx->error);
ctx->supports = ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1);
if (ctx->fname) {
struct stat sb;
if (stat(ctx->fname, &sb) < 0) {
zip_error_set(&ctx->stat_error, ZIP_ER_READ, errno);
if (ctx->start == 0 && ctx->end == 0) {
ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE;
}
}
else {
if ((ctx->st.valid & ZIP_STAT_MTIME) == 0) {
ctx->st.mtime = sb.st_mtime;
ctx->st.valid |= ZIP_STAT_MTIME;
}
if (S_ISREG(sb.st_mode)) {
ctx->supports = ZIP_SOURCE_SUPPORTS_SEEKABLE;
if (stat(ctx->fname, &sb) < 0 || S_ISREG(sb.st_mode)) {
ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE;
if (ctx->start + ctx->end > (zip_uint64_t)sb.st_size) {
zip_error_set(error, ZIP_ER_INVAL, 0);
free(ctx->fname);
free(ctx);
return NULL;
}
if (ctx->end == 0) {
ctx->st.size = (zip_uint64_t)sb.st_size - ctx->start;
ctx->st.valid |= ZIP_STAT_SIZE;
if (start == 0) {
ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE;
}
}
}
}
}
else if (fseeko(ctx->f, 0, SEEK_CUR) == 0) {
@ -179,7 +224,7 @@ create_temp_output(struct read_file *ctx)
int tfd;
mode_t mask;
FILE *tfp;
if ((temp=(char *)malloc(strlen(ctx->fname)+8)) == NULL) {
zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
return -1;
@ -202,7 +247,7 @@ create_temp_output(struct read_file *ctx)
free(temp);
return -1;
}
#ifdef _WIN32
/*
According to Pierre Joye, Windows in some environments per
@ -210,10 +255,10 @@ create_temp_output(struct read_file *ctx)
*/
_setmode(_fileno(tfp), _O_BINARY );
#endif
ctx->fout = tfp;
ctx->tmpname = temp;
return 0;
}
@ -236,7 +281,7 @@ read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
return -1;
}
return create_temp_output(ctx);
case ZIP_SOURCE_COMMIT_WRITE: {
mode_t mask;
@ -257,17 +302,17 @@ read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
ctx->tmpname = NULL;
return 0;
}
case ZIP_SOURCE_CLOSE:
if (ctx->fname) {
fclose(ctx->f);
ctx->f = NULL;
}
return 0;
case ZIP_SOURCE_ERROR:
return zip_error_to_data(&ctx->error, data, len);
case ZIP_SOURCE_FREE:
free(ctx->fname);
free(ctx->tmpname);
@ -275,7 +320,7 @@ read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
fclose(ctx->f);
free(ctx);
return 0;
case ZIP_SOURCE_OPEN:
if (ctx->fname) {
if ((ctx->f=fopen(ctx->fname, "rb")) == NULL) {
@ -283,18 +328,19 @@ read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
return -1;
}
}
if (ctx->start > 0) {
if (_zip_fseek_u(ctx->f, ctx->start, SEEK_SET, &ctx->error) < 0) {
/* TODO: skip by reading */
return -1;
}
}
ctx->current = ctx->start;
ctx->current = 0;
return 0;
case ZIP_SOURCE_READ:
if (ctx->end > 0) {
n = ctx->end-ctx->current;
n = ctx->end - ctx->current;
if (n > len) {
n = len;
}
@ -302,7 +348,7 @@ read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
else {
n = len;
}
if (n > SIZE_MAX)
n = SIZE_MAX;
@ -315,14 +361,14 @@ read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
ctx->current += i;
return (zip_int64_t)i;
case ZIP_SOURCE_REMOVE:
if (remove(ctx->fname) < 0) {
zip_error_set(&ctx->error, ZIP_ER_REMOVE, errno);
return -1;
}
return 0;
case ZIP_SOURCE_ROLLBACK_WRITE:
if (ctx->fout) {
fclose(ctx->fout);
@ -332,7 +378,7 @@ read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
free(ctx->tmpname);
ctx->tmpname = NULL;
return 0;
case ZIP_SOURCE_SEEK: {
zip_int64_t new_current;
int need_seek;
@ -340,14 +386,14 @@ read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
if (args == NULL)
return -1;
need_seek = 1;
switch (args->whence) {
case SEEK_SET:
new_current = args->offset;
break;
case SEEK_END:
if (ctx->end == 0) {
if (_zip_fseek(ctx->f, args->offset, SEEK_END, &ctx->error) < 0) {
@ -357,12 +403,14 @@ read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
zip_error_set(&ctx->error, ZIP_ER_SEEK, errno);
return -1;
}
new_current -= (zip_int64_t)ctx->start;
need_seek = 0;
}
else {
new_current = (zip_int64_t)ctx->end + args->offset;
}
break;
case SEEK_CUR:
new_current = (zip_int64_t)ctx->current + args->offset;
break;
@ -372,29 +420,30 @@ read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
return -1;
}
if (new_current < 0 || (zip_uint64_t)new_current < ctx->start || (ctx->end != 0 && (zip_uint64_t)new_current > ctx->end)) {
if (new_current < 0 || (ctx->end != 0 && (zip_uint64_t)new_current > ctx->end)
|| (zip_uint64_t)new_current + ctx->start < ctx->start) {
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
return -1;
}
ctx->current = (zip_uint64_t)new_current;
if (need_seek) {
if (_zip_fseek_u(ctx->f, ctx->current, SEEK_SET, &ctx->error) < 0) {
if (_zip_fseek_u(ctx->f, ctx->current + ctx->start, SEEK_SET, &ctx->error) < 0) {
return -1;
}
}
return 0;
}
case ZIP_SOURCE_SEEK_WRITE: {
zip_source_args_seek_t *args;
args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error);
if (args == NULL) {
return -1;
}
if (_zip_fseek(ctx->fout, args->offset, args->whence, &ctx->error) < 0) {
return -1;
}
@ -405,68 +454,43 @@ read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
if (len < sizeof(ctx->st))
return -1;
if (ctx->st.valid != 0)
memcpy(data, &ctx->st, sizeof(ctx->st));
else {
zip_stat_t *st;
struct stat fst;
int err;
if (ctx->f)
err = fstat(fileno(ctx->f), &fst);
else
err = stat(ctx->fname, &fst);
if (err != 0) {
zip_error_set(&ctx->error, ZIP_ER_READ, errno);
return -1;
}
st = (zip_stat_t *)data;
zip_stat_init(st);
st->mtime = fst.st_mtime;
st->valid |= ZIP_STAT_MTIME;
if (ctx->end != 0) {
st->size = ctx->end - ctx->start;
st->valid |= ZIP_STAT_SIZE;
}
else if ((fst.st_mode&S_IFMT) == S_IFREG) {
st->size = (zip_uint64_t)fst.st_size;
st->valid |= ZIP_STAT_SIZE;
}
if (zip_error_code_zip(&ctx->stat_error) != 0) {
zip_error_set(&ctx->error, zip_error_code_zip(&ctx->stat_error), zip_error_code_system(&ctx->stat_error));
return -1;
}
memcpy(data, &ctx->st, sizeof(ctx->st));
return sizeof(ctx->st);
}
case ZIP_SOURCE_SUPPORTS:
return ctx->supports;
case ZIP_SOURCE_TELL:
return (zip_int64_t)ctx->current;
case ZIP_SOURCE_TELL_WRITE:
{
off_t ret = ftello(ctx->fout);
if (ret < 0) {
zip_error_set(&ctx->error, ZIP_ER_TELL, errno);
return -1;
}
return ret;
}
case ZIP_SOURCE_WRITE:
{
size_t ret;
clearerr(ctx->fout);
ret = fwrite(data, 1, len, ctx->fout);
if (ret != len || ferror(ctx->fout)) {
zip_error_set(&ctx->error, ZIP_ER_WRITE, errno);
return -1;
}
return (zip_int64_t)ret;
}

View File

@ -1,6 +1,6 @@
/*
zip_source_function.c -- create zip data source from callback function
Copyright (C) 1999-2014 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>
@ -94,6 +94,7 @@ _zip_source_new(zip_error_t *error)
src->source_archive = NULL;
src->refcount = 1;
zip_error_init(&src->error);
src->eof = false;
return src;
}

View File

@ -1,6 +1,6 @@
/*
zip_source_open.c -- open zip_source (prepare for reading)
Copyright (C) 2009-2014 Dieter Baron and Thomas Klausner
Copyright (C) 2009-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>
@ -67,6 +67,8 @@ zip_source_open(zip_source_t *src)
}
}
src->eof = false;
_zip_error_clear(&src->error);
src->open_count++;
return 0;

View File

@ -1,6 +1,6 @@
/*
zip_source_pkware.c -- Traditional PKWARE de/encryption routines
Copyright (C) 2009-2015 Dieter Baron and Thomas Klausner
Copyright (C) 2009-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>

View File

@ -1,6 +1,6 @@
/*
zip_source_read.c -- read data from zip_source
Copyright (C) 2009-2014 Dieter Baron and Thomas Klausner
Copyright (C) 2009-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>
@ -38,6 +38,9 @@
zip_int64_t
zip_source_read(zip_source_t *src, void *data, zip_uint64_t len)
{
zip_uint64_t bytes_read;
zip_int64_t n;
if (src->source_closed) {
return -1;
}
@ -46,5 +49,39 @@ zip_source_read(zip_source_t *src, void *data, zip_uint64_t len)
return -1;
}
return _zip_source_call(src, data, len, ZIP_SOURCE_READ);
if (_zip_source_had_error(src)) {
return -1;
}
if (_zip_source_eof(src)) {
return 0;
}
bytes_read = 0;
while (bytes_read < len) {
if ((n = _zip_source_call(src, (zip_uint8_t *)data + bytes_read, len - bytes_read, ZIP_SOURCE_READ)) < 0) {
if (bytes_read == 0) {
return -1;
}
else {
return (zip_int64_t)bytes_read;
}
}
if (n == 0) {
src->eof = 1;
break;
}
bytes_read += (zip_uint64_t)n;
}
return (zip_int64_t)bytes_read;
}
bool
_zip_source_eof(zip_source_t *src)
{
return src->eof;
}

View File

@ -1,6 +1,6 @@
/*
zip_source_stat.c -- get meta information from zip_source
Copyright (C) 2009-2015 Dieter Baron and Thomas Klausner
Copyright (C) 2009-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>

View File

@ -1,6 +1,6 @@
/*
zip_source_supports.c -- check for supported functions
Copyright (C) 2014-2015 Dieter Baron and Thomas Klausner
Copyright (C) 2014-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>

View File

@ -344,9 +344,12 @@ _win32_read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd
}
else {
h = ctx->ops->op_open(ctx);
if (h == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND) {
zip_error_set(&ctx->error, ZIP_ER_READ, ENOENT);
return -1;
if (h == INVALID_HANDLE_VALUE) {
win32err = GetLastError();
if (win32err == ERROR_FILE_NOT_FOUND || win32err == ERROR_PATH_NOT_FOUND) {
zip_error_set(&ctx->error, ZIP_ER_READ, ENOENT);
return -1;
}
}
}

View File

@ -1,6 +1,6 @@
/*
zip_source_zip_new.c -- prepare data structures for zip_fopen/zip_source_zip
Copyright (C) 2012-2015 Dieter Baron and Thomas Klausner
Copyright (C) 2012-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>
@ -81,11 +81,14 @@ _zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t fl
enc_impl = NULL;
if (((flags & ZIP_FL_ENCRYPTED) == 0) && (st.encryption_method != ZIP_EM_NONE)) {
if (password == NULL) {
password = za->default_password;
}
if (password == NULL) {
zip_error_set(&za->error, ZIP_ER_NOPASSWD, 0);
return NULL;
}
if ((enc_impl=_zip_get_encryption_implementation(st.encryption_method)) == NULL) {
if ((enc_impl=_zip_get_encryption_implementation(st.encryption_method, ZIP_CODEC_DECODE)) == NULL) {
zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
return NULL;
}
@ -94,7 +97,7 @@ _zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t fl
comp_impl = NULL;
if ((flags & ZIP_FL_COMPRESSED) == 0) {
if (st.comp_method != ZIP_CM_STORE) {
if ((comp_impl=_zip_get_compression_implementation(st.comp_method)) == NULL) {
if ((comp_impl=_zip_get_compression_implementation(st.comp_method, ZIP_CODEC_DECODE)) == NULL) {
zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
return NULL;
}

View File

@ -1,6 +1,6 @@
/*
zip_stat_index.c -- get information about file by index
Copyright (C) 1999-2014 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>
@ -64,17 +64,8 @@ zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags,
st->mtime = de->last_mod;
st->comp_size = de->comp_size;
st->comp_method = (zip_uint16_t)de->comp_method;
if (de->bitflags & ZIP_GPBF_ENCRYPTED) {
if (de->bitflags & ZIP_GPBF_STRONG_ENCRYPTION) {
/* TODO */
st->encryption_method = ZIP_EM_UNKNOWN;
}
else
st->encryption_method = ZIP_EM_TRAD_PKWARE;
}
else
st->encryption_method = ZIP_EM_NONE;
st->valid = ZIP_STAT_CRC|ZIP_STAT_SIZE|ZIP_STAT_MTIME
st->encryption_method = de->encryption_method;
st->valid = (de->crc_valid ? ZIP_STAT_CRC : 0) | ZIP_STAT_SIZE|ZIP_STAT_MTIME
|ZIP_STAT_COMP_SIZE|ZIP_STAT_COMP_METHOD|ZIP_STAT_ENCRYPTION_METHOD;
}

View File

@ -1,6 +1,6 @@
/*
zip_unchange.c -- undo changes to file in zip archive
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>

View File

@ -1,6 +1,6 @@
/*
zip_unchange.c -- undo changes to all files in zip archive
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>

View File

@ -20,7 +20,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
@ -64,16 +64,19 @@
#define CDBUFSIZE (MAXCOMLEN+EOCDLEN+EOCD64LOCLEN)
#define BUFSIZE 8192
#define EFZIP64SIZE 28
#define EF_WINZIP_AES_SIZE 7
#define ZIP_CM_REPLACED_DEFAULT (-2)
#define ZIP_CM_WINZIP_AES 99 /* Winzip AES encrypted */
#define ZIP_CM_IS_DEFAULT(x) ((x) == ZIP_CM_DEFAULT || (x) == ZIP_CM_REPLACED_DEFAULT)
#define ZIP_EF_UTF_8_COMMENT 0x6375
#define ZIP_EF_UTF_8_NAME 0x7075
#define ZIP_EF_WINZIP_AES 0x9901
#define ZIP_EF_ZIP64 0x0001
#define ZIP_EF_IS_INTERNAL(id) ((id) == ZIP_EF_UTF_8_COMMENT || (id) == ZIP_EF_UTF_8_NAME || (id) == ZIP_EF_ZIP64)
#define ZIP_EF_IS_INTERNAL(id) ((id) == ZIP_EF_UTF_8_COMMENT || (id) == ZIP_EF_UTF_8_NAME || (id) == ZIP_EF_WINZIP_AES || (id) == ZIP_EF_ZIP64)
/* according to unzip-6.0's zipinfo.c, this corresponds to a regular file with rw permissions for everyone */
#define ZIP_EXT_ATTRIB_DEFAULT (0100666u<<16)
@ -96,8 +99,8 @@
typedef zip_source_t *(*zip_compression_implementation)(zip_t *, zip_source_t *, zip_int32_t, int);
typedef zip_source_t *(*zip_encryption_implementation)(zip_t *, zip_source_t *, zip_uint16_t, int, const char *);
zip_compression_implementation _zip_get_compression_implementation(zip_int32_t);
zip_encryption_implementation _zip_get_encryption_implementation(zip_uint16_t);
zip_compression_implementation _zip_get_compression_implementation(zip_int32_t method, int operation);
zip_encryption_implementation _zip_get_encryption_implementation(zip_uint16_t method, int operation);
@ -118,6 +121,8 @@ zip_source_t *zip_source_pkware(zip_t *, zip_source_t *, zip_uint16_t, int, cons
int zip_source_remove(zip_source_t *);
zip_int64_t zip_source_supports(zip_source_t *src);
zip_source_t *zip_source_window(zip_t *, zip_source_t *, zip_uint64_t, zip_uint64_t);
zip_source_t *zip_source_winzip_aes_decode(zip_t *, zip_source_t *, zip_uint16_t, int, const char *);
zip_source_t *zip_source_winzip_aes_encode(zip_t *, zip_source_t *, zip_uint16_t, int, const char *);
/* error source for layered sources */
@ -193,8 +198,8 @@ struct zip {
zip_source_t **open_source; /* open sources using archive */
zip_hash_t *names; /* hash table for name lookup */
char *tempdir; /* custom temp dir (needed e.g. for OS X sandboxing) */
zip_progress_callback_t progress_callback; /* progress callback for zip_close() */
};
/* file in zip archive, part of API */
@ -208,18 +213,22 @@ struct zip_file {
/* zip archive directory entry (central or local) */
#define ZIP_DIRENT_COMP_METHOD 0x0001u
#define ZIP_DIRENT_FILENAME 0x0002u
#define ZIP_DIRENT_COMMENT 0x0004u
#define ZIP_DIRENT_EXTRA_FIELD 0x0008u
#define ZIP_DIRENT_ATTRIBUTES 0x0010u
#define ZIP_DIRENT_LAST_MOD 0x0020u
#define ZIP_DIRENT_ALL 0xffffu
#define ZIP_DIRENT_COMP_METHOD 0x0001u
#define ZIP_DIRENT_FILENAME 0x0002u
#define ZIP_DIRENT_COMMENT 0x0004u
#define ZIP_DIRENT_EXTRA_FIELD 0x0008u
#define ZIP_DIRENT_ATTRIBUTES 0x0010u
#define ZIP_DIRENT_LAST_MOD 0x0020u
#define ZIP_DIRENT_ENCRYPTION_METHOD 0x0040u
#define ZIP_DIRENT_PASSWORD 0x0080u
#define ZIP_DIRENT_ALL ZIP_UINT32_MAX
struct zip_dirent {
zip_uint32_t changed;
bool local_extra_fields_read; /* whether we already read in local header extra fields */
bool cloned; /* whether this instance is cloned, and thus shares non-changed strings */
bool cloned; /* whether this instance is cloned, and thus shares non-changed strings */
bool crc_valid; /* if CRC is valid (sometimes not for encrypted archives) */
zip_uint16_t version_madeby; /* (c) version of creator */
zip_uint16_t version_needed; /* (cl) version needed to extract */
@ -236,6 +245,9 @@ struct zip_dirent {
zip_uint16_t int_attrib; /* (c) internal file attributes */
zip_uint32_t ext_attrib; /* (c) external file attributes */
zip_uint64_t offset; /* (c) offset of local header */
zip_uint16_t encryption_method; /* encryption method, computed from other fields */
char *password; /* file specific encryption password */
};
/* zip archive central directory */
@ -248,6 +260,7 @@ struct zip_cdir {
zip_uint64_t size; /* size of central directory */
zip_uint64_t offset; /* offset of central directory in file */
zip_string_t *comment; /* zip archive comment */
bool is_zip64; /* central directory in zip64 format */
};
struct zip_extra_field {
@ -280,6 +293,7 @@ struct zip_source {
bool source_closed; /* set if source archive is closed */
zip_t *source_archive; /* zip archive we're reading from, NULL if not from archive */
unsigned int refcount;
bool eof; /* EOF reached */
};
#define ZIP_SOURCE_IS_OPEN_READING(src) ((src)->open_count > 0)
@ -312,7 +326,7 @@ struct zip_string {
struct zip_buffer {
bool ok;
bool free_data;
zip_uint8_t *data;
zip_uint64_t size;
zip_uint64_t offset;
@ -332,6 +346,8 @@ extern const char * const _zip_err_str[];
extern const int _zip_nerr_str;
extern const int _zip_err_type[];
#define ZIP_MAX(a, b) ((a) > (b) ? (a) : (b))
#define ZIP_MIN(a, b) ((a) < (b) ? (a) : (b))
#define ZIP_ENTRY_CHANGED(e, f) ((e)->changes && ((e)->changes->changed & (f)))
@ -340,6 +356,17 @@ extern const int _zip_err_type[];
#define ZIP_IS_RDONLY(za) ((za)->ch_flags & ZIP_AFL_RDONLY)
#ifdef HAVE_EXPLICIT_MEMSET
#define _zip_crypto_clear(b, l) explicit_memset((b), 0, (l))
#else
#ifdef HAVE_EXPLICIT_BZERO
#define _zip_crypto_clear(b, l) explicit_bzero((b), (l))
#else
#define _zip_crypto_clear(b, l) memset((b), 0, (l))
#endif
#endif
zip_int64_t _zip_add_entry(zip_t *);
zip_uint8_t *_zip_buffer_data(zip_buffer_t *buffer);
@ -355,17 +382,20 @@ zip_buffer_t *_zip_buffer_new(zip_uint8_t *data, zip_uint64_t size);
zip_buffer_t *_zip_buffer_new_from_source(zip_source_t *src, zip_uint64_t size, zip_uint8_t *buf, zip_error_t *error);
zip_uint64_t _zip_buffer_offset(zip_buffer_t *buffer);
bool _zip_buffer_ok(zip_buffer_t *buffer);
zip_uint8_t *_zip_buffer_peek(zip_buffer_t *buffer, zip_uint64_t length);
int _zip_buffer_put(zip_buffer_t *buffer, const void *src, size_t length);
int _zip_buffer_put_16(zip_buffer_t *buffer, zip_uint16_t i);
int _zip_buffer_put_32(zip_buffer_t *buffer, zip_uint32_t i);
int _zip_buffer_put_64(zip_buffer_t *buffer, zip_uint64_t i);
int _zip_buffer_put_8(zip_buffer_t *buffer, zip_uint8_t i);
zip_uint64_t _zip_buffer_read(zip_buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length);
int _zip_buffer_skip(zip_buffer_t *buffer, zip_uint64_t length);
int _zip_buffer_set_offset(zip_buffer_t *buffer, zip_uint64_t offset);
zip_uint64_t _zip_buffer_size(zip_buffer_t *buffer);
int _zip_cdir_compute_crc(zip_t *, uLong *);
void _zip_cdir_free(zip_cdir_t *);
bool _zip_cdir_grow(zip_cdir_t *cd, zip_uint64_t additional_entries, zip_error_t *error);
zip_cdir_t *_zip_cdir_new(zip_uint64_t, zip_error_t *);
zip_int64_t _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors);
void _zip_deregister_source(zip_t *za, zip_source_t *src);
@ -422,6 +452,8 @@ void _zip_hash_revert(zip_hash_t *hash);
zip_t *_zip_open(zip_source_t *, unsigned int, zip_error_t *);
bool zip_random(zip_uint8_t *buffer, zip_uint16_t length);
int _zip_read(zip_source_t *src, zip_uint8_t *data, zip_uint64_t length, zip_error_t *error);
int _zip_read_at_offset(zip_source_t *src, zip_uint64_t offset, unsigned char *b, size_t length, zip_error_t *error);
zip_uint8_t *_zip_read_data(zip_buffer_t *buffer, zip_source_t *src, size_t length, bool nulp, zip_error_t *error);
@ -432,8 +464,10 @@ int _zip_register_source(zip_t *za, zip_source_t *src);
void _zip_set_open_error(int *zep, const zip_error_t *err, int ze);
zip_int64_t _zip_source_call(zip_source_t *src, void *data, zip_uint64_t length, zip_source_cmd_t command);
bool _zip_source_eof(zip_source_t *);
zip_source_t *_zip_source_file_or_p(const char *, FILE *, zip_uint64_t, zip_int64_t, const zip_stat_t *, zip_error_t *error);
void _zip_source_invalidate(zip_source_t *src);
bool _zip_source_had_error(zip_source_t *);
zip_source_t *_zip_source_new(zip_error_t *error);
int _zip_source_set_source_archive(zip_source_t *, zip_t *);
zip_source_t *_zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_uint64_t length, zip_stat_t *st, zip_error_t *error);