initial libzip upgrade patch to 0.10.1

This commit is contained in:
Anatoliy Belsky 2012-06-04 21:30:04 +02:00
parent 7cae4ff02c
commit 335a11b14b
64 changed files with 2720 additions and 695 deletions

View file

@ -89,7 +89,14 @@ yes
lib/zip_new.c lib/zip_source_file.c lib/zip_stat_index.c \ lib/zip_new.c lib/zip_source_file.c lib/zip_stat_index.c \
lib/zip_set_archive_comment.c lib/zip_set_file_comment.c \ lib/zip_set_archive_comment.c lib/zip_set_file_comment.c \
lib/zip_unchange_archive.c lib/zip_memdup.c lib/zip_stat_init.c lib/zip_add_dir.c \ lib/zip_unchange_archive.c lib/zip_memdup.c lib/zip_stat_init.c lib/zip_add_dir.c \
lib/zip_error_clear.c lib/zip_file_error_clear.c" lib/zip_error_clear.c lib/zip_file_error_clear.c \
lib/zip_fdopen.c lib/zip_fopen_encrypted.c lib/zip_fopen_index_encrypted.c \
lib/zip_get_compression_implementation.c lib/zip_get_encryption_implementation.c \
lib/zip_get_file_extra.c lib/zip_get_num_entries.c lib/zip_set_default_password.c \
lib/zip_set_file_extra.c lib/zip_source_close.c lib/zip_source_crc.c \
lib/zip_source_deflate.c lib/zip_source_error.c lib/zip_source_layered.c \
lib/zip_source_open.c lib/zip_source_pkware.c lib/zip_source_pop.c \
lib/zip_source_read.c lib/zip_source_stat.c"
AC_DEFINE(HAVE_ZIP,1,[ ]) AC_DEFINE(HAVE_ZIP,1,[ ])
PHP_NEW_EXTENSION(zip, php_zip.c zip_stream.c $PHP_ZIP_SOURCES, $ext_shared) PHP_NEW_EXTENSION(zip, php_zip.c zip_stream.c $PHP_ZIP_SOURCES, $ext_shared)

View file

@ -27,7 +27,14 @@ if (PHP_ZIP != "no") {
zip_get_archive_comment.c zip_get_file_comment.c \ zip_get_archive_comment.c zip_get_file_comment.c \
zip_set_archive_comment.c zip_set_file_comment.c \ zip_set_archive_comment.c zip_set_file_comment.c \
zip_unchange_archive.c zip_memdup.c zip_stat_init.c \ zip_unchange_archive.c zip_memdup.c zip_stat_init.c \
zip_add_dir.c zip_file_error_clear.c zip_error_clear.c", "zip"); zip_add_dir.c zip_file_error_clear.c zip_error_clear.c
lib/zip_fdopen.c lib/zip_fopen_encrypted.c lib/zip_fopen_index_encrypted.c \
lib/zip_get_compression_implementation.c lib/zip_get_encryption_implementation.c \
lib/zip_get_file_extra.c lib/zip_get_num_entries.c lib/zip_set_default_password.c \
lib/zip_set_file_extra.c lib/zip_source_close.c lib/zip_source_crc.c \
lib/zip_source_deflate.c lib/zip_source_error.c lib/zip_source_layered.c \
lib/zip_source_open.c lib/zip_source_pkware.c lib/zip_source_pop.c \
lib/zip_source_read.c lib/zip_source_stat.c", "zip");
AC_DEFINE('HAVE_ZIP', 1); AC_DEFINE('HAVE_ZIP', 1);
} else { } else {

View file

@ -3,7 +3,7 @@
/* /*
zip.h -- exported declarations. zip.h -- exported declarations.
Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner Copyright (C) 1999-2011 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <libzip@nih.at>
@ -52,6 +52,8 @@
BEGIN_EXTERN_C() BEGIN_EXTERN_C()
#include <lib/zipconf.h>
#include <sys/types.h> #include <sys/types.h>
#include <stdio.h> #include <stdio.h>
#include <time.h> #include <time.h>
@ -71,10 +73,19 @@ BEGIN_EXTERN_C()
#define ZIP_FL_COMPRESSED 4 /* read compressed data */ #define ZIP_FL_COMPRESSED 4 /* read compressed data */
#define ZIP_FL_UNCHANGED 8 /* use original data, ignoring changes */ #define ZIP_FL_UNCHANGED 8 /* use original data, ignoring changes */
#define ZIP_FL_RECOMPRESS 16 /* force recompression of data */ #define ZIP_FL_RECOMPRESS 16 /* force recompression of data */
#define ZIP_FL_ENCRYPTED 32 /* read encrypted data
(implies ZIP_FL_COMPRESSED) */
/* archive global flags flags */ /* archive global flags flags */
#define ZIP_AFL_TORRENT 1 /* torrent zipped */ #define ZIP_AFL_TORRENT 1 /* torrent zipped */
#define ZIP_AFL_RDONLY 2 /* read only -- cannot be cleared */
/* flags for compression and encryption sources */
#define ZIP_CODEC_ENCODE 1 /* compress/encrypt */
/* libzip error codes */ /* libzip error codes */
@ -102,7 +113,10 @@ BEGIN_EXTERN_C()
#define ZIP_ER_INCONS 21 /* N Zip archive inconsistent */ #define ZIP_ER_INCONS 21 /* N Zip archive inconsistent */
#define ZIP_ER_REMOVE 22 /* S Can't remove file */ #define ZIP_ER_REMOVE 22 /* S Can't remove file */
#define ZIP_ER_DELETED 23 /* N Entry has been deleted */ #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_NOPASSWD 26 /* N No password provided */
#define ZIP_ER_WRONGPASSWD 27 /* N Wrong password provided */
/* type of system error value */ /* type of system error value */
@ -162,69 +176,99 @@ enum zip_source_cmd {
ZIP_SOURCE_FREE /* cleanup and free resources */ ZIP_SOURCE_FREE /* cleanup and free resources */
}; };
typedef ssize_t (*zip_source_callback)(void *state, void *data, #define ZIP_SOURCE_ERR_LOWER -2
size_t len, enum zip_source_cmd cmd);
#define ZIP_STAT_NAME 0x0001
#define ZIP_STAT_INDEX 0x0002
#define ZIP_STAT_SIZE 0x0004
#define ZIP_STAT_COMP_SIZE 0x0008
#define ZIP_STAT_MTIME 0x0010
#define ZIP_STAT_CRC 0x0020
#define ZIP_STAT_COMP_METHOD 0x0040
#define ZIP_STAT_ENCRYPTION_METHOD 0x0080
#define ZIP_STAT_FLAGS 0x0100
struct zip_stat { struct zip_stat {
zip_uint64_t valid; /* which fields have valid values */
const char *name; /* name of the file */ const char *name; /* name of the file */
int index; /* index within archive */ zip_uint64_t index; /* index within archive */
unsigned int crc; /* crc of file data */ zip_uint64_t size; /* size of file (uncompressed) */
zip_uint64_t comp_size; /* size of file (compressed) */
time_t mtime; /* modification time */ time_t mtime; /* modification time */
off_t size; /* size of file (uncompressed) */ zip_uint32_t crc; /* crc of file data */
off_t comp_size; /* size of file (compressed) */ zip_uint16_t comp_method; /* compression method used */
unsigned short comp_method; /* compression method used */ zip_uint16_t encryption_method; /* encryption method used */
unsigned short encryption_method; /* encryption method used */ zip_uint32_t flags; /* reserved for future use */
}; };
struct zip; struct zip;
struct zip_file; struct zip_file;
struct zip_source; struct zip_source;
typedef zip_int64_t (*zip_source_callback)(void *, void *, zip_uint64_t,
enum zip_source_cmd);
ZIP_EXTERN(int) zip_add(struct zip *, const char *, struct zip_source *); ZIP_EXTERN(zip_int64_t) zip_add(struct zip *, const char *, struct zip_source *);
ZIP_EXTERN(int) zip_add_dir(struct zip *, const char *); ZIP_EXTERN(zip_int64_t) zip_add_dir(struct zip *, const char *);
ZIP_EXTERN(int) zip_close(struct zip *); ZIP_EXTERN(int) zip_close(struct zip *);
ZIP_EXTERN(int) zip_delete(struct zip *, int); ZIP_EXTERN(int) zip_delete(struct zip *, zip_uint64_t);
ZIP_EXTERN(void) zip_error_clear(struct zip *); ZIP_EXTERN(void) zip_error_clear(struct zip *);
ZIP_EXTERN(void) zip_error_get(struct zip *, int *, int *); ZIP_EXTERN(void) zip_error_get(struct zip *, int *, int *);
ZIP_EXTERN(int) zip_error_get_sys_type(int); ZIP_EXTERN(int) zip_error_get_sys_type(int);
ZIP_EXTERN(int) zip_error_to_str(char *, size_t, int, int); ZIP_EXTERN(int) zip_error_to_str(char *, zip_uint64_t, int, int);
ZIP_EXTERN(int) zip_fclose(struct zip_file *); ZIP_EXTERN(int) zip_fclose(struct zip_file *);
ZIP_EXTERN(struct zip *)zip_fdopen(int, int, int *);
ZIP_EXTERN(void) zip_file_error_clear(struct zip_file *); ZIP_EXTERN(void) zip_file_error_clear(struct zip_file *);
ZIP_EXTERN(void) zip_file_error_get(struct zip_file *, int *, int *); ZIP_EXTERN(void) zip_file_error_get(struct zip_file *, int *, int *);
ZIP_EXTERN(const char *)zip_file_strerror(struct zip_file *); ZIP_EXTERN(const char *)zip_file_strerror(struct zip_file *);
ZIP_EXTERN(struct zip_file *)zip_fopen(struct zip *, const char *, int); ZIP_EXTERN(struct) zip_file *zip_fopen(struct zip *, const char *, int);
ZIP_EXTERN(struct zip_file *)zip_fopen_index(struct zip *, int, int); ZIP_EXTERN(struct) zip_file *zip_fopen_encrypted(struct zip *, const char *,
ZIP_EXTERN(ssize_t) zip_fread(struct zip_file *, void *, size_t); int, const char *);
ZIP_EXTERN(struct zip_file *)zip_fopen_index(struct zip *, zip_uint64_t, int);
ZIP_EXTERN(struct zip_file *)zip_fopen_index_encrypted(struct zip *,
zip_uint64_t, int,
const char *);
ZIP_EXTERN(zip_int64_t) zip_fread(struct zip_file *, void *, zip_uint64_t);
ZIP_EXTERN(const char *)zip_get_archive_comment(struct zip *, int *, int); ZIP_EXTERN(const char *)zip_get_archive_comment(struct zip *, int *, int);
ZIP_EXTERN(int) zip_get_archive_flag(struct zip *, int, int); ZIP_EXTERN(int) zip_get_archive_flag(struct zip *, int, int);
ZIP_EXTERN(const char *)zip_get_file_comment(struct zip *, int, int *, int); ZIP_EXTERN(const char *)zip_get_file_comment(struct zip *, zip_uint64_t,
ZIP_EXTERN(const char *)zip_get_name(struct zip *, int, int); int *, int);
ZIP_EXTERN(int) zip_get_num_files(struct zip *); ZIP_EXTERN(const char *)zip_get_file_extra(struct zip *, zip_uint64_t,
int *, int);
ZIP_EXTERN(const char *)zip_get_name(struct zip *, zip_uint64_t, int);
ZIP_EXTERN(zip_uint64_t) zip_get_num_entries(struct zip *, int);
ZIP_EXTERN(int) zip_get_num_files(struct zip *); /* deprecated, use zip_get_num_entries instead */
ZIP_EXTERN(int) zip_name_locate(struct zip *, const char *, int); ZIP_EXTERN(int) zip_name_locate(struct zip *, const char *, int);
ZIP_EXTERN(struct zip *)zip_open(const char *, int, int *); ZIP_EXTERN(struct zip *)zip_open(const char *, int, int *);
ZIP_EXTERN(int) zip_rename(struct zip *, int, const char *); ZIP_EXTERN(int) zip_rename(struct zip *, zip_uint64_t, const char *);
ZIP_EXTERN(int) zip_replace(struct zip *, int, struct zip_source *); ZIP_EXTERN(int) zip_replace(struct zip *, zip_uint64_t, struct zip_source *);
ZIP_EXTERN(int) zip_set_archive_comment(struct zip *, const char *, int); ZIP_EXTERN(int) zip_set_archive_comment(struct zip *, const char *, int);
ZIP_EXTERN(int) zip_set_archive_flag(struct zip *, int, int); ZIP_EXTERN(int) zip_set_archive_flag(struct zip *, int, int);
ZIP_EXTERN(int) zip_set_file_comment(struct zip *, int, const char *, int); ZIP_EXTERN(int) zip_set_default_password(struct zip *, const char *);
ZIP_EXTERN(struct zip_source *)zip_source_buffer(struct zip *, const void *, ZIP_EXTERN(int) zip_set_file_comment(struct zip *, zip_uint64_t,
off_t, int); const char *, int);
ZIP_EXTERN(struct zip_source *)zip_source_file(struct zip *, const char *, ZIP_EXTERN(int) zip_set_file_extra(struct zip *, zip_uint64_t,
off_t, off_t); const char *, int);
ZIP_EXTERN(struct zip_source *)zip_source_filep(struct zip *, FILE *, ZIP_EXTERN(struct) zip_source *zip_source_buffer(struct zip *, const void *,
off_t, off_t); zip_uint64_t, int);
ZIP_EXTERN(struct) zip_source *zip_source_file(struct zip *, const char *,
zip_uint64_t, zip_int64_t);
ZIP_EXTERN(struct) zip_source *zip_source_filep(struct zip *, FILE *,
zip_uint64_t, zip_int64_t);
ZIP_EXTERN(void) zip_source_free(struct zip_source *); ZIP_EXTERN(void) zip_source_free(struct zip_source *);
ZIP_EXTERN(struct zip_source *)zip_source_function(struct zip *, ZIP_EXTERN(struct zip_source *)zip_source_function(struct zip *,
zip_source_callback, void *); zip_source_callback, void *);
ZIP_EXTERN(struct zip_source *)zip_source_zip(struct zip *, struct zip *, ZIP_EXTERN(struct zip_source *)zip_source_zip(struct zip *, struct zip *,
int, int, off_t, off_t); zip_uint64_t, int,
zip_uint64_t, zip_int64_t);
ZIP_EXTERN(int) zip_stat(struct zip *, const char *, int, struct zip_stat *); ZIP_EXTERN(int) zip_stat(struct zip *, const char *, int, struct zip_stat *);
ZIP_EXTERN(int) zip_stat_index(struct zip *, int, int, struct zip_stat *); ZIP_EXTERN(int) zip_stat_index(struct zip *, zip_uint64_t, int,
struct zip_stat *);
ZIP_EXTERN(void) zip_stat_init(struct zip_stat *); ZIP_EXTERN(void) zip_stat_init(struct zip_stat *);
ZIP_EXTERN(const char *)zip_strerror(struct zip *); ZIP_EXTERN(const char *)zip_strerror(struct zip *);
ZIP_EXTERN(int) zip_unchange(struct zip *, int); ZIP_EXTERN(int) zip_unchange(struct zip *, zip_uint64_t);
ZIP_EXTERN(int) zip_unchange_all(struct zip *); ZIP_EXTERN(int) zip_unchange_all(struct zip *);
ZIP_EXTERN(int) zip_unchange_archive(struct zip *); ZIP_EXTERN(int) zip_unchange_archive(struct zip *);

View file

@ -37,13 +37,20 @@
ZIP_EXTERN(int) /*
NOTE: Return type is signed so we can return -1 on error.
The index can not be larger than ZIP_INT64_MAX since the size
of the central directory cannot be larger than
ZIP_UINT64_MAX, and each entry is larger than 2 bytes.
*/
ZIP_EXTERN(zip_int64_t)
zip_add(struct zip *za, const char *name, struct zip_source *source) zip_add(struct zip *za, const char *name, struct zip_source *source)
{ {
if (name == NULL || source == NULL) { if (name == NULL || source == NULL) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0); _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1; return -1;
} }
return _zip_replace(za, -1, name, source); return _zip_replace(za, ZIP_UINT64_MAX, name, source);
} }

View file

@ -1,6 +1,6 @@
/* /*
zip_add_dir.c -- add directory zip_add_dir.c -- add directory
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <libzip@nih.at>
@ -40,13 +40,21 @@
ZIP_EXTERN(int) /* NOTE: Signed due to -1 on error. See zip_add.c for more details. */
ZIP_EXTERN(zip_int64_t)
zip_add_dir(struct zip *za, const char *name) zip_add_dir(struct zip *za, const char *name)
{ {
int len, ret; int len;
zip_int64_t ret;
char *s; char *s;
struct zip_source *source; struct zip_source *source;
if (ZIP_IS_RDONLY(za)) {
_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
if (name == NULL) { if (name == NULL) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0); _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1; return -1;

View file

@ -1,6 +1,6 @@
/* /*
zip_close.c -- close zip archive and update changes zip_close.c -- close zip archive and update changes
Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner Copyright (C) 1999-2011 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <libzip@nih.at>
@ -33,26 +33,28 @@
#include "zipint.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#ifdef PHP_WIN32
#include "zipint.h" #include <io.h>
#include <fcntl.h>
#endif
static int add_data(struct zip *, struct zip_source *, struct zip_dirent *, static int add_data(struct zip *, struct zip_source *, struct zip_dirent *,
FILE *); FILE *);
static int add_data_comp(zip_source_callback, void *, struct zip_stat *,
FILE *, struct zip_error *);
static int add_data_uncomp(struct zip *, zip_source_callback, void *,
struct zip_stat *, FILE *);
static void ch_set_error(struct zip_error *, zip_source_callback, void *);
static int copy_data(FILE *, off_t, FILE *, struct zip_error *); static int copy_data(FILE *, off_t, FILE *, struct zip_error *);
static int copy_source(struct zip *, struct zip_source *, FILE *);
static int write_cdir(struct zip *, struct zip_cdir *, FILE *); static int write_cdir(struct zip *, struct zip_cdir *, FILE *);
static int _zip_cdir_set_comment(struct zip_cdir *, struct zip *); static int _zip_cdir_set_comment(struct zip_cdir *, struct zip *);
static int _zip_changed(struct zip *, int *);
static char *_zip_create_temp_output(struct zip *, FILE **); static char *_zip_create_temp_output(struct zip *, FILE **);
static int _zip_torrentzip_cmp(const void *, const void *); static int _zip_torrentzip_cmp(const void *, const void *);
@ -72,7 +74,9 @@ zip_close(struct zip *za)
int i, j, error; int i, j, error;
char *temp; char *temp;
FILE *out; FILE *out;
#ifndef PHP_WIN32
mode_t mask; mode_t mask;
#endif
struct zip_cdir *cd; struct zip_cdir *cd;
struct zip_dirent de; struct zip_dirent de;
struct filelist *filelist; struct filelist *filelist;
@ -99,7 +103,7 @@ zip_close(struct zip *za)
} }
_zip_free(za); _zip_free(za);
return 0; return 0;
} }
if ((filelist=(struct filelist *)malloc(sizeof(filelist[0])*survivors)) if ((filelist=(struct filelist *)malloc(sizeof(filelist[0])*survivors))
== NULL) == NULL)
@ -126,11 +130,11 @@ zip_close(struct zip *za)
cd->comment_len = TORRENT_SIG_LEN + TORRENT_CRC_LEN; cd->comment_len = TORRENT_SIG_LEN + TORRENT_CRC_LEN;
} }
else if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, ZIP_FL_UNCHANGED) == 0) { else if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, ZIP_FL_UNCHANGED) == 0) {
if (_zip_cdir_set_comment(cd, za) == -1) { if (_zip_cdir_set_comment(cd, za) == -1) {
_zip_cdir_free(cd); _zip_cdir_free(cd);
free(filelist); free(filelist);
return -1; return -1;
} }
} }
if ((temp=_zip_create_temp_output(za, &out)) == NULL) { if ((temp=_zip_create_temp_output(za, &out)) == NULL) {
@ -198,8 +202,7 @@ zip_close(struct zip *za)
error = 1; error = 1;
break; break;
} }
memcpy(cd->entry+j, za->cdir->entry+i, sizeof(cd->entry[j])); memcpy(cd->entry+j, za->cdir->entry+i, sizeof(cd->entry[j]));
if (de.bitflags & ZIP_GPBF_DATA_DESCRIPTOR) { if (de.bitflags & ZIP_GPBF_DATA_DESCRIPTOR) {
de.crc = za->cdir->entry[i].crc; de.crc = za->cdir->entry[i].crc;
de.comp_size = za->cdir->entry[i].comp_size; de.comp_size = za->cdir->entry[i].comp_size;
@ -220,6 +223,22 @@ zip_close(struct zip *za)
cd->entry[j].filename_len = de.filename_len; cd->entry[j].filename_len = de.filename_len;
} }
if (za->entry[i].ch_extra_len != -1) {
free(de.extrafield);
if ((de.extrafield=malloc(za->entry[i].ch_extra_len)) == NULL) {
error = 1;
break;
}
memcpy(de.extrafield, za->entry[i].ch_extra, za->entry[i].ch_extra_len);
de.extrafield_len = za->entry[i].ch_extra_len;
/* as the rest of cd entries, its malloc/free is done by za */
/* TODO unsure if this should also be set in the CD --
* not done for now
cd->entry[j].extrafield = za->entry[i].ch_extra;
cd->entry[j].extrafield_len = za->entry[i].ch_extra_len;
*/
}
if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0) == 0 if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0) == 0
&& za->entry[i].ch_comment_len != -1) { && za->entry[i].ch_comment_len != -1) {
/* as the rest of cd entries, its malloc/free is done by za */ /* as the rest of cd entries, its malloc/free is done by za */
@ -234,16 +253,22 @@ zip_close(struct zip *za)
zs = NULL; zs = NULL;
if (!ZIP_ENTRY_DATA_CHANGED(za->entry+i)) { if (!ZIP_ENTRY_DATA_CHANGED(za->entry+i)) {
if ((zs=zip_source_zip(za, za, i, ZIP_FL_RECOMPRESS, 0, -1)) == NULL) { if ((zs=zip_source_zip(za, za, i, ZIP_FL_RECOMPRESS, 0, -1))
error = 1; == NULL) {
break; error = 1;
} break;
}
} }
if (add_data(za, zs ? zs : za->entry[i].source, &de, out) < 0) { if (add_data(za, zs ? zs : za->entry[i].source, &de, out) < 0) {
error = 1; error = 1;
if (zs)
zip_source_free(zs);
break; break;
} }
if (zs)
zip_source_free(zs);
cd->entry[j].last_mod = de.last_mod; cd->entry[j].last_mod = de.last_mod;
cd->entry[j].comp_method = de.comp_method; cd->entry[j].comp_method = de.comp_method;
cd->entry[j].comp_size = de.comp_size; cd->entry[j].comp_size = de.comp_size;
@ -307,9 +332,11 @@ zip_close(struct zip *za)
} }
return -1; return -1;
} }
#ifndef PHP_WIN32
mask = umask(0); mask = umask(0);
umask(mask); umask(mask);
chmod(za->zn, 0666&~mask); chmod(za->zn, 0666&~mask);
#endif
if (za->ch_comment) if (za->ch_comment)
free(za->ch_comment); free(za->ch_comment);
@ -322,23 +349,17 @@ zip_close(struct zip *za)
static int static int
add_data(struct zip *za, struct zip_source *zs, struct zip_dirent *de, FILE *ft) add_data(struct zip *za, struct zip_source *src, struct zip_dirent *de,
FILE *ft)
{ {
off_t offstart, offend; off_t offstart, offdata, offend;
zip_source_callback cb;
void *ud;
struct zip_stat st; struct zip_stat st;
struct zip_source *s2;
cb = zs->f; zip_compression_implementation comp_impl;
ud = zs->ud; int ret;
if (cb(ud, &st, sizeof(st), ZIP_SOURCE_STAT) < (ssize_t)sizeof(st)) { if (zip_source_stat(src, &st) < 0) {
ch_set_error(&za->error, cb, ud); _zip_error_set_from_source(&za->error, src);
return -1;
}
if (cb(ud, NULL, 0, ZIP_SOURCE_OPEN) < 0) {
ch_set_error(&za->error, cb, ud);
return -1; return -1;
} }
@ -347,19 +368,49 @@ add_data(struct zip *za, struct zip_source *zs, struct zip_dirent *de, FILE *ft)
if (_zip_dirent_write(de, ft, 1, &za->error) < 0) if (_zip_dirent_write(de, ft, 1, &za->error) < 0)
return -1; return -1;
if (st.comp_method != ZIP_CM_STORE) { if ((s2=zip_source_crc(za, src, 0)) == NULL) {
if (add_data_comp(cb, ud, &st, ft, &za->error) < 0) zip_source_pop(s2);
return -1;
}
else {
if (add_data_uncomp(za, cb, ud, &st, ft) < 0)
return -1;
}
if (cb(ud, NULL, 0, ZIP_SOURCE_CLOSE) < 0) {
ch_set_error(&za->error, cb, ud);
return -1; return -1;
} }
/* XXX: deflate 0-byte files for torrentzip? */
if (((st.valid & ZIP_STAT_COMP_METHOD) == 0
|| st.comp_method == ZIP_CM_STORE)
&& ((st.valid & ZIP_STAT_SIZE) == 0 || st.size != 0)) {
comp_impl = NULL;
if ((comp_impl=zip_get_compression_implementation(ZIP_CM_DEFLATE))
== NULL) {
_zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
zip_source_pop(s2);
return -1;
}
if ((s2=comp_impl(za, s2, ZIP_CM_DEFLATE, ZIP_CODEC_ENCODE))
== NULL) {
/* XXX: set error? */
zip_source_pop(s2);
return -1;
}
}
else
s2 = src;
offdata = ftello(ft);
ret = copy_source(za, s2, ft);
if (zip_source_stat(s2, &st) < 0)
ret = -1;
while (s2 != src) {
if ((s2=zip_source_pop(s2)) == NULL) {
/* XXX: set erorr */
ret = -1;
break;
}
}
if (ret < 0)
return -1;
offend = ftello(ft); offend = ftello(ft);
@ -368,19 +419,18 @@ add_data(struct zip *za, struct zip_source *zs, struct zip_dirent *de, FILE *ft)
return -1; return -1;
} }
de->last_mod = st.mtime; de->last_mod = st.mtime;
de->comp_method = st.comp_method; de->comp_method = st.comp_method;
de->crc = st.crc; de->crc = st.crc;
de->uncomp_size = st.size; de->uncomp_size = st.size;
de->comp_size = st.comp_size; de->comp_size = offend - offdata;
if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0)) if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0))
_zip_dirent_torrent_normalize(de); _zip_dirent_torrent_normalize(de);
if (_zip_dirent_write(de, ft, 1, &za->error) < 0) if (_zip_dirent_write(de, ft, 1, &za->error) < 0)
return -1; return -1;
if (fseeko(ft, offend, SEEK_SET) < 0) { if (fseeko(ft, offend, SEEK_SET) < 0) {
_zip_error_set(&za->error, ZIP_ER_SEEK, errno); _zip_error_set(&za->error, ZIP_ER_SEEK, errno);
return -1; return -1;
@ -391,133 +441,6 @@ add_data(struct zip *za, struct zip_source *zs, struct zip_dirent *de, FILE *ft)
static int
add_data_comp(zip_source_callback cb, void *ud, struct zip_stat *st,FILE *ft,
struct zip_error *error)
{
char buf[BUFSIZE];
ssize_t n;
st->comp_size = 0;
while ((n=cb(ud, buf, sizeof(buf), ZIP_SOURCE_READ)) > 0) {
if (fwrite(buf, 1, n, ft) != (size_t)n) {
_zip_error_set(error, ZIP_ER_WRITE, errno);
return -1;
}
st->comp_size += n;
}
if (n < 0) {
ch_set_error(error, cb, ud);
return -1;
}
return 0;
}
static int
add_data_uncomp(struct zip *za, zip_source_callback cb, void *ud,
struct zip_stat *st, FILE *ft)
{
char b1[BUFSIZE], b2[BUFSIZE];
int end, flush, ret;
ssize_t n;
size_t n2;
z_stream zstr;
int mem_level;
st->comp_method = ZIP_CM_DEFLATE;
st->comp_size = st->size = 0;
st->crc = crc32(0, NULL, 0);
zstr.zalloc = Z_NULL;
zstr.zfree = Z_NULL;
zstr.opaque = NULL;
zstr.avail_in = 0;
zstr.avail_out = 0;
if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0))
mem_level = TORRENT_MEM_LEVEL;
else
mem_level = MAX_MEM_LEVEL;
/* -MAX_WBITS: undocumented feature of zlib to _not_ write a zlib header */
deflateInit2(&zstr, Z_BEST_COMPRESSION, Z_DEFLATED, -MAX_WBITS, mem_level,
Z_DEFAULT_STRATEGY);
zstr.next_out = (Bytef *)b2;
zstr.avail_out = sizeof(b2);
zstr.next_in = NULL;
zstr.avail_in = 0;
flush = 0;
end = 0;
while (!end) {
if (zstr.avail_in == 0 && !flush) {
if ((n=cb(ud, b1, sizeof(b1), ZIP_SOURCE_READ)) < 0) {
ch_set_error(&za->error, cb, ud);
deflateEnd(&zstr);
return -1;
}
if (n > 0) {
zstr.avail_in = n;
zstr.next_in = (Bytef *)b1;
st->size += n;
st->crc = crc32(st->crc, (Bytef *)b1, n);
}
else
flush = Z_FINISH;
}
ret = deflate(&zstr, flush);
if (ret != Z_OK && ret != Z_STREAM_END) {
_zip_error_set(&za->error, ZIP_ER_ZLIB, ret);
return -1;
}
if (zstr.avail_out != sizeof(b2)) {
n2 = sizeof(b2) - zstr.avail_out;
if (fwrite(b2, 1, n2, ft) != n2) {
_zip_error_set(&za->error, ZIP_ER_WRITE, errno);
return -1;
}
zstr.next_out = (Bytef *)b2;
zstr.avail_out = sizeof(b2);
st->comp_size += n2;
}
if (ret == Z_STREAM_END) {
deflateEnd(&zstr);
end = 1;
}
}
return 0;
}
static void
ch_set_error(struct zip_error *error, zip_source_callback cb, void *ud)
{
int e[2];
if ((cb(ud, e, sizeof(e), ZIP_SOURCE_ERROR)) < (ssize_t)sizeof(e)) {
error->zip_err = ZIP_ER_INTERNAL;
error->sys_err = 0;
}
else {
error->zip_err = e[0];
error->sys_err = e[1];
}
}
static int static int
copy_data(FILE *fs, off_t len, FILE *ft, struct zip_error *error) copy_data(FILE *fs, off_t len, FILE *ft, struct zip_error *error)
{ {
@ -551,6 +474,40 @@ copy_data(FILE *fs, off_t len, FILE *ft, struct zip_error *error)
static int
copy_source(struct zip *za, struct zip_source *src, FILE *ft)
{
char buf[BUFSIZE];
zip_int64_t n;
int ret;
if (zip_source_open(src) < 0) {
_zip_error_set_from_source(&za->error, src);
return -1;
}
ret = 0;
while ((n=zip_source_read(src, buf, sizeof(buf))) > 0) {
if (fwrite(buf, 1, n, ft) != (size_t)n) {
_zip_error_set(&za->error, ZIP_ER_WRITE, errno);
ret = -1;
break;
}
}
if (n < 0) {
if (ret == 0)
_zip_error_set_from_source(&za->error, src);
ret = -1;
}
zip_source_close(src);
return ret;
}
static int static int
write_cdir(struct zip *za, struct zip_cdir *cd, FILE *out) write_cdir(struct zip *za, struct zip_cdir *cd, FILE *out)
{ {
@ -613,7 +570,7 @@ _zip_cdir_set_comment(struct zip_cdir *dest, struct zip *src)
static int int
_zip_changed(struct zip *za, int *survivorsp) _zip_changed(struct zip *za, int *survivorsp)
{ {
int changed, i, survivors; int changed, i, survivors;
@ -626,13 +583,15 @@ _zip_changed(struct zip *za, int *survivorsp)
for (i=0; i<za->nentry; i++) { for (i=0; i<za->nentry; i++) {
if ((za->entry[i].state != ZIP_ST_UNCHANGED) if ((za->entry[i].state != ZIP_ST_UNCHANGED)
|| (za->entry[i].ch_extra_len != -1)
|| (za->entry[i].ch_comment_len != -1)) || (za->entry[i].ch_comment_len != -1))
changed = 1; changed = 1;
if (za->entry[i].state != ZIP_ST_DELETED) if (za->entry[i].state != ZIP_ST_DELETED)
survivors++; survivors++;
} }
*survivorsp = survivors; if (survivorsp)
*survivorsp = survivors;
return changed; return changed;
} }
@ -668,6 +627,10 @@ _zip_create_temp_output(struct zip *za, FILE **outp)
return NULL; return NULL;
} }
#ifdef PHP_WIN32 #ifdef PHP_WIN32
/*
According to Pierre Joye, Windows in some environments per
default creates text files, so force binary mode.
*/
_setmode(_fileno(tfp), _O_BINARY ); _setmode(_fileno(tfp), _O_BINARY );
#endif #endif

View file

@ -1,6 +1,6 @@
/* /*
zip_delete.c -- delete file from zip archive zip_delete.c -- delete file from zip archive
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <libzip@nih.at>
@ -38,13 +38,18 @@
ZIP_EXTERN(int) ZIP_EXTERN(int)
zip_delete(struct zip *za, int idx) zip_delete(struct zip *za, zip_uint64_t idx)
{ {
if (idx < 0 || idx >= za->nentry) { if (idx < 0 || idx >= za->nentry) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0); _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1; return -1;
} }
if (ZIP_IS_RDONLY(za)) {
_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
/* allow duplicate file names, because the file will /* allow duplicate file names, because the file will
* be removed directly afterwards */ * be removed directly afterwards */
if (_zip_unchange(za, idx, 1) != 0) if (_zip_unchange(za, idx, 1) != 0)

View file

@ -45,7 +45,6 @@
static time_t _zip_d2u_time(int, int); static time_t _zip_d2u_time(int, int);
static char *_zip_readfpstr(FILE *, unsigned int, int, struct zip_error *); static char *_zip_readfpstr(FILE *, unsigned int, int, struct zip_error *);
static char *_zip_readstr(unsigned char **, int, int, struct zip_error *); static char *_zip_readstr(unsigned char **, int, int, struct zip_error *);
static void _zip_u2d_time(time_t, unsigned short *, unsigned short *);
static void _zip_write2(unsigned short, FILE *); static void _zip_write2(unsigned short, FILE *);
static void _zip_write4(unsigned int, FILE *); static void _zip_write4(unsigned int, FILE *);
@ -213,13 +212,13 @@ _zip_dirent_init(struct zip_dirent *de)
int int
_zip_dirent_read(struct zip_dirent *zde, FILE *fp, _zip_dirent_read(struct zip_dirent *zde, FILE *fp,
unsigned char **bufp, unsigned int *leftp, int local, unsigned char **bufp, zip_uint32_t *leftp, int local,
struct zip_error *error) struct zip_error *error)
{ {
unsigned char buf[CDENTRYSIZE]; unsigned char buf[CDENTRYSIZE];
unsigned char *cur; unsigned char *cur;
unsigned short dostime, dosdate; unsigned short dostime, dosdate;
unsigned int size; zip_uint32_t size;
if (local) if (local)
size = LENTRYSIZE; size = LENTRYSIZE;
@ -475,6 +474,8 @@ _zip_d2u_time(int dtime, int ddate)
{ {
struct tm tm = {0}; struct tm tm = {0};
memset(&tm, 0, sizeof(tm));
/* let mktime decide if DST is in effect */ /* let mktime decide if DST is in effect */
tm.tm_isdst = -1; tm.tm_isdst = -1;
@ -598,7 +599,7 @@ _zip_write4(unsigned int i, FILE *fp)
static void void
_zip_u2d_time(time_t time, unsigned short *dtime, unsigned short *ddate) _zip_u2d_time(time_t time, unsigned short *dtime, unsigned short *ddate)
{ {
struct tm *tm; struct tm *tm;

View file

@ -44,6 +44,9 @@ _zip_entry_free(struct zip_entry *ze)
{ {
free(ze->ch_filename); free(ze->ch_filename);
ze->ch_filename = NULL; ze->ch_filename = NULL;
free(ze->ch_extra);
ze->ch_extra = NULL;
ze->ch_extra_len = -1;
free(ze->ch_comment); free(ze->ch_comment);
ze->ch_comment = NULL; ze->ch_comment = NULL;
ze->ch_comment_len = -1; ze->ch_comment_len = -1;

View file

@ -1,6 +1,6 @@
/* /*
zip_entry_new.c -- create and init struct zip_entry zip_entry_new.c -- create and init struct zip_entry
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <libzip@nih.at>
@ -46,20 +46,21 @@ _zip_entry_new(struct zip *za)
if (!za) { if (!za) {
ze = (struct zip_entry *)malloc(sizeof(struct zip_entry)); ze = (struct zip_entry *)malloc(sizeof(struct zip_entry));
if (!ze) { if (!ze) {
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return NULL; return NULL;
} }
} }
else { else {
if (za->nentry >= za->nentry_alloc-1) { if (za->nentry+1 >= za->nentry_alloc) {
struct zip_entry *rentries;
za->nentry_alloc += 16; za->nentry_alloc += 16;
za->entry = (struct zip_entry *)realloc(za->entry, rentries = (struct zip_entry *)realloc(za->entry,
sizeof(struct zip_entry) sizeof(struct zip_entry)
* za->nentry_alloc); * za->nentry_alloc);
if (!za->entry) { if (!rentries) {
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0); _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return NULL; return NULL;
} }
za->entry = rentries;
} }
ze = za->entry+za->nentry; ze = za->entry+za->nentry;
} }
@ -67,6 +68,8 @@ _zip_entry_new(struct zip *za)
ze->state = ZIP_ST_UNCHANGED; ze->state = ZIP_ST_UNCHANGED;
ze->ch_filename = NULL; ze->ch_filename = NULL;
ze->ch_extra = NULL;
ze->ch_extra_len = -1;
ze->ch_comment = NULL; ze->ch_comment = NULL;
ze->ch_comment_len = -1; ze->ch_comment_len = -1;
ze->source = NULL; ze->source = NULL;

View file

@ -32,6 +32,10 @@ const char * const _zip_err_str[] = {
"Zip archive inconsistent", "Zip archive inconsistent",
"Can't remove file", "Can't remove file",
"Entry has been deleted", "Entry has been deleted",
"Encryption method not supported",
"Read-only archive",
"No password provided",
"Wrong password provided",
}; };
const int _zip_nerr_str = sizeof(_zip_err_str)/sizeof(_zip_err_str[0]); const int _zip_nerr_str = sizeof(_zip_err_str)/sizeof(_zip_err_str[0]);
@ -65,4 +69,8 @@ const int _zip_err_type[] = {
N, N,
S, S,
N, N,
N,
N,
N,
N,
}; };

View file

@ -1,6 +1,6 @@
/* /*
zip_error.c -- struct zip_error helper functions zip_error.c -- struct zip_error helper functions
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <libzip@nih.at>
@ -99,3 +99,14 @@ _zip_error_set(struct zip_error *err, int ze, int se)
err->sys_err = se; err->sys_err = se;
} }
} }
void
_zip_error_set_from_source(struct zip_error *err, struct zip_source *src)
{
int ze, se;
zip_source_error(src, &ze, &se);
_zip_error_set(err, ze, se);
}

View file

@ -1,6 +1,6 @@
/* /*
zip_error_to_str.c -- get string representation of zip error code zip_error_to_str.c -- get string representation of zip error code
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <libzip@nih.at>
@ -43,7 +43,7 @@
ZIP_EXTERN(int) ZIP_EXTERN(int)
zip_error_to_str(char *buf, size_t len, int ze, int se) zip_error_to_str(char *buf, zip_uint64_t len, int ze, int se)
{ {
const char *zs, *ss; const char *zs, *ss;

View file

@ -44,28 +44,20 @@ zip_fclose(struct zip_file *zf)
{ {
int i, ret; int i, ret;
if (zf->zstr) if (zf->src)
inflateEnd(zf->zstr); zip_source_free(zf->src);
free(zf->buffer);
free(zf->zstr); for (i=0; i<zf->za->nfile; i++) {
if (zf->za) { if (zf->za->file[i] == zf) {
for (i=0; i<zf->za->nfile; i++) { zf->za->file[i] = zf->za->file[zf->za->nfile-1];
if (zf->za->file[i] == zf) { zf->za->nfile--;
zf->za->file[i] = zf->za->file[zf->za->nfile-1]; break;
zf->za->nfile--;
break;
}
}
} }
}
ret = 0; ret = 0;
if (zf->error.zip_err) if (zf->error.zip_err)
ret = zf->error.zip_err; ret = zf->error.zip_err;
else if ((zf->flags & ZIP_ZF_CRC) && (zf->flags & ZIP_ZF_EOF)) {
/* if EOF, compare CRC */
if (zf->crc_orig != zf->crc)
ret = ZIP_ER_CRC;
}
free(zf); free(zf);
return ret; return ret;

62
ext/zip/lib/zip_fdopen.c Normal file
View file

@ -0,0 +1,62 @@
/*
zip_fdopen.c -- open read-only archive from file descriptor
Copyright (C) 2009-2010 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:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN(struct zip *)
zip_fdopen(int fd_orig, int flags, int *zep)
{
int fd;
FILE *fp;
/* We dup() here to avoid messing with the passed in fd.
We could not restore it to the original state in case of error. */
if ((fd=dup(fd_orig)) < 0) {
*zep = ZIP_ER_OPEN;
return NULL;
}
if ((fp=fdopen(fd, "rb")) == NULL) {
close(fd);
*zep = ZIP_ER_OPEN;
return NULL;
}
close(fd_orig);
return _zip_open(NULL, fp, flags, ZIP_AFL_RDONLY, zep);
}

View file

@ -1,6 +1,6 @@
/* /*
zip_filerange_crc.c -- compute CRC32 for a range of a file zip_filerange_crc.c -- compute CRC32 for a range of a file
Copyright (C) 2008-2009 Dieter Baron and Thomas Klausner Copyright (C) 2008 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <libzip@nih.at>

View file

@ -1,6 +1,6 @@
/* /*
zip_fopen.c -- open file in zip archive for reading zip_fopen.c -- open file in zip archive for reading
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <libzip@nih.at>
@ -45,5 +45,5 @@ zip_fopen(struct zip *za, const char *fname, int flags)
if ((idx=zip_name_locate(za, fname, flags)) < 0) if ((idx=zip_name_locate(za, fname, flags)) < 0)
return NULL; return NULL;
return zip_fopen_index(za, idx, flags); return zip_fopen_index_encrypted(za, idx, flags, za->default_password);
} }

View file

@ -0,0 +1,50 @@
/*
zip_fopen_encrypted.c -- open file for reading with password
Copyright (C) 1999-2009 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:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN(struct zip_file *)
zip_fopen_encrypted(struct zip *za, const char *fname, int flags,
const char *password)
{
int idx;
if ((idx=zip_name_locate(za, fname, flags)) < 0)
return NULL;
return zip_fopen_index_encrypted(za, idx, flags, password);
}

View file

@ -1,6 +1,6 @@
/* /*
zip_fopen_index.c -- open file in zip archive for reading by index zip_fopen_index.c -- open file in zip archive for reading by index
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <libzip@nih.at>
@ -39,178 +39,11 @@
#include "zipint.h" #include "zipint.h"
static struct zip_file *_zip_file_new(struct zip *za);
ZIP_EXTERN(struct zip_file *) ZIP_EXTERN(struct zip_file *)
zip_fopen_index(struct zip *za, int fileno, int flags) zip_fopen_index(struct zip *za, zip_uint64_t fileno, int flags)
{ {
int len, ret; return zip_fopen_index_encrypted(za, fileno, flags, za->default_password);
int zfflags;
struct zip_file *zf;
if ((fileno < 0) || (fileno >= za->nentry)) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return NULL;
}
if ((flags & ZIP_FL_UNCHANGED) == 0
&& ZIP_ENTRY_DATA_CHANGED(za->entry+fileno)) {
_zip_error_set(&za->error, ZIP_ER_CHANGED, 0);
return NULL;
}
if (fileno >= za->cdir->nentry) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return NULL;
}
zfflags = 0;
switch (za->cdir->entry[fileno].comp_method) {
case ZIP_CM_STORE:
zfflags |= ZIP_ZF_CRC;
break;
case ZIP_CM_DEFLATE:
if ((flags & ZIP_FL_COMPRESSED) == 0)
zfflags |= ZIP_ZF_CRC | ZIP_ZF_DECOMP;
break;
default:
if ((flags & ZIP_FL_COMPRESSED) == 0) {
_zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
return NULL;
}
break;
}
zf = _zip_file_new(za);
zf->flags = zfflags;
/* zf->name = za->cdir->entry[fileno].filename; */
zf->method = za->cdir->entry[fileno].comp_method;
zf->bytes_left = za->cdir->entry[fileno].uncomp_size;
zf->cbytes_left = za->cdir->entry[fileno].comp_size;
zf->crc_orig = za->cdir->entry[fileno].crc;
if ((zf->fpos=_zip_file_get_offset(za, fileno)) == 0) {
zip_fclose(zf);
return NULL;
}
if ((zf->flags & ZIP_ZF_DECOMP) == 0)
zf->bytes_left = zf->cbytes_left;
else {
if ((zf->buffer=(char *)malloc(BUFSIZE)) == NULL) {
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
zip_fclose(zf);
return NULL;
}
len = _zip_file_fillbuf(zf->buffer, BUFSIZE, zf);
if (len <= 0) {
_zip_error_copy(&za->error, &zf->error);
zip_fclose(zf);
return NULL;
}
if ((zf->zstr = (z_stream *)malloc(sizeof(z_stream))) == NULL) {
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
zip_fclose(zf);
return NULL;
}
zf->zstr->zalloc = Z_NULL;
zf->zstr->zfree = Z_NULL;
zf->zstr->opaque = NULL;
zf->zstr->next_in = (Bytef *)zf->buffer;
zf->zstr->avail_in = len;
/* negative value to tell zlib that there is no header */
if ((ret=inflateInit2(zf->zstr, -MAX_WBITS)) != Z_OK) {
_zip_error_set(&za->error, ZIP_ER_ZLIB, ret);
zip_fclose(zf);
return NULL;
}
}
return zf;
}
int
_zip_file_fillbuf(void *buf, size_t buflen, struct zip_file *zf)
{
int i, j;
if (zf->error.zip_err != ZIP_ER_OK)
return -1;
if ((zf->flags & ZIP_ZF_EOF) || zf->cbytes_left <= 0 || buflen <= 0)
return 0;
if (fseeko(zf->za->zp, zf->fpos, SEEK_SET) < 0) {
_zip_error_set(&zf->error, ZIP_ER_SEEK, errno);
return -1;
}
if (buflen < zf->cbytes_left)
i = buflen;
else
i = zf->cbytes_left;
j = fread(buf, 1, i, zf->za->zp);
if (j == 0) {
_zip_error_set(&zf->error, ZIP_ER_EOF, 0);
j = -1;
}
else if (j < 0)
_zip_error_set(&zf->error, ZIP_ER_READ, errno);
else {
zf->fpos += j;
zf->cbytes_left -= j;
}
return j;
}
static struct zip_file *
_zip_file_new(struct zip *za)
{
struct zip_file *zf, **file;
int n;
if ((zf=(struct zip_file *)malloc(sizeof(struct zip_file))) == NULL) {
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return NULL;
}
if (za->nfile >= za->nfile_alloc-1) {
n = za->nfile_alloc + 10;
file = (struct zip_file **)realloc(za->file,
n*sizeof(struct zip_file *));
if (file == NULL) {
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
free(zf);
return NULL;
}
za->nfile_alloc = n;
za->file = file;
}
za->file[za->nfile++] = zf;
zf->za = za;
_zip_error_init(&zf->error);
zf->flags = 0;
zf->crc = crc32(0L, Z_NULL, 0);
zf->crc_orig = 0;
zf->method = -1;
zf->bytes_left = zf->cbytes_left = 0;
zf->fpos = 0;
zf->buffer = NULL;
zf->zstr = NULL;
return zf;
} }

View file

@ -0,0 +1,191 @@
/*
zip_fopen_index_encrypted.c -- open file for reading by index w/ password
Copyright (C) 1999-2009 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:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include "zipint.h"
static struct zip_file *_zip_file_new(struct zip *za);
ZIP_EXTERN(struct zip_file *)
zip_fopen_index_encrypted(struct zip *za, zip_uint64_t fileno, int flags,
const char *password)
{
struct zip_file *zf;
zip_compression_implementation comp_impl;
zip_encryption_implementation enc_impl;
struct zip_source *src, *s2;
zip_uint64_t start;
struct zip_stat st;
if (fileno >= za->nentry) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return NULL;
}
if ((flags & ZIP_FL_UNCHANGED) == 0
&& ZIP_ENTRY_DATA_CHANGED(za->entry+fileno)) {
_zip_error_set(&za->error, ZIP_ER_CHANGED, 0);
return NULL;
}
if (fileno >= za->cdir->nentry) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return NULL;
}
if (flags & ZIP_FL_ENCRYPTED)
flags |= ZIP_FL_COMPRESSED;
zip_stat_index(za, fileno, flags, &st);
enc_impl = NULL;
if ((flags & ZIP_FL_ENCRYPTED) == 0) {
if (st.encryption_method != ZIP_EM_NONE) {
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) {
_zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
return NULL;
}
}
}
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) {
_zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
return NULL;
}
}
}
if ((start=_zip_file_get_offset(za, fileno)) == 0)
return NULL;
if (st.comp_size == 0) {
if ((src=zip_source_buffer(za, NULL, 0, 0)) == NULL)
return NULL;
}
else {
if ((src=_zip_source_file_or_p(za, NULL, za->zp, start, st.comp_size,
0, &st)) == NULL)
return NULL;
if (enc_impl) {
if ((s2=enc_impl(za, src, ZIP_EM_TRAD_PKWARE, 0,
password)) == NULL) {
zip_source_free(src);
/* XXX: set error (how?) */
return NULL;
}
src = s2;
}
if (comp_impl) {
if ((s2=comp_impl(za, src, za->cdir->entry[fileno].comp_method,
0)) == NULL) {
zip_source_free(src);
/* XXX: set error (how?) */
return NULL;
}
src = s2;
}
if ((flags & ZIP_FL_COMPRESSED) == 0
|| st.comp_method == ZIP_CM_STORE ) {
if ((s2=zip_source_crc(za, src, 1)) == NULL) {
zip_source_free(src);
/* XXX: set error (how?) */
return NULL;
}
src = s2;
}
}
if (zip_source_open(src) < 0) {
_zip_error_set_from_source(&za->error, src);
zip_source_free(src);
return NULL;
}
zf = _zip_file_new(za);
zf->src = src;
return zf;
}
static struct zip_file *
_zip_file_new(struct zip *za)
{
struct zip_file *zf, **file;
int n;
if ((zf=(struct zip_file *)malloc(sizeof(struct zip_file))) == NULL) {
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return NULL;
}
if (za->nfile >= za->nfile_alloc-1) {
n = za->nfile_alloc + 10;
file = (struct zip_file **)realloc(za->file,
n*sizeof(struct zip_file *));
if (file == NULL) {
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
free(zf);
return NULL;
}
za->nfile_alloc = n;
za->file = file;
}
za->file[za->nfile++] = zf;
zf->za = za;
_zip_error_init(&zf->error);
zf->eof = 0;
zf->src = NULL;
return zf;
}

View file

@ -1,6 +1,6 @@
/* /*
zip_fread.c -- read from file zip_fread.c -- read from file
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <libzip@nih.at>
@ -37,12 +37,10 @@
ZIP_EXTERN(ssize_t) ZIP_EXTERN(zip_int64_t)
zip_fread(struct zip_file *zf, void *outbuf, size_t toread) zip_fread(struct zip_file *zf, void *outbuf, zip_uint64_t toread)
{ {
int ret; zip_int64_t n;
size_t out_before, len;
int i;
if (!zf) if (!zf)
return -1; return -1;
@ -50,81 +48,27 @@ zip_fread(struct zip_file *zf, void *outbuf, size_t toread)
if (zf->error.zip_err != 0) if (zf->error.zip_err != 0)
return -1; return -1;
if ((zf->flags & ZIP_ZF_EOF) || (toread == 0)) if (toread > ZIP_INT64_MAX) {
return 0; _zip_error_set(&zf->error, ZIP_ER_INVAL, 0);
return -1;
if (zf->bytes_left == 0) {
zf->flags |= ZIP_ZF_EOF;
if (zf->flags & ZIP_ZF_CRC) {
if (zf->crc != zf->crc_orig) {
_zip_error_set(&zf->error, ZIP_ER_CRC, 0);
return -1;
}
}
return 0;
} }
if ((zf->flags & ZIP_ZF_DECOMP) == 0) { if ((zf->eof) || (toread == 0))
ret = _zip_file_fillbuf(outbuf, toread, zf); return 0;
if (ret > 0) {
if (zf->flags & ZIP_ZF_CRC) if ((n=zip_source_read(zf->src, outbuf, toread)) < 0) {
zf->crc = crc32(zf->crc, (Bytef *)outbuf, ret); _zip_error_set_from_source(&zf->error, zf->src);
zf->bytes_left -= ret; return -1;
}
return ret;
} }
zf->zstr->next_out = (Bytef *)outbuf; /* XXX the following left from the previous PHP port, let's see how to use it now */
/*zf->zstr->next_out = (Bytef *)outbuf;
zf->zstr->avail_out = toread; zf->zstr->avail_out = toread;
out_before = zf->zstr->total_out; out_before = zf->zstr->total_out;*/
/* endless loop until something has been accomplished */ /* endless loop until something has been accomplished */
for (;;) { /*for (;;) {
ret = inflate(zf->zstr, Z_SYNC_FLUSH); ret = inflate(zf->zstr, Z_SYNC_FLUSH);*/
switch (ret) { return n;
case Z_STREAM_END:
if (zf->zstr->total_out == out_before) {
if (zf->crc != zf->crc_orig) {
_zip_error_set(&zf->error, ZIP_ER_CRC, 0);
return -1;
}
else
return 0;
}
/* fallthrough */
case Z_OK:
len = zf->zstr->total_out - out_before;
if (len >= zf->bytes_left || len >= toread) {
if (zf->flags & ZIP_ZF_CRC)
zf->crc = crc32(zf->crc, (Bytef *)outbuf, len);
zf->bytes_left -= len;
return len;
}
break;
case Z_BUF_ERROR:
if (zf->zstr->avail_in == 0) {
i = _zip_file_fillbuf(zf->buffer, BUFSIZE, zf);
if (i == 0) {
_zip_error_set(&zf->error, ZIP_ER_INCONS, 0);
return -1;
}
else if (i < 0)
return -1;
zf->zstr->next_in = (Bytef *)zf->buffer;
zf->zstr->avail_in = i;
continue;
}
/* fallthrough */
case Z_NEED_DICT:
case Z_DATA_ERROR:
case Z_STREAM_ERROR:
case Z_MEM_ERROR:
_zip_error_set(&zf->error, ZIP_ER_ZLIB, ret);
return -1;
}
}
} }

View file

@ -57,7 +57,9 @@ _zip_free(struct zip *za)
if (za->zp) if (za->zp)
fclose(za->zp); fclose(za->zp);
free(za->default_password);
_zip_cdir_free(za->cdir); _zip_cdir_free(za->cdir);
free(za->ch_comment);
if (za->entry) { if (za->entry) {
for (i=0; i<za->nentry; i++) { for (i=0; i<za->nentry; i++) {

View file

@ -42,11 +42,11 @@ zip_get_archive_comment(struct zip *za, int *lenp, int flags)
{ {
if ((flags & ZIP_FL_UNCHANGED) if ((flags & ZIP_FL_UNCHANGED)
|| (za->ch_comment_len == -1)) { || (za->ch_comment_len == -1)) {
if (za->cdir) { if (za->cdir) {
if (lenp != NULL) if (lenp != NULL)
*lenp = za->cdir->comment_len; *lenp = za->cdir->comment_len;
return za->cdir->comment; return za->cdir->comment;
} }
else { else {
if (lenp != NULL) if (lenp != NULL)
*lenp = -1; *lenp = -1;

View file

@ -1,6 +1,6 @@
/* /*
zip_get_archive_flag.c -- get archive global flag zip_get_archive_flag.c -- get archive global flag
Copyright (C) 2008-2009 Dieter Baron and Thomas Klausner Copyright (C) 2008 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <libzip@nih.at>

View file

@ -0,0 +1,46 @@
/*
zip_get_compression_implementation.c -- get compression implementation
Copyright (C) 2009 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:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN(zip_compression_implementation)
zip_get_compression_implementation(zip_uint16_t cm)
{
if (cm == ZIP_CM_DEFLATE)
return zip_source_deflate;
return NULL;
}

View file

@ -0,0 +1,46 @@
/*
zip_get_encryption_implementation.c -- get encryption implementation
Copyright (C) 2009 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:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN(zip_encryption_implementation)
zip_get_encryption_implementation(zip_uint16_t em)
{
if (em == ZIP_EM_TRAD_PKWARE)
return zip_source_pkware;
return NULL;
}

View file

@ -38,9 +38,9 @@
ZIP_EXTERN(const char *) ZIP_EXTERN(const char *)
zip_get_file_comment(struct zip *za, int idx, int *lenp, int flags) zip_get_file_comment(struct zip *za, zip_uint64_t idx, int *lenp, int flags)
{ {
if (idx < 0 || idx >= za->nentry) { if (idx >= za->nentry) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0); _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return NULL; return NULL;
} }

View file

@ -0,0 +1,58 @@
/*
zip_get_file_extra.c -- get file extra field
Copyright (C) 2006-2010 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:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN(const char *)
zip_get_file_extra(struct zip *za, zip_uint64_t idx, int *lenp, int flags)
{
if (idx >= za->nentry) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return NULL;
}
if ((flags & ZIP_FL_UNCHANGED)
|| (za->entry[idx].ch_extra_len == -1)) {
if (lenp != NULL)
*lenp = za->cdir->entry[idx].extrafield_len;
return za->cdir->entry[idx].extrafield;
}
if (lenp != NULL)
*lenp = za->entry[idx].ch_extra_len;
return za->entry[idx].ch_extra;
}

View file

@ -38,7 +38,7 @@
ZIP_EXTERN(const char *) ZIP_EXTERN(const char *)
zip_get_name(struct zip *za, int idx, int flags) zip_get_name(struct zip *za, zip_uint64_t idx, int flags)
{ {
return _zip_get_name(za, idx, flags, &za->error); return _zip_get_name(za, idx, flags, &za->error);
} }
@ -46,9 +46,10 @@ zip_get_name(struct zip *za, int idx, int flags)
const char * const char *
_zip_get_name(struct zip *za, int idx, int flags, struct zip_error *error) _zip_get_name(struct zip *za, zip_uint64_t idx, int flags,
struct zip_error *error)
{ {
if (idx < 0 || idx >= za->nentry) { if (idx >= za->nentry) {
_zip_error_set(error, ZIP_ER_INVAL, 0); _zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL; return NULL;
} }

View file

@ -0,0 +1,52 @@
/*
zip_get_num_entries.c -- get number of entries in archive
Copyright (C) 1999-2011 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:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN(zip_uint64_t)
zip_get_num_entries(struct zip *za, int flags)
{
if (za == NULL)
return -1;
if (flags & ZIP_FL_UNCHANGED) {
if (za->cdir == NULL)
return 0;
return za->cdir->nentry;
}
return za->nentry;
}

View file

@ -1,6 +1,6 @@
/* /*
zip_name_locate.c -- get index by name zip_name_locate.c -- get index by name
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner Copyright (C) 1999-2011 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> 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 3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior products derived from this software without specific prior
written permission. written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@ -55,16 +55,20 @@ _zip_name_locate(struct zip *za, const char *fname, int flags,
const char *fn, *p; const char *fn, *p;
int i, n; int i, n;
if (za == NULL)
return -1;
if (fname == NULL) { if (fname == NULL) {
_zip_error_set(error, ZIP_ER_INVAL, 0); _zip_error_set(error, ZIP_ER_INVAL, 0);
return -1; return -1;
} }
if((flags & ZIP_FL_UNCHANGED) && !za->cdir) { if ((flags & ZIP_FL_UNCHANGED) && za->cdir == NULL) {
return -1; _zip_error_set(error, ZIP_ER_NOENT, 0);
return -1;
} }
cmp = (flags & ZIP_FL_NOCASE) ? strcmpi : strcmp; cmp = (flags & ZIP_FL_NOCASE) ? strcasecmp : strcmp;
n = (flags & ZIP_FL_UNCHANGED) ? za->cdir->nentry : za->nentry; n = (flags & ZIP_FL_UNCHANGED) ? za->cdir->nentry : za->nentry;
for (i=0; i<n; i++) { for (i=0; i<n; i++) {

View file

@ -65,6 +65,7 @@ _zip_new(struct zip_error *error)
za->nfile = za->nfile_alloc = 0; za->nfile = za->nfile_alloc = 0;
za->file = NULL; za->file = NULL;
za->flags = za->ch_flags = 0; za->flags = za->ch_flags = 0;
za->default_password = NULL;
return za; return za;
} }

View file

@ -1,6 +1,6 @@
/* /*
zip_open.c -- open zip archive zip_open.c -- open zip archive by name
Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner Copyright (C) 1999-2011 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <libzip@nih.at>
@ -52,7 +52,7 @@ static int _zip_headercomp(struct zip_dirent *, int,
struct zip_dirent *, int); struct zip_dirent *, int);
static unsigned char *_zip_memmem(const unsigned char *, int, static unsigned char *_zip_memmem(const unsigned char *, int,
const unsigned char *, int); const unsigned char *, int);
static struct zip_cdir *_zip_readcdir(FILE *, unsigned char *, unsigned char *, static struct zip_cdir *_zip_readcdir(FILE *, off_t, unsigned char *, unsigned char *,
int, int, struct zip_error *); int, int, struct zip_error *);
@ -61,24 +61,12 @@ ZIP_EXTERN(struct zip *)
zip_open(const char *fn, int flags, int *zep) zip_open(const char *fn, int flags, int *zep)
{ {
FILE *fp; FILE *fp;
struct zip *za;
struct zip_cdir *cdir;
int i;
off_t len;
if (flags & ZIP_OVERWRITE) {
return _zip_allocate_new(fn, zep);
}
switch (_zip_file_exists(fn, flags, zep)) { switch (_zip_file_exists(fn, flags, zep)) {
case -1: case -1:
if (!(flags & ZIP_OVERWRITE)) { return NULL;
return NULL;
}
case 0: case 0:
return _zip_allocate_new(fn, zep); return _zip_allocate_new(fn, zep);
default: default:
break; break;
} }
@ -88,7 +76,23 @@ zip_open(const char *fn, int flags, int *zep)
return NULL; return NULL;
} }
fseeko(fp, 0, SEEK_END); return _zip_open(fn, fp, flags, 0, zep);
}
struct zip *
_zip_open(const char *fn, FILE *fp, int flags, int aflags, int *zep)
{
struct zip *za;
struct zip_cdir *cdir;
int i;
off_t len;
if (fseeko(fp, 0, SEEK_END) < 0) {
*zep = ZIP_ER_SEEK;
return NULL;
}
len = ftello(fp); len = ftello(fp);
/* treat empty files as empty archives */ /* treat empty files as empty archives */
@ -156,13 +160,13 @@ set_error(int *zep, struct zip_error *err, int ze)
entries, or NULL if unsuccessful. */ entries, or NULL if unsuccessful. */
static struct zip_cdir * static struct zip_cdir *
_zip_readcdir(FILE *fp, unsigned char *buf, unsigned char *eocd, int buflen, _zip_readcdir(FILE *fp, off_t buf_offset, unsigned char *buf, unsigned char *eocd, int buflen,
int flags, struct zip_error *error) int flags, struct zip_error *error)
{ {
struct zip_cdir *cd; struct zip_cdir *cd;
unsigned char *cdp, **bufp; unsigned char *cdp, **bufp;
int i, comlen, nentry; int i, comlen, nentry;
unsigned int left; zip_uint32_t left;
comlen = buf + buflen - eocd - EOCDLEN; comlen = buf + buflen - eocd - EOCDLEN;
if (comlen < 0) { if (comlen < 0) {
@ -196,14 +200,24 @@ _zip_readcdir(FILE *fp, unsigned char *buf, unsigned char *eocd, int buflen,
cd->comment = NULL; cd->comment = NULL;
cd->comment_len = _zip_read2(&cdp); cd->comment_len = _zip_read2(&cdp);
if (((zip_uint64_t)cd->offset)+cd->size > buf_offset + (eocd-buf)) {
/* cdir spans past EOCD record */
_zip_error_set(error, ZIP_ER_INCONS, 0);
cd->nentry = 0;
_zip_cdir_free(cd);
return NULL;
}
if ((comlen < cd->comment_len) || (cd->nentry != i)) { if ((comlen < cd->comment_len) || (cd->nentry != i)) {
_zip_error_set(error, ZIP_ER_NOZIP, 0); _zip_error_set(error, ZIP_ER_NOZIP, 0);
free(cd); cd->nentry = 0;
_zip_cdir_free(cd);
return NULL; return NULL;
} }
if ((flags & ZIP_CHECKCONS) && comlen != cd->comment_len) { if ((flags & ZIP_CHECKCONS) && comlen != cd->comment_len) {
_zip_error_set(error, ZIP_ER_INCONS, 0); _zip_error_set(error, ZIP_ER_INCONS, 0);
free(cd); cd->nentry = 0;
_zip_cdir_free(cd);
return NULL; return NULL;
} }
@ -211,14 +225,15 @@ _zip_readcdir(FILE *fp, unsigned char *buf, unsigned char *eocd, int buflen,
if ((cd->comment=(char *)_zip_memdup(eocd+EOCDLEN, if ((cd->comment=(char *)_zip_memdup(eocd+EOCDLEN,
cd->comment_len, error)) cd->comment_len, error))
== NULL) { == NULL) {
free(cd); cd->nentry = 0;
_zip_cdir_free(cd);
return NULL; return NULL;
} }
} }
if (cd->size < (unsigned int)(eocd-buf)) { if (cd->offset >= buf_offset) {
/* if buffer already read in, use it */ /* if buffer already read in, use it */
cdp = eocd - cd->size; cdp = buf + (cd->offset - buf_offset);
bufp = &cdp; bufp = &cdp;
} }
else { else {
@ -234,20 +249,15 @@ _zip_readcdir(FILE *fp, unsigned char *buf, unsigned char *eocd, int buflen,
_zip_error_set(error, ZIP_ER_SEEK, errno); _zip_error_set(error, ZIP_ER_SEEK, errno);
else else
_zip_error_set(error, ZIP_ER_NOZIP, 0); _zip_error_set(error, ZIP_ER_NOZIP, 0);
free(cd); cd->nentry = 0;
_zip_cdir_free(cd);
return NULL; return NULL;
} }
} }
left = cd->size; left = cd->size;
i=0; i=0;
do { while (i<cd->nentry && left > 0) {
if (i == cd->nentry && left > 0) {
/* Infozip extension for more than 64k entries:
nentries wraps around, size indicates correct EOCD */
_zip_cdir_grow(cd, cd->nentry+0x10000, error);
}
if ((_zip_dirent_read(cd->entry+i, fp, bufp, &left, 0, error)) < 0) { if ((_zip_dirent_read(cd->entry+i, fp, bufp, &left, 0, error)) < 0) {
cd->nentry = i; cd->nentry = i;
_zip_cdir_free(cd); _zip_cdir_free(cd);
@ -255,7 +265,18 @@ _zip_readcdir(FILE *fp, unsigned char *buf, unsigned char *eocd, int buflen,
} }
i++; i++;
} while (i<cd->nentry); if (i == cd->nentry && left > 0) {
/* Infozip extension for more than 64k entries:
nentries wraps around, size indicates correct EOCD */
if (_zip_cdir_grow(cd, cd->nentry+ZIP_UINT16_MAX, error) < 0) {
cd->nentry = i;
_zip_cdir_free(cd);
return NULL;
}
}
}
cd->nentry = i;
return cd; return cd;
} }
@ -434,12 +455,16 @@ _zip_allocate_new(const char *fn, int *zep)
set_error(zep, &error, 0); set_error(zep, &error, 0);
return NULL; return NULL;
} }
za->zn = strdup(fn); if (fn == NULL)
if (!za->zn) { za->zn = NULL;
_zip_free(za); else {
set_error(zep, NULL, ZIP_ER_MEMORY); za->zn = strdup(fn);
return NULL; if (!za->zn) {
_zip_free(za);
set_error(zep, NULL, ZIP_ER_MEMORY);
return NULL;
}
} }
return za; return za;
} }
@ -481,6 +506,7 @@ _zip_find_central_dir(FILE *fp, int flags, int *zep, off_t len)
{ {
struct zip_cdir *cdir, *cdirnew; struct zip_cdir *cdir, *cdirnew;
unsigned char *buf, *match; unsigned char *buf, *match;
off_t buf_offset;
int a, best, buflen, i; int a, best, buflen, i;
struct zip_error zerr; struct zip_error zerr;
@ -490,7 +516,8 @@ _zip_find_central_dir(FILE *fp, int flags, int *zep, off_t len)
set_error(zep, NULL, ZIP_ER_SEEK); set_error(zep, NULL, ZIP_ER_SEEK);
return NULL; return NULL;
} }
buf_offset = ftello(fp);
/* 64k is too much for stack */ /* 64k is too much for stack */
if ((buf=(unsigned char *)malloc(CDBUFSIZE)) == NULL) { if ((buf=(unsigned char *)malloc(CDBUFSIZE)) == NULL) {
set_error(zep, NULL, ZIP_ER_MEMORY); set_error(zep, NULL, ZIP_ER_MEMORY);
@ -516,7 +543,7 @@ _zip_find_central_dir(FILE *fp, int flags, int *zep, off_t len)
/* found match -- check, if good */ /* found match -- check, if good */
/* to avoid finding the same match all over again */ /* to avoid finding the same match all over again */
match++; match++;
if ((cdirnew=_zip_readcdir(fp, buf, match-1, buflen, flags, if ((cdirnew=_zip_readcdir(fp, buf_offset, buf, match-1, buflen, flags,
&zerr)) == NULL) &zerr)) == NULL)
continue; continue;

View file

@ -40,16 +40,21 @@
ZIP_EXTERN(int) ZIP_EXTERN(int)
zip_rename(struct zip *za, int idx, const char *name) zip_rename(struct zip *za, zip_uint64_t idx, const char *name)
{ {
const char *old_name; const char *old_name;
int old_is_dir, new_is_dir; int old_is_dir, new_is_dir;
if (idx >= za->nentry || idx < 0 || name[0] == '\0') { if (idx >= za->nentry || name[0] == '\0') {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0); _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1; return -1;
} }
if (ZIP_IS_RDONLY(za)) {
_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
if ((old_name=zip_get_name(za, idx, 0)) == NULL) if ((old_name=zip_get_name(za, idx, 0)) == NULL)
return -1; return -1;

View file

@ -1,6 +1,6 @@
/* /*
zip_replace.c -- replace file via callback function zip_replace.c -- replace file via callback function
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <libzip@nih.at>
@ -38,9 +38,9 @@
ZIP_EXTERN(int) ZIP_EXTERN(int)
zip_replace(struct zip *za, int idx, struct zip_source *source) zip_replace(struct zip *za, zip_uint64_t idx, struct zip_source *source)
{ {
if (idx < 0 || idx >= za->nentry || source == NULL) { if (idx >= za->nentry || source == NULL) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0); _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1; return -1;
} }
@ -54,11 +54,18 @@ zip_replace(struct zip *za, int idx, struct zip_source *source)
int /* NOTE: Signed due to -1 on error. See zip_add.c for more details. */
_zip_replace(struct zip *za, int idx, const char *name,
zip_int64_t
_zip_replace(struct zip *za, zip_uint64_t idx, const char *name,
struct zip_source *source) struct zip_source *source)
{ {
if (idx == -1) { if (ZIP_IS_RDONLY(za)) {
_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
if (idx == ZIP_UINT64_MAX) {
if (_zip_entry_new(za) == NULL) if (_zip_entry_new(za) == NULL)
return -1; return -1;

View file

@ -1,6 +1,6 @@
/* /*
zip_set_archive_comment.c -- set archive comment zip_set_archive_comment.c -- set archive comment
Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner Copyright (C) 2006-2009 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <libzip@nih.at>
@ -50,6 +50,11 @@ zip_set_archive_comment(struct zip *za, const char *comment, int len)
return -1; return -1;
} }
if (ZIP_IS_RDONLY(za)) {
_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
if (len > 0) { if (len > 0) {
if ((tmpcom=(char *)_zip_memdup(comment, len, &za->error)) == NULL) if ((tmpcom=(char *)_zip_memdup(comment, len, &za->error)) == NULL)
return -1; return -1;

View file

@ -40,10 +40,30 @@
ZIP_EXTERN(int) ZIP_EXTERN(int)
zip_set_archive_flag(struct zip *za, int flag, int value) zip_set_archive_flag(struct zip *za, int flag, int value)
{ {
unsigned int new_flags;
if (value) if (value)
za->ch_flags |= flag; new_flags = za->ch_flags | flag;
else else
za->ch_flags &= ~flag; new_flags = za->ch_flags & ~flag;
if (new_flags == za->ch_flags)
return 0;
if (ZIP_IS_RDONLY(za)) {
_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
if ((flag & ZIP_AFL_RDONLY) && value
&& (za->ch_flags & ZIP_AFL_RDONLY) == 0) {
if (_zip_changed(za, NULL)) {
_zip_error_set(&za->error, ZIP_ER_CHANGED, 0);
return -1;
}
}
za->ch_flags = new_flags;
return 0; return 0;
} }

View file

@ -0,0 +1,62 @@
/*
zip_set_default_password.c -- set default password for decryption
Copyright (C) 2009 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:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#include "zipint.h"
ZIP_EXTERN(int)
zip_set_default_password(struct zip *za, const char *passwd)
{
if (za == NULL)
return -1;
if (za->default_password)
free(za->default_password);
if (passwd) {
if ((za->default_password=strdup(passwd)) == NULL) {
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1;
}
}
else
za->default_password = NULL;
return 0;
}

View file

@ -1,6 +1,6 @@
/* /*
zip_set_file_comment.c -- set comment for file in archive zip_set_file_comment.c -- set comment for file in archive
Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner Copyright (C) 2006-2009 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <libzip@nih.at>
@ -40,17 +40,23 @@
ZIP_EXTERN(int) ZIP_EXTERN(int)
zip_set_file_comment(struct zip *za, int idx, const char *comment, int len) zip_set_file_comment(struct zip *za, zip_uint64_t idx,
const char *comment, int len)
{ {
char *tmpcom; char *tmpcom;
if (idx < 0 || idx >= za->nentry if (idx >= za->nentry
|| len < 0 || len > MAXCOMLEN || len < 0 || len > MAXCOMLEN
|| (len > 0 && comment == NULL)) { || (len > 0 && comment == NULL)) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0); _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1; return -1;
} }
if (ZIP_IS_RDONLY(za)) {
_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
if (len > 0) { if (len > 0) {
if ((tmpcom=(char *)_zip_memdup(comment, len, &za->error)) == NULL) if ((tmpcom=(char *)_zip_memdup(comment, len, &za->error)) == NULL)
return -1; return -1;

View file

@ -0,0 +1,72 @@
/*
zip_set_file_extra.c -- set extra field for file in archive
Copyright (C) 2006-2010 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:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include "zipint.h"
ZIP_EXTERN(int)
zip_set_file_extra(struct zip *za, zip_uint64_t idx,
const char *extra, int len)
{
char *tmpext;
if (idx >= za->nentry
|| len < 0 || len > MAXEXTLEN
|| (len > 0 && extra == NULL)) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if (ZIP_IS_RDONLY(za)) {
_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
if (len > 0) {
if ((tmpext=(char *)_zip_memdup(extra, len, &za->error)) == NULL)
return -1;
}
else
tmpext = NULL;
free(za->entry[idx].ch_extra);
za->entry[idx].ch_extra = tmpext;
za->entry[idx].ch_extra_len = len;
return 0;
}

View file

@ -41,12 +41,12 @@
int int
_zip_set_name(struct zip *za, int idx, const char *name) _zip_set_name(struct zip *za, zip_uint64_t idx, const char *name)
{ {
char *s; char *s;
int i; zip_int64_t i;
if (idx < 0 || idx >= za->nentry || name == NULL) { if (idx >= za->nentry || name == NULL) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0); _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1; return -1;
} }

View file

@ -1,6 +1,6 @@
/* /*
zip_source_buffer.c -- create zip data source from buffer zip_source_buffer.c -- create zip data source from buffer
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <libzip@nih.at>
@ -44,13 +44,12 @@ struct read_data {
int freep; int freep;
}; };
static ssize_t read_data(void *state, void *data, size_t len, static zip_int64_t read_data(void *, void *, zip_uint64_t, enum zip_source_cmd);
enum zip_source_cmd cmd);
ZIP_EXTERN(struct zip_source *) ZIP_EXTERN(struct zip_source *)
zip_source_buffer(struct zip *za, const void *data, off_t len, int freep) zip_source_buffer(struct zip *za, const void *data, zip_uint64_t len, int freep)
{ {
struct read_data *f; struct read_data *f;
struct zip_source *zs; struct zip_source *zs;
@ -58,7 +57,7 @@ zip_source_buffer(struct zip *za, const void *data, off_t len, int freep)
if (za == NULL) if (za == NULL)
return NULL; return NULL;
if (len < 0 || (data == NULL && len > 0)) { if (data == NULL && len > 0) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0); _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return NULL; return NULL;
} }
@ -83,12 +82,12 @@ zip_source_buffer(struct zip *za, const void *data, off_t len, int freep)
static ssize_t static zip_int64_t
read_data(void *state, void *data, size_t len, enum zip_source_cmd cmd) read_data(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd)
{ {
struct read_data *z; struct read_data *z;
char *buf; char *buf;
size_t n; zip_uint64_t n;
z = (struct read_data *)state; z = (struct read_data *)state;
buf = (char *)data; buf = (char *)data;
@ -99,6 +98,8 @@ read_data(void *state, void *data, size_t len, enum zip_source_cmd cmd)
return 0; return 0;
case ZIP_SOURCE_READ: case ZIP_SOURCE_READ:
/* XXX: return error if (len > ZIP_INT64_MAX) */
n = z->end - z->buf; n = z->end - z->buf;
if (n > len) if (n > len)
n = len; n = len;
@ -125,6 +126,11 @@ read_data(void *state, void *data, size_t len, enum zip_source_cmd cmd)
zip_stat_init(st); zip_stat_init(st);
st->mtime = z->mtime; st->mtime = z->mtime;
st->size = z->end - z->data; st->size = z->end - z->data;
st->comp_size = st->size;
st->comp_method = ZIP_CM_STORE;
st->encryption_method = ZIP_EM_NONE;
st->valid = ZIP_STAT_MTIME|ZIP_STAT_SIZE|ZIP_STAT_COMP_SIZE
|ZIP_STAT_COMP_METHOD|ZIP_STAT_ENCRYPTION_METHOD;
return sizeof(*st); return sizeof(*st);
} }

View file

@ -0,0 +1,54 @@
/*
zip_source_close.c -- close zip_source (stop reading)
Copyright (C) 2009 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:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN(void)
zip_source_close(struct zip_source *src)
{
if (!src->is_open)
return;
if (src->src == NULL)
(void)src->cb.f(src->ud, NULL, 0, ZIP_SOURCE_CLOSE);
else {
(void)src->cb.l(src->src, src->ud, NULL, 0, ZIP_SOURCE_CLOSE);
zip_source_close(src->src);
}
src->is_open = 0;
}

View file

@ -0,0 +1,159 @@
/*
zip_source_crc.c -- pass-through source that calculates CRC32 and size
Copyright (C) 2009 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:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#include "zipint.h"
struct crc {
int eof;
int validate;
int e[2];
zip_uint64_t size;
zip_uint32_t crc;
};
static zip_int64_t crc_read(struct zip_source *, void *, void *
, zip_uint64_t, enum zip_source_cmd);
ZIP_EXTERN(struct zip_source *)
zip_source_crc(struct zip *za, struct zip_source *src, int validate)
{
struct crc *ctx;
if (src == NULL) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return NULL;
}
if ((ctx=(struct crc *)malloc(sizeof(*ctx))) == NULL) {
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return NULL;
}
ctx->validate = validate;
return zip_source_layered(za, src, crc_read, ctx);
}
static zip_int64_t
crc_read(struct zip_source *src, void *_ctx, void *data,
zip_uint64_t len, enum zip_source_cmd cmd)
{
struct crc *ctx;
zip_int64_t n;
ctx = (struct crc *)_ctx;
switch (cmd) {
case ZIP_SOURCE_OPEN:
ctx->eof = 0;
ctx->crc = crc32(0, NULL, 0);
ctx->size = 0;
return 0;
case ZIP_SOURCE_READ:
if (ctx->eof || len == 0)
return 0;
if ((n=zip_source_read(src, data, len)) < 0)
return ZIP_SOURCE_ERR_LOWER;
if (n == 0) {
ctx->eof = 1;
if (ctx->validate) {
struct zip_stat st;
if (zip_source_stat(src, &st) < 0)
return ZIP_SOURCE_ERR_LOWER;
if ((st.valid & ZIP_STAT_CRC) && st.crc != ctx->crc) {
ctx->e[0] = ZIP_ER_CRC;
ctx->e[1] = 0;
return -1;
}
if ((st.valid & ZIP_STAT_SIZE) && st.size != ctx->size) {
ctx->e[0] = ZIP_ER_INCONS;
ctx->e[1] = 0;
return -1;
}
}
}
else {
ctx->size += n;
ctx->crc = crc32(ctx->crc, data, n);
}
return n;
case ZIP_SOURCE_CLOSE:
return 0;
case ZIP_SOURCE_STAT:
{
struct zip_stat *st;
st = (struct zip_stat *)data;
if (ctx->eof) {
/* XXX: Set comp_size, comp_method, encryption_method?
After all, this only works for uncompressed data. */
st->size = ctx->size;
st->crc = ctx->crc;
st->valid |= ZIP_STAT_SIZE|ZIP_STAT_CRC;
}
}
return 0;
case ZIP_SOURCE_ERROR:
memcpy(data, ctx->e, sizeof(ctx->e));
return 0;
case ZIP_SOURCE_FREE:
free(ctx);
return 0;
default:
return -1;
}
}

View file

@ -0,0 +1,394 @@
/*
zip_source_deflate.c -- deflate (de)compressoin routines
Copyright (C) 2009 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:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#include "zipint.h"
struct deflate {
int e[2];
int eof;
int mem_level;
zip_uint64_t size;
char buffer[BUFSIZE];
z_stream zstr;
};
static zip_int64_t compress_read(struct zip_source *, struct deflate *,
void *, zip_uint64_t);
static zip_int64_t decompress_read(struct zip_source *, struct deflate *,
void *, zip_uint64_t);
static zip_int64_t deflate_compress(struct zip_source *, void *, void *,
zip_uint64_t, enum zip_source_cmd);
static zip_int64_t deflate_decompress(struct zip_source *, void *, void *,
zip_uint64_t, enum zip_source_cmd);
static void deflate_free(struct deflate *);
ZIP_EXTERN(struct zip_source *)
zip_source_deflate(struct zip *za, struct zip_source *src,
zip_uint16_t cm, int flags)
{
struct deflate *ctx;
struct zip_source *s2;
if (src == NULL || cm != ZIP_CM_DEFLATE) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return NULL;
}
if ((ctx=(struct deflate *)malloc(sizeof(*ctx))) == NULL) {
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return NULL;
}
ctx->e[0] = ctx->e[1] = 0;
ctx->eof = 0;
if (flags & ZIP_CODEC_ENCODE) {
if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0))
ctx->mem_level = TORRENT_MEM_LEVEL;
else
ctx->mem_level = MAX_MEM_LEVEL;
}
if ((s2=zip_source_layered(za, src,
((flags & ZIP_CODEC_ENCODE)
? deflate_compress : deflate_decompress),
ctx)) == NULL) {
deflate_free(ctx);
return NULL;
}
return s2;
}
static zip_int64_t
compress_read(struct zip_source *src, struct deflate *ctx,
void *data, zip_uint64_t len)
{
int end, ret;
zip_int64_t n;
if (ctx->e[0] != 0)
return -1;
if (len == 0)
return 0;
ctx->zstr.next_out = (Bytef *)data;
ctx->zstr.avail_out = len;
end = 0;
while (!end) {
ret = deflate(&ctx->zstr, ctx->eof ? Z_FINISH : 0);
switch (ret) {
case Z_OK:
case Z_STREAM_END:
/* all ok */
if (ctx->zstr.avail_out == 0
|| (ctx->eof && ctx->zstr.avail_in == 0))
end = 1;
break;
case Z_BUF_ERROR:
if (ctx->zstr.avail_in == 0) {
if (ctx->eof) {
end = 1;
break;
}
if ((n=zip_source_read(src, ctx->buffer,
sizeof(ctx->buffer))) < 0) {
zip_source_error(src, ctx->e, ctx->e+1);
end = 1;
break;
}
else if (n == 0) {
ctx->eof = 1;
ctx->size = ctx->zstr.total_in;
/* XXX: check against stat of src? */
}
else {
ctx->zstr.next_in = (Bytef *)ctx->buffer;
ctx->zstr.avail_in = n;
}
continue;
}
/* fallthrough */
case Z_NEED_DICT:
case Z_DATA_ERROR:
case Z_STREAM_ERROR:
case Z_MEM_ERROR:
ctx->e[0] = ZIP_ER_ZLIB;
ctx->e[1] = ret;
end = 1;
break;
}
}
if (ctx->zstr.avail_out < len)
return len - ctx->zstr.avail_out;
return (ctx->e[0] == 0) ? 0 : -1;
}
static zip_int64_t
decompress_read(struct zip_source *src, struct deflate *ctx,
void *data, zip_uint64_t len)
{
int end, ret;
zip_int64_t n;
if (ctx->e[0] != 0)
return -1;
if (len == 0)
return 0;
ctx->zstr.next_out = (Bytef *)data;
ctx->zstr.avail_out = len;
end = 0;
while (!end && ctx->zstr.avail_out) {
ret = inflate(&ctx->zstr, Z_SYNC_FLUSH);
switch (ret) {
case Z_OK:
break;
case Z_STREAM_END:
ctx->eof = 1;
end = 1;
break;
case Z_BUF_ERROR:
if (ctx->zstr.avail_in == 0) {
if (ctx->eof) {
end = 1;
break;
}
if ((n=zip_source_read(src, ctx->buffer,
sizeof(ctx->buffer))) < 0) {
zip_source_error(src, ctx->e, ctx->e+1);
end = 1;
break;
}
else if (n == 0)
ctx->eof = 1;
else {
ctx->zstr.next_in = (Bytef *)ctx->buffer;
ctx->zstr.avail_in = n;
}
continue;
}
/* fallthrough */
case Z_NEED_DICT:
case Z_DATA_ERROR:
case Z_STREAM_ERROR:
case Z_MEM_ERROR:
ctx->e[0] = ZIP_ER_ZLIB;
ctx->e[1] = ret;
end = 1;
break;
}
}
if (ctx->zstr.avail_out < len)
return len - ctx->zstr.avail_out;
return (ctx->e[0] == 0) ? 0 : -1;
}
static zip_int64_t
deflate_compress(struct zip_source *src, void *ud, void *data,
zip_uint64_t len, enum zip_source_cmd cmd)
{
struct deflate *ctx;
int ret;
ctx = (struct deflate *)ud;
switch (cmd) {
case ZIP_SOURCE_OPEN:
ctx->zstr.zalloc = Z_NULL;
ctx->zstr.zfree = Z_NULL;
ctx->zstr.opaque = NULL;
ctx->zstr.avail_in = 0;
ctx->zstr.next_in = NULL;
ctx->zstr.avail_out = 0;
ctx->zstr.next_out = NULL;
/* negative value to tell zlib not to write a header */
if ((ret=deflateInit2(&ctx->zstr, Z_BEST_COMPRESSION, Z_DEFLATED,
-MAX_WBITS, ctx->mem_level,
Z_DEFAULT_STRATEGY)) != Z_OK) {
ctx->e[0] = ZIP_ER_ZLIB;
ctx->e[1] = ret;
return -1;
}
return 0;
case ZIP_SOURCE_READ:
return compress_read(src, ctx, data, len);
case ZIP_SOURCE_CLOSE:
deflateEnd(&ctx->zstr);
return 0;
case ZIP_SOURCE_STAT:
{
struct zip_stat *st;
st = (struct zip_stat *)data;
st->comp_method = ZIP_CM_DEFLATE;
st->valid |= ZIP_STAT_COMP_METHOD;
if (ctx->eof) {
st->comp_size = ctx->size;
st->valid |= ZIP_STAT_COMP_SIZE;
}
else
st->valid &= ~ZIP_STAT_COMP_SIZE;
}
return 0;
case ZIP_SOURCE_ERROR:
memcpy(data, ctx->e, sizeof(int)*2);
return sizeof(int)*2;
case ZIP_SOURCE_FREE:
deflate_free(ctx);
return 0;
default:
ctx->e[0] = ZIP_ER_INVAL;
ctx->e[1] = 0;
return -1;
}
}
static zip_int64_t
deflate_decompress(struct zip_source *src, void *ud, void *data,
zip_uint64_t len, enum zip_source_cmd cmd)
{
struct deflate *ctx;
zip_int64_t n;
int ret;
ctx = (struct deflate *)ud;
switch (cmd) {
case ZIP_SOURCE_OPEN:
if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0)
return ZIP_SOURCE_ERR_LOWER;
ctx->zstr.zalloc = Z_NULL;
ctx->zstr.zfree = Z_NULL;
ctx->zstr.opaque = NULL;
ctx->zstr.next_in = (Bytef *)ctx->buffer;
ctx->zstr.avail_in = n;
/* negative value to tell zlib that there is no header */
if ((ret=inflateInit2(&ctx->zstr, -MAX_WBITS)) != Z_OK) {
ctx->e[0] = ZIP_ER_ZLIB;
ctx->e[1] = ret;
return -1;
}
return 0;
case ZIP_SOURCE_READ:
return decompress_read(src, ctx, data, len);
case ZIP_SOURCE_CLOSE:
inflateEnd(&ctx->zstr);
return 0;
case ZIP_SOURCE_STAT:
{
struct zip_stat *st;
st = (struct zip_stat *)data;
st->comp_method = ZIP_CM_STORE;
if (st->comp_size > 0 && st->size > 0)
st->comp_size = st->size;
}
return 0;
case ZIP_SOURCE_ERROR:
if (len < sizeof(int)*2)
return -1;
memcpy(data, ctx->e, sizeof(int)*2);
return sizeof(int)*2;
case ZIP_SOURCE_FREE:
/* XXX: inflateEnd if close was not called */
free(ctx);
return 0;
default:
ctx->e[0] = ZIP_ER_INVAL;
ctx->e[1] = 0;
return -1;
}
}
static void
deflate_free(struct deflate *ctx)
{
/* XXX: deflateEnd if close was not called */
free(ctx);
}

View file

@ -0,0 +1,87 @@
/*
zip_source_error.c -- get last error from zip_source
Copyright (C) 2009 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:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN(void)
zip_source_error(struct zip_source *src, int *ze, int *se)
{
int e[2];
if (src->src == NULL) {
}
else {
switch (src->error_source) {
case ZIP_LES_NONE:
if (src->src == NULL) {
if (src->cb.f(src->ud, e, sizeof(e), ZIP_SOURCE_ERROR) < 0) {
e[0] = ZIP_ER_INTERNAL;
e[1] = 0;
}
}
else
e[0] = e[1] = 0;
break;
case ZIP_LES_INVAL:
e[0] = ZIP_ER_INVAL;
e[1] = 0;
break;
case ZIP_LES_LOWER:
zip_source_error(src->src, ze, se);
return;
case ZIP_LES_UPPER:
if (src->cb.l(src->src, src->ud, e, sizeof(e),
ZIP_SOURCE_ERROR) < 0) {
e[0] = ZIP_ER_INTERNAL;
e[1] = 0;
}
break;
default:
e[0] = ZIP_ER_INTERNAL;
e[1] = 0;
}
}
if (ze)
*ze = e[0];
if (se)
*se = e[1];
}

View file

@ -41,15 +41,16 @@
ZIP_EXTERN(struct zip_source *) ZIP_EXTERN(struct zip_source *)
zip_source_file(struct zip *za, const char *fname, off_t start, off_t len) zip_source_file(struct zip *za, const char *fname, zip_uint64_t start,
zip_int64_t len)
{ {
if (za == NULL) if (za == NULL)
return NULL; return NULL;
if (fname == NULL || start < 0 || len < -1) { if (fname == NULL || len < -1) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0); _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return NULL; return NULL;
} }
return _zip_source_file_or_p(za, fname, NULL, start, len); return _zip_source_file_or_p(za, fname, NULL, start, len, 1, NULL);
} }

View file

@ -44,19 +44,23 @@
struct read_file { struct read_file {
char *fname; /* name of file to copy from */ char *fname; /* name of file to copy from */
FILE *f; /* file to copy from */ FILE *f; /* file to copy from */
off_t off; /* start offset of */ int closep; /* close f */
off_t len; /* lengt of data to copy */ struct zip_stat st; /* stat information passed in */
off_t remain; /* bytes remaining to be copied */
zip_uint64_t off; /* start offset of */
zip_int64_t len; /* length of data to copy */
zip_int64_t remain; /* bytes remaining to be copied */
int e[2]; /* error codes */ int e[2]; /* error codes */
}; };
static ssize_t read_file(void *state, void *data, size_t len, static zip_int64_t read_file(void *state, void *data, zip_uint64_t len,
enum zip_source_cmd cmd); enum zip_source_cmd cmd);
ZIP_EXTERN(struct zip_source *) ZIP_EXTERN(struct zip_source *)
zip_source_filep(struct zip *za, FILE *file, off_t start, off_t len) zip_source_filep(struct zip *za, FILE *file, zip_uint64_t start,
zip_int64_t len)
{ {
if (za == NULL) if (za == NULL)
return NULL; return NULL;
@ -66,14 +70,15 @@ zip_source_filep(struct zip *za, FILE *file, off_t start, off_t len)
return NULL; return NULL;
} }
return _zip_source_file_or_p(za, NULL, file, start, len); return _zip_source_file_or_p(za, NULL, file, start, len, 1, NULL);
} }
struct zip_source * struct zip_source *
_zip_source_file_or_p(struct zip *za, const char *fname, FILE *file, _zip_source_file_or_p(struct zip *za, const char *fname, FILE *file,
off_t start, off_t len) zip_uint64_t start, zip_int64_t len, int closep,
const struct zip_stat *st)
{ {
struct read_file *f; struct read_file *f;
struct zip_source *zs; struct zip_source *zs;
@ -99,7 +104,12 @@ _zip_source_file_or_p(struct zip *za, const char *fname, FILE *file,
f->f = file; f->f = file;
f->off = start; f->off = start;
f->len = (len ? len : -1); f->len = (len ? len : -1);
f->closep = f->fname ? 1 : closep;
if (st)
memcpy(&f->st, st, sizeof(f->st));
else
zip_stat_init(&f->st);
if ((zs=zip_source_function(za, read_file, f)) == NULL) { if ((zs=zip_source_function(za, read_file, f)) == NULL) {
free(f); free(f);
return NULL; return NULL;
@ -110,8 +120,8 @@ _zip_source_file_or_p(struct zip *za, const char *fname, FILE *file,
static ssize_t static zip_int64_t
read_file(void *state, void *data, size_t len, enum zip_source_cmd cmd) read_file(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd)
{ {
struct read_file *z; struct read_file *z;
char *buf; char *buf;
@ -130,20 +140,33 @@ read_file(void *state, void *data, size_t len, enum zip_source_cmd cmd)
} }
} }
if (fseeko(z->f, z->off, SEEK_SET) < 0) { if (z->closep) {
z->e[0] = ZIP_ER_SEEK; if (fseeko(z->f, (off_t)z->off, SEEK_SET) < 0) {
z->e[1] = errno; z->e[0] = ZIP_ER_SEEK;
return -1; z->e[1] = errno;
return -1;
}
} }
z->remain = z->len; z->remain = z->len;
return 0; return 0;
case ZIP_SOURCE_READ: case ZIP_SOURCE_READ:
/* XXX: return INVAL if len > size_t max */
if (z->remain != -1) if (z->remain != -1)
n = len > z->remain ? z->remain : len; n = len > z->remain ? z->remain : len;
else else
n = len; n = len;
if (!z->closep) {
/* we might share this file with others, so let's be safe */
if (fseeko(z->f, (off_t)(z->off + z->len-z->remain),
SEEK_SET) < 0) {
z->e[0] = ZIP_ER_SEEK;
z->e[1] = errno;
return -1;
}
}
if ((i=fread(buf, 1, n, z->f)) < 0) { if ((i=fread(buf, 1, n, z->f)) < 0) {
z->e[0] = ZIP_ER_READ; z->e[0] = ZIP_ER_READ;
z->e[1] = errno; z->e[1] = errno;
@ -164,34 +187,42 @@ read_file(void *state, void *data, size_t len, enum zip_source_cmd cmd)
case ZIP_SOURCE_STAT: case ZIP_SOURCE_STAT:
{ {
struct zip_stat *st; if (len < sizeof(z->st))
struct stat fst; return -1;
int err;
if (z->st.valid != 0)
memcpy(data, &z->st, sizeof(z->st));
else {
struct zip_stat *st;
struct stat fst;
int err;
if (len < sizeof(*st)) if (z->f)
return -1; err = fstat(fileno(z->f), &fst);
else
err = stat(z->fname, &fst);
if (z->f) if (err != 0) {
err = fstat(fileno(z->f), &fst); z->e[0] = ZIP_ER_READ; /* best match */
else z->e[1] = errno;
err = stat(z->fname, &fst); return -1;
}
if (err != 0) { st = (struct zip_stat *)data;
z->e[0] = ZIP_ER_READ; /* best match */
z->e[1] = errno; zip_stat_init(st);
return -1; st->mtime = fst.st_mtime;
st->valid |= ZIP_STAT_MTIME;
if (z->len != -1) {
st->size = z->len;
st->valid |= ZIP_STAT_SIZE;
}
else if ((fst.st_mode&S_IFMT) == S_IFREG) {
st->size = fst.st_size;
st->valid |= ZIP_STAT_SIZE;
}
} }
return sizeof(z->st);
st = (struct zip_stat *)data;
zip_stat_init(st);
st->mtime = fst.st_mtime;
if (z->len != -1)
st->size = z->len;
else if ((fst.st_mode&S_IFMT) == S_IFREG)
st->size = fst.st_size;
return sizeof(*st);
} }
case ZIP_SOURCE_ERROR: case ZIP_SOURCE_ERROR:
@ -203,8 +234,8 @@ read_file(void *state, void *data, size_t len, enum zip_source_cmd cmd)
case ZIP_SOURCE_FREE: case ZIP_SOURCE_FREE:
free(z->fname); free(z->fname);
if (z->f) if (z->closep && z->f)
fclose(z->f); fclose(z->f);
free(z); free(z);
return 0; return 0;

View file

@ -1,6 +1,6 @@
/* /*
zip_source_free.c -- free zip data source zip_source_free.c -- free zip data source
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <libzip@nih.at>
@ -40,12 +40,20 @@
ZIP_EXTERN(void) ZIP_EXTERN(void)
zip_source_free(struct zip_source *source) zip_source_free(struct zip_source *src)
{ {
if (source == NULL) if (src == NULL)
return; return;
(void)source->f(source->ud, NULL, 0, ZIP_SOURCE_FREE); if (src->is_open)
zip_source_close(src);
free(source); if (src->src == NULL)
(void)src->cb.f(src->ud, NULL, 0, ZIP_SOURCE_FREE);
else {
(void)src->cb.l(src->src, src->ud, NULL, 0, ZIP_SOURCE_FREE);
zip_source_free(src->src);
}
free(src);
} }

View file

@ -1,6 +1,6 @@
/* /*
zip_source_function.c -- create zip data source from callback function zip_source_function.c -- create zip data source from callback function
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <libzip@nih.at>
@ -47,13 +47,32 @@ zip_source_function(struct zip *za, zip_source_callback zcb, void *ud)
if (za == NULL) if (za == NULL)
return NULL; return NULL;
if ((zs=(struct zip_source *)malloc(sizeof(*zs))) == NULL) { if ((zs=_zip_source_new(za)) == NULL)
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return NULL; return NULL;
}
zs->f = zcb; zs->cb.f = zcb;
zs->ud = ud; zs->ud = ud;
return zs; return zs;
} }
struct zip_source *
_zip_source_new(struct zip *za)
{
struct zip_source *src;
if ((src=(struct zip_source *)malloc(sizeof(*src))) == NULL) {
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return NULL;
}
src->src = NULL;
src->cb.f = NULL;
src->ud = NULL;
src->error_source = ZIP_LES_NONE;
src->is_open = 0;
return src;
}

View file

@ -0,0 +1,59 @@
/*
zip_source_layered.c -- create layered source
Copyright (C) 2009 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:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include "zipint.h"
ZIP_EXTERN(struct zip_source *)
zip_source_layered(struct zip *za, struct zip_source *src,
zip_source_layered_callback cb, void *ud)
{
struct zip_source *zs;
if (za == NULL)
return NULL;
if ((zs=_zip_source_new(za)) == NULL)
return NULL;
zs->src = src;
zs->cb.l = cb;
zs->ud = ud;
return zs;
}

View file

@ -0,0 +1,76 @@
/*
zip_source_open.c -- open zip_source (prepare for reading)
Copyright (C) 2009 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:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN(int)
zip_source_open(struct zip_source *src)
{
zip_int64_t ret;
if (src->is_open) {
src->error_source = ZIP_LES_INVAL;
return -1;
}
if (src->src == NULL) {
if (src->cb.f(src->ud, NULL, 0, ZIP_SOURCE_OPEN) < 0)
return -1;
}
else {
if (zip_source_open(src->src) < 0) {
src->error_source = ZIP_LES_LOWER;
return -1;
}
ret = src->cb.l(src->src, src->ud, NULL, 0, ZIP_SOURCE_OPEN);
if (ret < 0) {
(void)zip_source_close(src->src);
if (ret == ZIP_SOURCE_ERR_LOWER)
src->error_source = ZIP_LES_LOWER;
else
src->error_source = ZIP_LES_UPPER;
return -1;
}
}
src->is_open = 1;
return 0;
}

View file

@ -0,0 +1,241 @@
/*
zip_source_pkware.c -- Traditional PKWARE de/encryption routines
Copyright (C) 2009 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:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#include "zipint.h"
struct trad_pkware {
int e[2];
zip_uint32_t key[3];
};
#define HEADERLEN 12
#define KEY0 305419896
#define KEY1 591751049
#define KEY2 878082192
static const uLongf *crc = NULL;
#define CRC32(c, b) (crc[((c) ^ (b)) & 0xff] ^ ((c) >> 8))
static void decrypt(struct trad_pkware *, zip_uint8_t *,
const zip_uint8_t *, zip_uint64_t, int);
static int decrypt_header(struct zip_source *, struct trad_pkware *);
static zip_int64_t pkware_decrypt(struct zip_source *, void *, void *,
zip_uint64_t, enum zip_source_cmd);
static void pkware_free(struct trad_pkware *);
ZIP_EXTERN(struct zip_source *)
zip_source_pkware(struct zip *za, struct zip_source *src,
zip_uint16_t em, int flags, const char *password)
{
struct trad_pkware *ctx;
struct zip_source *s2;
if (password == NULL || src == NULL || em != ZIP_EM_TRAD_PKWARE) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return NULL;
}
if (flags & ZIP_CODEC_ENCODE) {
_zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
return NULL;
}
if (crc == NULL)
crc = get_crc_table();
if ((ctx=(struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) {
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return NULL;
}
ctx->e[0] = ctx->e[1] = 0;
ctx->key[0] = KEY0;
ctx->key[1] = KEY1;
ctx->key[2] = KEY2;
decrypt(ctx, NULL, (const zip_uint8_t *)password, strlen(password), 1);
if ((s2=zip_source_layered(za, src, pkware_decrypt, ctx)) == NULL) {
pkware_free(ctx);
return NULL;
}
return s2;
}
static void
decrypt(struct trad_pkware *ctx, zip_uint8_t *out, const zip_uint8_t *in,
zip_uint64_t len, int update_only)
{
zip_uint16_t tmp;
zip_uint64_t i;
Bytef b;
for (i=0; i<len; i++) {
b = in[i];
if (!update_only) {
/* decrypt next byte */
tmp = ctx->key[2] | 2;
tmp = (tmp * (tmp ^ 1)) >> 8;
b ^= tmp;
}
/* store cleartext */
if (out)
out[i] = b;
/* update keys */
ctx->key[0] = CRC32(ctx->key[0], b);
ctx->key[1] = (ctx->key[1] + (ctx->key[0] & 0xff)) * 134775813 + 1;
b = ctx->key[1] >> 24;
ctx->key[2] = CRC32(ctx->key[2], b);
}
}
static int
decrypt_header(struct zip_source *src, struct trad_pkware *ctx)
{
zip_uint8_t header[HEADERLEN];
struct zip_stat st;
zip_int64_t n;
unsigned short dostime, dosdate;
if ((n=zip_source_read(src, header, HEADERLEN)) < 0) {
zip_source_error(src, ctx->e, ctx->e+1);
return -1;
}
if (n != HEADERLEN) {
ctx->e[0] = ZIP_ER_EOF;
ctx->e[1] = 0;
return -1;
}
decrypt(ctx, header, header, HEADERLEN, 0);
if (zip_source_stat(src, &st) < 0) {
/* stat failed, skip password validation */
return 0;
}
_zip_u2d_time(st.mtime, &dostime, &dosdate);
if (header[HEADERLEN-1] != st.crc>>24
&& header[HEADERLEN-1] != dostime>>8) {
ctx->e[0] = ZIP_ER_WRONGPASSWD;
ctx->e[1] = 0;
return -1;
}
return 0;
}
static zip_int64_t
pkware_decrypt(struct zip_source *src, void *ud, void *data,
zip_uint64_t len, enum zip_source_cmd cmd)
{
struct trad_pkware *ctx;
zip_int64_t n;
ctx = (struct trad_pkware *)ud;
switch (cmd) {
case ZIP_SOURCE_OPEN:
if (decrypt_header(src, ctx) < 0)
return -1;
return 0;
case ZIP_SOURCE_READ:
if ((n=zip_source_read(src, data, len)) < 0)
return ZIP_SOURCE_ERR_LOWER;
decrypt(ud, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n,
0);
return n;
case ZIP_SOURCE_CLOSE:
return 0;
case ZIP_SOURCE_STAT:
{
struct zip_stat *st;
st = (struct zip_stat *)data;
st->encryption_method = ZIP_EM_NONE;
st->valid |= ZIP_STAT_ENCRYPTION_METHOD;
/* XXX: deduce HEADERLEN from size for uncompressed */
if (st->valid & ZIP_STAT_COMP_SIZE)
st->comp_size -= HEADERLEN;
}
return 0;
case ZIP_SOURCE_ERROR:
memcpy(data, ctx->e, sizeof(int)*2);
return sizeof(int)*2;
case ZIP_SOURCE_FREE:
pkware_free(ctx);
return 0;
default:
ctx->e[0] = ZIP_ER_INVAL;
ctx->e[1] = 0;
return -1;
}
}
static void
pkware_free(struct trad_pkware *ctx)
{
free(ctx);
}

View file

@ -0,0 +1,63 @@
/*
zip_source_pop.c -- pop top layer from zip data source
Copyright (C) 2009 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:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include "zipint.h"
ZIP_EXTERN(struct zip_source *)
zip_source_pop(struct zip_source *src)
{
struct zip_source *lower;
if (src == NULL)
return NULL;
lower = src->src;
if (lower == NULL)
zip_source_free(src);
else {
if (src->is_open)
(void)src->cb.l(src, src->ud, NULL, 0, ZIP_SOURCE_CLOSE);
(void)src->cb.l(src, src->ud, NULL, 0, ZIP_SOURCE_FREE);
free(src);
}
return lower;
}

View file

@ -0,0 +1,64 @@
/*
zip_source_read.c -- read data from zip_source
Copyright (C) 2009 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:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN(zip_int64_t)
zip_source_read(struct zip_source *src, void *data, zip_uint64_t len)
{
zip_int64_t ret;
if (!src->is_open || len > ZIP_INT64_MAX || (len > 0 && data == NULL)) {
src->error_source = ZIP_LES_INVAL;
return -1;
}
if (src->src == NULL)
return src->cb.f(src->ud, data, len, ZIP_SOURCE_READ);
ret = src->cb.l(src->src, src->ud, data, len, ZIP_SOURCE_READ);
if (ret < 0) {
if (ret == ZIP_SOURCE_ERR_LOWER)
src->error_source = ZIP_LES_LOWER;
else
src->error_source = ZIP_LES_UPPER;
return -1;
}
return ret;
}

View file

@ -0,0 +1,72 @@
/*
zip_source_stat.c -- get meta information from zip_source
Copyright (C) 2009 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:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN(int)
zip_source_stat(struct zip_source *src, struct zip_stat *st)
{
zip_int64_t ret;
if (st == NULL) {
src->error_source = ZIP_LES_INVAL;
return -1;
}
if (src->src == NULL) {
if (src->cb.f(src->ud, st, sizeof(*st), ZIP_SOURCE_STAT) < 0)
return -1;
return 0;
}
if (zip_source_stat(src->src, st) < 0) {
src->error_source = ZIP_LES_LOWER;
return -1;
}
ret = src->cb.l(src->src, src->ud, st, sizeof(*st), ZIP_SOURCE_STAT);
if (ret < 0) {
if (ret == ZIP_SOURCE_ERR_LOWER)
src->error_source = ZIP_LES_LOWER;
else
src->error_source = ZIP_LES_UPPER;
return -1;
}
return 0;
}

View file

@ -1,6 +1,6 @@
/* /*
zip_source_zip.c -- create data source from zip file zip_source_zip.c -- create data source from zip file
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <libzip@nih.at>
@ -41,17 +41,18 @@
struct read_zip { struct read_zip {
struct zip_file *zf; struct zip_file *zf;
struct zip_stat st; struct zip_stat st;
off_t off, len; zip_uint64_t off;
zip_int64_t len;
}; };
static ssize_t read_zip(void *st, void *data, size_t len, static zip_int64_t read_zip(void *st, void *data, zip_uint64_t len,
enum zip_source_cmd cmd); enum zip_source_cmd cmd);
ZIP_EXTERN(struct zip_source *) ZIP_EXTERN(struct zip_source *)
zip_source_zip(struct zip *za, struct zip *srcza, int srcidx, int flags, zip_source_zip(struct zip *za, struct zip *srcza, zip_uint64_t srcidx,
off_t start, off_t len) int flags, zip_uint64_t start, zip_int64_t len)
{ {
struct zip_error error; struct zip_error error;
struct zip_source *zs; struct zip_source *zs;
@ -62,7 +63,7 @@ zip_source_zip(struct zip *za, struct zip *srcza, int srcidx, int flags,
if (za == NULL) if (za == NULL)
return NULL; return NULL;
if (srcza == NULL || start < 0 || len < -1 || srcidx < 0 || srcidx >= srcza->nentry) { if (srcza == NULL || len < -1 || srcidx < 0 || srcidx >= srcza->nentry) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0); _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return NULL; return NULL;
} }
@ -115,12 +116,13 @@ zip_source_zip(struct zip *za, struct zip *srcza, int srcidx, int flags,
static ssize_t static zip_int64_t
read_zip(void *state, void *data, size_t len, enum zip_source_cmd cmd) read_zip(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd)
{ {
struct read_zip *z; struct read_zip *z;
char b[8192], *buf; char b[8192], *buf;
int i, n; int i;
zip_uint64_t n;
z = (struct read_zip *)state; z = (struct read_zip *)state;
buf = (char *)data; buf = (char *)data;

View file

@ -1,6 +1,6 @@
/* /*
zip_stat_index.c -- get information about file by index zip_stat_index.c -- get information about file by index
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <libzip@nih.at>
@ -38,11 +38,12 @@
ZIP_EXTERN(int) ZIP_EXTERN(int)
zip_stat_index(struct zip *za, int index, int flags, struct zip_stat *st) zip_stat_index(struct zip *za, zip_uint64_t index, int flags,
struct zip_stat *st)
{ {
const char *name; const char *name;
if (index < 0 || index >= za->nentry) { if (index >= za->nentry) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0); _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1; return -1;
} }
@ -53,8 +54,7 @@ zip_stat_index(struct zip *za, int index, int flags, struct zip_stat *st)
if ((flags & ZIP_FL_UNCHANGED) == 0 if ((flags & ZIP_FL_UNCHANGED) == 0
&& ZIP_ENTRY_DATA_CHANGED(za->entry+index)) { && ZIP_ENTRY_DATA_CHANGED(za->entry+index)) {
if (za->entry[index].source->f(za->entry[index].source->ud, if (zip_source_stat(za->entry[index].source, st) < 0) {
st, sizeof(*st), ZIP_SOURCE_STAT) < 0) {
_zip_error_set(&za->error, ZIP_ER_CHANGED, 0); _zip_error_set(&za->error, ZIP_ER_CHANGED, 0);
return -1; return -1;
} }
@ -64,7 +64,9 @@ zip_stat_index(struct zip *za, int index, int flags, struct zip_stat *st)
_zip_error_set(&za->error, ZIP_ER_INVAL, 0); _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1; return -1;
} }
zip_stat_init(st);
st->crc = za->cdir->entry[index].crc; st->crc = za->cdir->entry[index].crc;
st->size = za->cdir->entry[index].uncomp_size; st->size = za->cdir->entry[index].uncomp_size;
st->mtime = za->cdir->entry[index].last_mod; st->mtime = za->cdir->entry[index].last_mod;
@ -80,11 +82,13 @@ zip_stat_index(struct zip *za, int index, int flags, struct zip_stat *st)
} }
else else
st->encryption_method = ZIP_EM_NONE; st->encryption_method = ZIP_EM_NONE;
/* st->bitflags = za->cdir->entry[index].bitflags; */ st->valid = ZIP_STAT_CRC|ZIP_STAT_SIZE|ZIP_STAT_MTIME
|ZIP_STAT_COMP_SIZE|ZIP_STAT_COMP_METHOD|ZIP_STAT_ENCRYPTION_METHOD;
} }
st->index = index; st->index = index;
st->name = name; st->name = name;
st->valid |= ZIP_STAT_INDEX|ZIP_STAT_NAME;
return 0; return 0;
} }

View file

@ -1,6 +1,6 @@
/* /*
zip_stat_init.c -- initialize struct zip_stat. zip_stat_init.c -- initialize struct zip_stat.
Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner Copyright (C) 2006-2009 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <libzip@nih.at>
@ -40,12 +40,13 @@
ZIP_EXTERN(void) ZIP_EXTERN(void)
zip_stat_init(struct zip_stat *st) zip_stat_init(struct zip_stat *st)
{ {
st->valid = 0;
st->name = NULL; st->name = NULL;
st->index = -1; st->index = ZIP_UINT64_MAX;
st->crc = 0; st->crc = 0;
st->mtime = (time_t)-1; st->mtime = (time_t)-1;
st->size = -1; st->size = 0;
st->comp_size = -1; st->comp_size = 0;
st->comp_method = ZIP_CM_STORE; st->comp_method = ZIP_CM_STORE;
st->encryption_method = ZIP_EM_NONE; st->encryption_method = ZIP_EM_NONE;
} }

View file

@ -40,7 +40,7 @@
ZIP_EXTERN(int) ZIP_EXTERN(int)
zip_unchange(struct zip *za, int idx) zip_unchange(struct zip *za, zip_uint64_t idx)
{ {
return _zip_unchange(za, idx, 0); return _zip_unchange(za, idx, 0);
} }
@ -48,11 +48,11 @@ zip_unchange(struct zip *za, int idx)
int int
_zip_unchange(struct zip *za, int idx, int allow_duplicates) _zip_unchange(struct zip *za, zip_uint64_t idx, int allow_duplicates)
{ {
int i; int i;
if (idx < 0 || idx >= za->nentry) { if (idx >= za->nentry) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0); _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1; return -1;
} }
@ -72,6 +72,9 @@ _zip_unchange(struct zip *za, int idx, int allow_duplicates)
za->entry[idx].ch_filename = NULL; za->entry[idx].ch_filename = NULL;
} }
free(za->entry[idx].ch_extra);
za->entry[idx].ch_extra = NULL;
za->entry[idx].ch_extra_len = -1;
free(za->entry[idx].ch_comment); free(za->entry[idx].ch_comment);
za->entry[idx].ch_comment = NULL; za->entry[idx].ch_comment = NULL;
za->entry[idx].ch_comment_len = -1; za->entry[idx].ch_comment_len = -1;

View file

@ -1,6 +1,6 @@
/* /*
zip_unchange_archive.c -- undo global changes to ZIP archive zip_unchange_archive.c -- undo global changes to ZIP archive
Copyright (C) 2006-2009 Dieter Baron and Thomas Klausner Copyright (C) 2006-2008 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <libzip@nih.at>

View file

@ -43,8 +43,7 @@ void
_zip_unchange_data(struct zip_entry *ze) _zip_unchange_data(struct zip_entry *ze)
{ {
if (ze->source) { if (ze->source) {
(void)ze->source->f(ze->source->ud, NULL, 0, ZIP_SOURCE_FREE); zip_source_free(ze->source);
free(ze->source);
ze->source = NULL; ze->source = NULL;
} }

47
ext/zip/lib/zipconf.h Normal file
View file

@ -0,0 +1,47 @@
#ifndef _HAD_ZIPCONF_H
#define _HAD_ZIPCONF_H
/*
zipconf.h -- platform specific include file
This file was generated automatically by ./make_zipconf.sh
based on ../config.h.
*/
#define LIBZIP_VERSION "0.10.1"
#define LIBZIP_VERSION_MAJOR 0
#define LIBZIP_VERSION_MINOR 10
#define LIBZIP_VERSION_MICRO 0
#include <inttypes.h>
typedef int8_t zip_int8_t;
#define ZIP_INT8_MIN INT8_MIN
#define ZIP_INT8_MAX INT8_MAX
typedef uint8_t zip_uint8_t;
#define ZIP_UINT8_MAX UINT8_MAX
typedef int16_t zip_int16_t;
#define ZIP_INT16_MIN INT16_MIN
#define ZIP_INT16_MAX INT16_MAX
typedef uint16_t zip_uint16_t;
#define ZIP_UINT16_MAX UINT16_MAX
typedef int32_t zip_int32_t;
#define ZIP_INT32_MIN INT32_MIN
#define ZIP_INT32_MAX INT32_MAX
typedef uint32_t zip_uint32_t;
#define ZIP_UINT32_MAX UINT32_MAX
typedef int64_t zip_int64_t;
#define ZIP_INT64_MIN INT64_MIN
#define ZIP_INT64_MAX INT64_MAX
typedef uint64_t zip_uint64_t;
#define ZIP_UINT64_MAX UINT64_MAX
#endif /* zipconf.h */

View file

@ -3,7 +3,7 @@
/* /*
zipint.h -- internal declarations. zipint.h -- internal declarations.
Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner Copyright (C) 1999-2011 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <libzip@nih.at>
@ -38,12 +38,35 @@
#include "zip.h" #include "zip.h"
#ifndef HAVE_FSEEKO
#define fseeko(s, o, w) (fseek((s), (long int)(o), (w)))
#endif
#ifndef HAVE_FTELLO
#define ftello(s) ((long)ftell((s)))
#endif
#ifndef HAVE_MKSTEMP
int _zip_mkstemp(char *);
#define mkstemp _zip_mkstemp
#endif
#ifdef PHP_WIN32 #ifdef PHP_WIN32
#include <windows.h> #include <windows.h>
#include <wchar.h> #include <wchar.h>
#define _zip_rename(s, t) \ #define _zip_rename(s, t) \
(!MoveFileExA((s), (t), \ (!MoveFileExA((s), (t), \
MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING)) MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING))
/* for dup(), close(), etc. */
#include <io.h>
#if !defined(HAVE_OPEN)
#if defined(HAVE__OPEN)
#define open(a, b, c) _open((a), (b))
#endif
#endif
#else #else
#define _zip_rename rename #define _zip_rename rename
#endif #endif
@ -52,12 +75,6 @@
# define strcmpi strcasecmp # define strcmpi strcasecmp
#endif #endif
#ifndef HAVE_FSEEKO
#define fseeko(s, o, w) (fseek((s), (long int)(o), (w)))
#endif
#ifndef HAVE_FTELLO
#define ftello(s) ((long)ftell((s)))
#endif
@ -73,22 +90,77 @@
#define LENTRYSIZE 30 #define LENTRYSIZE 30
#undef MAXCOMLEN /* defined as 19 on BSD for max command name */ #undef MAXCOMLEN /* defined as 19 on BSD for max command name */
#define MAXCOMLEN 65536 #define MAXCOMLEN 65536
#define MAXEXTLEN 65536
#define EOCDLEN 22 #define EOCDLEN 22
#define CDBUFSIZE (MAXCOMLEN+EOCDLEN) #define CDBUFSIZE (MAXCOMLEN+EOCDLEN)
#define BUFSIZE 8192 #define BUFSIZE 8192
/* This section contains API that won't materialize like this. It's
placed in the internal section, pending cleanup. */
typedef struct zip_source *(*zip_compression_implementation)(struct zip *,
struct zip_source *,
zip_uint16_t, int);
typedef struct zip_source *(*zip_encryption_implementation)(struct zip *,
struct zip_source *,
zip_uint16_t, int,
const char *);
ZIP_EXTERN(zip_compression_implementation) zip_get_compression_implementation(
zip_uint16_t);
ZIP_EXTERN(zip_encryption_implementation) zip_get_encryption_implementation(
zip_uint16_t);
/* This section contains API that is of limited use until support for
user-supplied compression/encryption implementation is finished.
Thus we will keep it private for now. */
typedef zip_int64_t (*zip_source_layered_callback)(struct zip_source *, void *,
void *, zip_uint64_t,
enum zip_source_cmd);
ZIP_EXTERN(void) zip_source_close(struct zip_source *);
ZIP_EXTERN(struct zip_source *)zip_source_crc(struct zip *, struct zip_source *,
int);
ZIP_EXTERN(struct zip_source *)zip_source_deflate(struct zip *,
struct zip_source *,
zip_uint16_t, int);
ZIP_EXTERN(void) zip_source_error(struct zip_source *, int *, int *);
ZIP_EXTERN(struct zip_source *)zip_source_layered(struct zip *,
struct zip_source *,
zip_source_layered_callback,
void *);
ZIP_EXTERN(int) zip_source_open(struct zip_source *);
ZIP_EXTERN(struct zip_source *)zip_source_pkware(struct zip *,
struct zip_source *,
zip_uint16_t, int,
const char *);
ZIP_EXTERN(zip_int64_t) zip_source_read(struct zip_source *, void *,
zip_uint64_t);
ZIP_EXTERN(int) zip_source_stat(struct zip_source *, struct zip_stat *);
/* This function will probably remain private. It is not needed to
implement compression/encryption routines. (We should probably
rename it to _zip_source_pop.) */
ZIP_EXTERN(struct zip_source *)zip_source_pop(struct zip_source *);
/* state of change of a file in zip archive */ /* state of change of a file in zip archive */
enum zip_state { ZIP_ST_UNCHANGED, ZIP_ST_DELETED, ZIP_ST_REPLACED, enum zip_state { ZIP_ST_UNCHANGED, ZIP_ST_DELETED, ZIP_ST_REPLACED,
ZIP_ST_ADDED, ZIP_ST_RENAMED }; ZIP_ST_ADDED, ZIP_ST_RENAMED };
/* constants for struct zip_file's member flags */ /* error source for layered sources */
#define ZIP_ZF_EOF 1 /* EOF reached */ enum zip_les { ZIP_LES_NONE, ZIP_LES_UPPER, ZIP_LES_LOWER, ZIP_LES_INVAL };
#define ZIP_ZF_DECOMP 2 /* decompress data */
#define ZIP_ZF_CRC 4 /* compute and compare CRC */
/* directory entry: general purpose bit flags */ /* directory entry: general purpose bit flags */
@ -114,12 +186,14 @@ struct zip {
unsigned int flags; /* archive global flags */ unsigned int flags; /* archive global flags */
unsigned int ch_flags; /* changed archive global flags */ unsigned int ch_flags; /* changed archive global flags */
char *default_password; /* password used when no other supplied */
struct zip_cdir *cdir; /* central directory */ struct zip_cdir *cdir; /* central directory */
char *ch_comment; /* changed archive comment */ char *ch_comment; /* changed archive comment */
int ch_comment_len; /* length of changed zip archive int ch_comment_len; /* length of changed zip archive
* comment, -1 if unchanged */ * comment, -1 if unchanged */
int nentry; /* number of entries */ zip_uint64_t nentry; /* number of entries */
int nentry_alloc; /* number of entries allocated */ zip_uint64_t nentry_alloc; /* number of entries allocated */
struct zip_entry *entry; /* entries */ struct zip_entry *entry; /* entries */
int nfile; /* number of opened files within archive */ int nfile; /* number of opened files within archive */
int nfile_alloc; /* number of files allocated */ int nfile_alloc; /* number of files allocated */
@ -131,18 +205,8 @@ struct zip {
struct zip_file { struct zip_file {
struct zip *za; /* zip archive containing this file */ struct zip *za; /* zip archive containing this file */
struct zip_error error; /* error information */ struct zip_error error; /* error information */
int flags; /* -1: eof, >0: error */ int eof;
struct zip_source *src; /* data source */
int method; /* compression method */
off_t fpos; /* position within zip file (fread/fwrite) */
unsigned long bytes_left; /* number of bytes left to read */
unsigned long cbytes_left; /* number of bytes of compressed data left */
unsigned long crc; /* CRC so far */
unsigned long crc_orig; /* CRC recorded in archive */
char *buffer;
z_stream *zstr;
}; };
/* zip archive directory entry (central or local) */ /* zip archive directory entry (central or local) */
@ -183,8 +247,14 @@ struct zip_cdir {
struct zip_source { struct zip_source {
zip_source_callback f; struct zip_source *src;
union {
zip_source_callback f;
zip_source_layered_callback l;
} cb;
void *ud; void *ud;
enum zip_les error_source;
int is_open;
}; };
/* entry in zip archive directory */ /* entry in zip archive directory */
@ -193,6 +263,8 @@ struct zip_entry {
enum zip_state state; enum zip_state state;
struct zip_source *source; struct zip_source *source;
char *ch_filename; char *ch_filename;
char *ch_extra;
int ch_extra_len;
char *ch_comment; char *ch_comment;
int ch_comment_len; int ch_comment_len;
}; };
@ -209,6 +281,8 @@ extern const int _zip_err_type[];
((x)->state == ZIP_ST_REPLACED \ ((x)->state == ZIP_ST_REPLACED \
|| (x)->state == ZIP_ST_ADDED) || (x)->state == ZIP_ST_ADDED)
#define ZIP_IS_RDONLY(za) ((za)->ch_flags & ZIP_AFL_RDONLY)
int _zip_cdir_compute_crc(struct zip *, uLong *); int _zip_cdir_compute_crc(struct zip *, uLong *);
@ -220,7 +294,7 @@ int _zip_cdir_write(struct zip_cdir *, FILE *, struct zip_error *);
void _zip_dirent_finalize(struct zip_dirent *); void _zip_dirent_finalize(struct zip_dirent *);
void _zip_dirent_init(struct zip_dirent *); void _zip_dirent_init(struct zip_dirent *);
int _zip_dirent_read(struct zip_dirent *, FILE *, unsigned char **, int _zip_dirent_read(struct zip_dirent *, FILE *, unsigned char **,
unsigned int *, int, struct zip_error *); zip_uint32_t *, int, struct zip_error *);
void _zip_dirent_torrent_normalize(struct zip_dirent *); void _zip_dirent_torrent_normalize(struct zip_dirent *);
int _zip_dirent_write(struct zip_dirent *, FILE *, int, struct zip_error *); int _zip_dirent_write(struct zip_dirent *, FILE *, int, struct zip_error *);
@ -234,6 +308,7 @@ void _zip_error_fini(struct zip_error *);
void _zip_error_get(struct zip_error *, int *, int *); void _zip_error_get(struct zip_error *, int *, int *);
void _zip_error_init(struct zip_error *); void _zip_error_init(struct zip_error *);
void _zip_error_set(struct zip_error *, int, int); void _zip_error_set(struct zip_error *, int, int);
void _zip_error_set_from_source(struct zip_error *, struct zip_source *);
const char *_zip_error_strerror(struct zip_error *); const char *_zip_error_strerror(struct zip_error *);
int _zip_file_fillbuf(void *, size_t, struct zip_file *); int _zip_file_fillbuf(void *, size_t, struct zip_file *);
@ -241,20 +316,27 @@ unsigned int _zip_file_get_offset(struct zip *, int);
int _zip_filerange_crc(FILE *, off_t, off_t, uLong *, struct zip_error *); int _zip_filerange_crc(FILE *, off_t, off_t, uLong *, struct zip_error *);
struct zip_source *_zip_source_file_or_p(struct zip *, const char *, FILE *, struct zip *_zip_open(const char *, FILE *, int, int, int *);
off_t, off_t);
struct zip_source *_zip_source_file_or_p(struct zip *, const char *, FILE *,
zip_uint64_t, zip_int64_t, int,
const struct zip_stat *);
struct zip_source *_zip_source_new(struct zip *);
int _zip_changed(struct zip *, int *);
void _zip_free(struct zip *); void _zip_free(struct zip *);
const char *_zip_get_name(struct zip *, int, int, struct zip_error *); const char *_zip_get_name(struct zip *, zip_uint64_t, int, struct zip_error *);
int _zip_local_header_read(struct zip *, int); int _zip_local_header_read(struct zip *, int);
void *_zip_memdup(const void *, size_t, struct zip_error *); void *_zip_memdup(const void *, size_t, struct zip_error *);
int _zip_name_locate(struct zip *, const char *, int, struct zip_error *); int _zip_name_locate(struct zip *, const char *, int, struct zip_error *);
struct zip *_zip_new(struct zip_error *); struct zip *_zip_new(struct zip_error *);
unsigned short _zip_read2(unsigned char **); unsigned short _zip_read2(unsigned char **);
unsigned int _zip_read4(unsigned char **); unsigned int _zip_read4(unsigned char **);
int _zip_replace(struct zip *, int, const char *, struct zip_source *); zip_int64_t _zip_replace(struct zip *, zip_uint64_t, const char *,
int _zip_set_name(struct zip *, int, const char *); struct zip_source *);
int _zip_unchange(struct zip *, int, int); int _zip_set_name(struct zip *, zip_uint64_t, const char *);
void _zip_u2d_time(time_t, unsigned short *, unsigned short *);
int _zip_unchange(struct zip *, zip_uint64_t, int);
void _zip_unchange_data(struct zip_entry *); void _zip_unchange_data(struct zip_entry *);
#endif /* zipint.h */ #endif /* zipint.h */