diff options
author | Anatoliy Belsky <ab@php.net> | 2012-06-04 21:30:04 +0200 |
---|---|---|
committer | Anatoliy Belsky <ab@php.net> | 2012-06-07 21:01:31 +0200 |
commit | 335a11b14b35e261c484d44a0e1b5ea9cc758e19 (patch) | |
tree | 515f54cede9e42804b4da1e1ef60d1d9f55bb633 /ext/zip | |
parent | 7cae4ff02c593ed212a363d65c83c38a67a27f0d (diff) | |
download | php-git-335a11b14b35e261c484d44a0e1b5ea9cc758e19.tar.gz |
initial libzip upgrade patch to 0.10.1
Diffstat (limited to 'ext/zip')
64 files changed, 2716 insertions, 691 deletions
diff --git a/ext/zip/config.m4 b/ext/zip/config.m4 index d5c24ce9cf..85f9119f5a 100644 --- a/ext/zip/config.m4 +++ b/ext/zip/config.m4 @@ -89,7 +89,14 @@ yes 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_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,[ ]) PHP_NEW_EXTENSION(zip, php_zip.c zip_stream.c $PHP_ZIP_SOURCES, $ext_shared) diff --git a/ext/zip/config.w32 b/ext/zip/config.w32 index e60a983b3a..b638170807 100644 --- a/ext/zip/config.w32 +++ b/ext/zip/config.w32 @@ -27,7 +27,14 @@ if (PHP_ZIP != "no") { zip_get_archive_comment.c zip_get_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_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); } else { diff --git a/ext/zip/lib/zip.h b/ext/zip/lib/zip.h index 14a57bc582..4a80c9e106 100644 --- a/ext/zip/lib/zip.h +++ b/ext/zip/lib/zip.h @@ -3,7 +3,7 @@ /* 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. The authors can be contacted at <libzip@nih.at> @@ -52,6 +52,8 @@ BEGIN_EXTERN_C() +#include <lib/zipconf.h> + #include <sys/types.h> #include <stdio.h> #include <time.h> @@ -71,10 +73,19 @@ BEGIN_EXTERN_C() #define ZIP_FL_COMPRESSED 4 /* read compressed data */ #define ZIP_FL_UNCHANGED 8 /* use original data, ignoring changes */ #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 */ #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 */ @@ -102,7 +113,10 @@ BEGIN_EXTERN_C() #define ZIP_ER_INCONS 21 /* N Zip archive inconsistent */ #define ZIP_ER_REMOVE 22 /* S Can't remove file */ #define ZIP_ER_DELETED 23 /* N Entry has been deleted */ - +#define ZIP_ER_ENCRNOTSUPP 24 /* N Encryption method not supported */ +#define ZIP_ER_RDONLY 25 /* N Read-only archive */ +#define ZIP_ER_NOPASSWD 26 /* N No password provided */ +#define ZIP_ER_WRONGPASSWD 27 /* N Wrong password provided */ /* type of system error value */ @@ -162,69 +176,99 @@ enum zip_source_cmd { ZIP_SOURCE_FREE /* cleanup and free resources */ }; -typedef ssize_t (*zip_source_callback)(void *state, void *data, - size_t len, enum zip_source_cmd cmd); +#define ZIP_SOURCE_ERR_LOWER -2 + +#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 { + zip_uint64_t valid; /* which fields have valid values */ const char *name; /* name of the file */ - int index; /* index within archive */ - unsigned int crc; /* crc of file data */ + zip_uint64_t index; /* index within archive */ + zip_uint64_t size; /* size of file (uncompressed) */ + zip_uint64_t comp_size; /* size of file (compressed) */ time_t mtime; /* modification time */ - off_t size; /* size of file (uncompressed) */ - off_t comp_size; /* size of file (compressed) */ - unsigned short comp_method; /* compression method used */ - unsigned short encryption_method; /* encryption method used */ + zip_uint32_t crc; /* crc of file data */ + zip_uint16_t comp_method; /* compression method used */ + zip_uint16_t encryption_method; /* encryption method used */ + zip_uint32_t flags; /* reserved for future use */ }; struct zip; struct zip_file; 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(int) zip_add_dir(struct zip *, const char *); +ZIP_EXTERN(zip_int64_t) zip_add(struct zip *, const char *, struct zip_source *); +ZIP_EXTERN(zip_int64_t) zip_add_dir(struct zip *, const char *); 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_get(struct zip *, int *, 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(struct zip *)zip_fdopen(int, int, int *); ZIP_EXTERN(void) zip_file_error_clear(struct zip_file *); ZIP_EXTERN(void) zip_file_error_get(struct zip_file *, int *, int *); 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_index(struct zip *, int, int); -ZIP_EXTERN(ssize_t) zip_fread(struct zip_file *, void *, size_t); +ZIP_EXTERN(struct) zip_file *zip_fopen(struct zip *, const char *, int); +ZIP_EXTERN(struct) zip_file *zip_fopen_encrypted(struct zip *, const char *, + 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(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_name(struct zip *, int, int); -ZIP_EXTERN(int) zip_get_num_files(struct zip *); +ZIP_EXTERN(const char *)zip_get_file_comment(struct zip *, zip_uint64_t, + int *, int); +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(struct zip *)zip_open(const char *, int, int *); -ZIP_EXTERN(int) zip_rename(struct zip *, int, const char *); -ZIP_EXTERN(int) zip_replace(struct zip *, int, struct zip_source *); +ZIP_EXTERN(int) zip_rename(struct zip *, zip_uint64_t, const char *); +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_flag(struct zip *, int, int); -ZIP_EXTERN(int) zip_set_file_comment(struct zip *, int, const char *, int); -ZIP_EXTERN(struct zip_source *)zip_source_buffer(struct zip *, const void *, - off_t, int); -ZIP_EXTERN(struct zip_source *)zip_source_file(struct zip *, const char *, - off_t, off_t); -ZIP_EXTERN(struct zip_source *)zip_source_filep(struct zip *, FILE *, - off_t, off_t); +ZIP_EXTERN(int) zip_set_default_password(struct zip *, const char *); +ZIP_EXTERN(int) zip_set_file_comment(struct zip *, zip_uint64_t, + const char *, int); +ZIP_EXTERN(int) zip_set_file_extra(struct zip *, zip_uint64_t, + const char *, int); +ZIP_EXTERN(struct) zip_source *zip_source_buffer(struct zip *, const void *, + 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(struct zip_source *)zip_source_function(struct zip *, zip_source_callback, void *); 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_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(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_archive(struct zip *); diff --git a/ext/zip/lib/zip_add.c b/ext/zip/lib/zip_add.c index 85d5997911..6067abbac4 100644 --- a/ext/zip/lib/zip_add.c +++ b/ext/zip/lib/zip_add.c @@ -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) { if (name == NULL || source == NULL) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return -1; } - - return _zip_replace(za, -1, name, source); + + return _zip_replace(za, ZIP_UINT64_MAX, name, source); } diff --git a/ext/zip/lib/zip_add_dir.c b/ext/zip/lib/zip_add_dir.c index 9b23425194..0a9d7f4863 100644 --- a/ext/zip/lib/zip_add_dir.c +++ b/ext/zip/lib/zip_add_dir.c @@ -1,6 +1,6 @@ /* 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. 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) { - int len, ret; + int len; + zip_int64_t ret; char *s; struct zip_source *source; + if (ZIP_IS_RDONLY(za)) { + _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); + return -1; + } + if (name == NULL) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return -1; diff --git a/ext/zip/lib/zip_close.c b/ext/zip/lib/zip_close.c index 0796f27462..fc1ad02d52 100644 --- a/ext/zip/lib/zip_close.c +++ b/ext/zip/lib/zip_close.c @@ -1,6 +1,6 @@ /* 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. The authors can be contacted at <libzip@nih.at> @@ -33,26 +33,28 @@ +#include "zipint.h" + #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif #include <sys/types.h> #include <sys/stat.h> - -#include "zipint.h" +#ifdef PHP_WIN32 +#include <io.h> +#include <fcntl.h> +#endif static int add_data(struct zip *, struct zip_source *, struct zip_dirent *, 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_source(struct zip *, struct zip_source *, 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_changed(struct zip *, int *); static char *_zip_create_temp_output(struct zip *, FILE **); static int _zip_torrentzip_cmp(const void *, const void *); @@ -72,7 +74,9 @@ zip_close(struct zip *za) int i, j, error; char *temp; FILE *out; +#ifndef PHP_WIN32 mode_t mask; +#endif struct zip_cdir *cd; struct zip_dirent de; struct filelist *filelist; @@ -99,7 +103,7 @@ zip_close(struct zip *za) } _zip_free(za); return 0; - } + } if ((filelist=(struct filelist *)malloc(sizeof(filelist[0])*survivors)) == NULL) @@ -126,11 +130,11 @@ zip_close(struct zip *za) cd->comment_len = TORRENT_SIG_LEN + TORRENT_CRC_LEN; } else if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, ZIP_FL_UNCHANGED) == 0) { - if (_zip_cdir_set_comment(cd, za) == -1) { - _zip_cdir_free(cd); + if (_zip_cdir_set_comment(cd, za) == -1) { + _zip_cdir_free(cd); free(filelist); - return -1; - } + return -1; + } } if ((temp=_zip_create_temp_output(za, &out)) == NULL) { @@ -198,8 +202,7 @@ zip_close(struct zip *za) error = 1; 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) { de.crc = za->cdir->entry[i].crc; 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; } + 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 && za->entry[i].ch_comment_len != -1) { /* as the rest of cd entries, its malloc/free is done by za */ @@ -234,16 +253,22 @@ zip_close(struct zip *za) zs = NULL; if (!ZIP_ENTRY_DATA_CHANGED(za->entry+i)) { - if ((zs=zip_source_zip(za, za, i, ZIP_FL_RECOMPRESS, 0, -1)) == NULL) { - error = 1; - break; - } + if ((zs=zip_source_zip(za, za, i, ZIP_FL_RECOMPRESS, 0, -1)) + == NULL) { + error = 1; + break; + } } if (add_data(za, zs ? zs : za->entry[i].source, &de, out) < 0) { error = 1; + if (zs) + zip_source_free(zs); break; } + if (zs) + zip_source_free(zs); + cd->entry[j].last_mod = de.last_mod; cd->entry[j].comp_method = de.comp_method; cd->entry[j].comp_size = de.comp_size; @@ -307,9 +332,11 @@ zip_close(struct zip *za) } return -1; } +#ifndef PHP_WIN32 mask = umask(0); umask(mask); chmod(za->zn, 0666&~mask); +#endif if (za->ch_comment) free(za->ch_comment); @@ -322,23 +349,17 @@ zip_close(struct zip *za) 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; - zip_source_callback cb; - void *ud; + off_t offstart, offdata, offend; struct zip_stat st; - - cb = zs->f; - ud = zs->ud; - - if (cb(ud, &st, sizeof(st), ZIP_SOURCE_STAT) < (ssize_t)sizeof(st)) { - ch_set_error(&za->error, cb, ud); - return -1; - } - - if (cb(ud, NULL, 0, ZIP_SOURCE_OPEN) < 0) { - ch_set_error(&za->error, cb, ud); + struct zip_source *s2; + zip_compression_implementation comp_impl; + int ret; + + if (zip_source_stat(src, &st) < 0) { + _zip_error_set_from_source(&za->error, src); 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) return -1; - if (st.comp_method != ZIP_CM_STORE) { - if (add_data_comp(cb, ud, &st, ft, &za->error) < 0) - return -1; + if ((s2=zip_source_crc(za, src, 0)) == NULL) { + zip_source_pop(s2); + return -1; } - else { - if (add_data_uncomp(za, cb, ud, &st, ft) < 0) + + /* 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 (cb(ud, NULL, 0, ZIP_SOURCE_CLOSE) < 0) { - ch_set_error(&za->error, cb, ud); + if (ret < 0) return -1; - } offend = ftello(ft); @@ -368,19 +419,18 @@ add_data(struct zip *za, struct zip_source *zs, struct zip_dirent *de, FILE *ft) return -1; } - de->last_mod = st.mtime; de->comp_method = st.comp_method; de->crc = st.crc; 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)) _zip_dirent_torrent_normalize(de); if (_zip_dirent_write(de, ft, 1, &za->error) < 0) return -1; - + if (fseeko(ft, offend, SEEK_SET) < 0) { _zip_error_set(&za->error, ZIP_ER_SEEK, errno); return -1; @@ -392,133 +442,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 copy_data(FILE *fs, off_t len, FILE *ft, struct zip_error *error) { char buf[BUFSIZE]; @@ -552,6 +475,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 write_cdir(struct zip *za, struct zip_cdir *cd, FILE *out) { off_t offset; @@ -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) { int changed, i, survivors; @@ -626,13 +583,15 @@ _zip_changed(struct zip *za, int *survivorsp) for (i=0; i<za->nentry; i++) { if ((za->entry[i].state != ZIP_ST_UNCHANGED) + || (za->entry[i].ch_extra_len != -1) || (za->entry[i].ch_comment_len != -1)) changed = 1; if (za->entry[i].state != ZIP_ST_DELETED) survivors++; } - *survivorsp = survivors; + if (survivorsp) + *survivorsp = survivors; return changed; } @@ -668,6 +627,10 @@ _zip_create_temp_output(struct zip *za, FILE **outp) return NULL; } #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 ); #endif diff --git a/ext/zip/lib/zip_delete.c b/ext/zip/lib/zip_delete.c index 4591ff7f86..da3e65b28a 100644 --- a/ext/zip/lib/zip_delete.c +++ b/ext/zip/lib/zip_delete.c @@ -1,6 +1,6 @@ /* 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. The authors can be contacted at <libzip@nih.at> @@ -38,13 +38,18 @@ 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) { _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; + } + /* allow duplicate file names, because the file will * be removed directly afterwards */ if (_zip_unchange(za, idx, 1) != 0) diff --git a/ext/zip/lib/zip_dirent.c b/ext/zip/lib/zip_dirent.c index 59f8ab0af9..6cb9ee3ee5 100644 --- a/ext/zip/lib/zip_dirent.c +++ b/ext/zip/lib/zip_dirent.c @@ -45,7 +45,6 @@ static time_t _zip_d2u_time(int, int); static char *_zip_readfpstr(FILE *, unsigned 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_write4(unsigned int, FILE *); @@ -213,13 +212,13 @@ _zip_dirent_init(struct zip_dirent *de) int _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) { unsigned char buf[CDENTRYSIZE]; unsigned char *cur; unsigned short dostime, dosdate; - unsigned int size; + zip_uint32_t size; if (local) size = LENTRYSIZE; @@ -475,6 +474,8 @@ _zip_d2u_time(int dtime, int ddate) { struct tm tm = {0}; + memset(&tm, 0, sizeof(tm)); + /* let mktime decide if DST is in effect */ 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) { struct tm *tm; diff --git a/ext/zip/lib/zip_entry_free.c b/ext/zip/lib/zip_entry_free.c index c50c9434bd..e8a77707f0 100644 --- a/ext/zip/lib/zip_entry_free.c +++ b/ext/zip/lib/zip_entry_free.c @@ -44,6 +44,9 @@ _zip_entry_free(struct zip_entry *ze) { free(ze->ch_filename); ze->ch_filename = NULL; + free(ze->ch_extra); + ze->ch_extra = NULL; + ze->ch_extra_len = -1; free(ze->ch_comment); ze->ch_comment = NULL; ze->ch_comment_len = -1; diff --git a/ext/zip/lib/zip_entry_new.c b/ext/zip/lib/zip_entry_new.c index 7059b1b060..ad5d59975a 100644 --- a/ext/zip/lib/zip_entry_new.c +++ b/ext/zip/lib/zip_entry_new.c @@ -1,6 +1,6 @@ /* 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. The authors can be contacted at <libzip@nih.at> @@ -46,20 +46,21 @@ _zip_entry_new(struct zip *za) if (!za) { ze = (struct zip_entry *)malloc(sizeof(struct zip_entry)); if (!ze) { - _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); return NULL; } } else { - if (za->nentry >= za->nentry_alloc-1) { + if (za->nentry+1 >= za->nentry_alloc) { + struct zip_entry *rentries; za->nentry_alloc += 16; - za->entry = (struct zip_entry *)realloc(za->entry, - sizeof(struct zip_entry) - * za->nentry_alloc); - if (!za->entry) { + rentries = (struct zip_entry *)realloc(za->entry, + sizeof(struct zip_entry) + * za->nentry_alloc); + if (!rentries) { _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); return NULL; } + za->entry = rentries; } ze = za->entry+za->nentry; } @@ -67,6 +68,8 @@ _zip_entry_new(struct zip *za) ze->state = ZIP_ST_UNCHANGED; ze->ch_filename = NULL; + ze->ch_extra = NULL; + ze->ch_extra_len = -1; ze->ch_comment = NULL; ze->ch_comment_len = -1; ze->source = NULL; diff --git a/ext/zip/lib/zip_err_str.c b/ext/zip/lib/zip_err_str.c index 3fcdf1738a..8fb60036e0 100644 --- a/ext/zip/lib/zip_err_str.c +++ b/ext/zip/lib/zip_err_str.c @@ -32,6 +32,10 @@ const char * const _zip_err_str[] = { "Zip archive inconsistent", "Can't remove file", "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]); @@ -65,4 +69,8 @@ const int _zip_err_type[] = { N, S, N, + N, + N, + N, + N, }; diff --git a/ext/zip/lib/zip_error.c b/ext/zip/lib/zip_error.c index aab7079456..b8d907abf4 100644 --- a/ext/zip/lib/zip_error.c +++ b/ext/zip/lib/zip_error.c @@ -1,6 +1,6 @@ /* 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. 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; } } + + + +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); +} diff --git a/ext/zip/lib/zip_error_to_str.c b/ext/zip/lib/zip_error_to_str.c index 4dea4d667a..bafe74335a 100644 --- a/ext/zip/lib/zip_error_to_str.c +++ b/ext/zip/lib/zip_error_to_str.c @@ -1,6 +1,6 @@ /* 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. The authors can be contacted at <libzip@nih.at> @@ -43,7 +43,7 @@ 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; diff --git a/ext/zip/lib/zip_fclose.c b/ext/zip/lib/zip_fclose.c index 8f062d9d09..eb55ddbcea 100644 --- a/ext/zip/lib/zip_fclose.c +++ b/ext/zip/lib/zip_fclose.c @@ -44,28 +44,20 @@ zip_fclose(struct zip_file *zf) { int i, ret; - if (zf->zstr) - inflateEnd(zf->zstr); - free(zf->buffer); - free(zf->zstr); - if (zf->za) { - for (i=0; i<zf->za->nfile; i++) { - if (zf->za->file[i] == zf) { - zf->za->file[i] = zf->za->file[zf->za->nfile-1]; - zf->za->nfile--; - break; - } - } + if (zf->src) + zip_source_free(zf->src); + + for (i=0; i<zf->za->nfile; i++) { + if (zf->za->file[i] == zf) { + zf->za->file[i] = zf->za->file[zf->za->nfile-1]; + zf->za->nfile--; + break; } + } ret = 0; if (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); return ret; diff --git a/ext/zip/lib/zip_fdopen.c b/ext/zip/lib/zip_fdopen.c new file mode 100644 index 0000000000..df70f27561 --- /dev/null +++ b/ext/zip/lib/zip_fdopen.c @@ -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); +} diff --git a/ext/zip/lib/zip_filerange_crc.c b/ext/zip/lib/zip_filerange_crc.c index c6890987b1..4d1ad56692 100644 --- a/ext/zip/lib/zip_filerange_crc.c +++ b/ext/zip/lib/zip_filerange_crc.c @@ -1,6 +1,6 @@ /* 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. The authors can be contacted at <libzip@nih.at> diff --git a/ext/zip/lib/zip_fopen.c b/ext/zip/lib/zip_fopen.c index b4b76049f4..f62adbbf92 100644 --- a/ext/zip/lib/zip_fopen.c +++ b/ext/zip/lib/zip_fopen.c @@ -1,6 +1,6 @@ /* 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. 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) return NULL; - return zip_fopen_index(za, idx, flags); + return zip_fopen_index_encrypted(za, idx, flags, za->default_password); } diff --git a/ext/zip/lib/zip_fopen_encrypted.c b/ext/zip/lib/zip_fopen_encrypted.c new file mode 100644 index 0000000000..8aba062567 --- /dev/null +++ b/ext/zip/lib/zip_fopen_encrypted.c @@ -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); +} diff --git a/ext/zip/lib/zip_fopen_index.c b/ext/zip/lib/zip_fopen_index.c index 1e7e419897..5c777ee0ff 100644 --- a/ext/zip/lib/zip_fopen_index.c +++ b/ext/zip/lib/zip_fopen_index.c @@ -1,6 +1,6 @@ /* 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. The authors can be contacted at <libzip@nih.at> @@ -39,178 +39,11 @@ #include "zipint.h" -static struct zip_file *_zip_file_new(struct zip *za); 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; - 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; + return zip_fopen_index_encrypted(za, fileno, flags, za->default_password); } diff --git a/ext/zip/lib/zip_fopen_index_encrypted.c b/ext/zip/lib/zip_fopen_index_encrypted.c new file mode 100644 index 0000000000..988a78fe03 --- /dev/null +++ b/ext/zip/lib/zip_fopen_index_encrypted.c @@ -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; +} diff --git a/ext/zip/lib/zip_fread.c b/ext/zip/lib/zip_fread.c index 00a6bdc4e0..4c828a8433 100644 --- a/ext/zip/lib/zip_fread.c +++ b/ext/zip/lib/zip_fread.c @@ -1,6 +1,6 @@ /* 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. The authors can be contacted at <libzip@nih.at> @@ -37,12 +37,10 @@ -ZIP_EXTERN(ssize_t) -zip_fread(struct zip_file *zf, void *outbuf, size_t toread) +ZIP_EXTERN(zip_int64_t) +zip_fread(struct zip_file *zf, void *outbuf, zip_uint64_t toread) { - int ret; - size_t out_before, len; - int i; + zip_int64_t n; if (!zf) return -1; @@ -50,81 +48,27 @@ zip_fread(struct zip_file *zf, void *outbuf, size_t toread) if (zf->error.zip_err != 0) return -1; - if ((zf->flags & ZIP_ZF_EOF) || (toread == 0)) - return 0; + if (toread > ZIP_INT64_MAX) { + _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; - } - } + if ((zf->eof) || (toread == 0)) return 0; - } - if ((zf->flags & ZIP_ZF_DECOMP) == 0) { - ret = _zip_file_fillbuf(outbuf, toread, zf); - if (ret > 0) { - if (zf->flags & ZIP_ZF_CRC) - zf->crc = crc32(zf->crc, (Bytef *)outbuf, ret); - zf->bytes_left -= ret; - } - return ret; + if ((n=zip_source_read(zf->src, outbuf, toread)) < 0) { + _zip_error_set_from_source(&zf->error, zf->src); + return -1; } - 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; - out_before = zf->zstr->total_out; + out_before = zf->zstr->total_out;*/ /* endless loop until something has been accomplished */ - for (;;) { - ret = inflate(zf->zstr, Z_SYNC_FLUSH); + /*for (;;) { + ret = inflate(zf->zstr, Z_SYNC_FLUSH);*/ - switch (ret) { - 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; - } - } + return n; } diff --git a/ext/zip/lib/zip_free.c b/ext/zip/lib/zip_free.c index 76c3a9673f..9932c14fec 100644 --- a/ext/zip/lib/zip_free.c +++ b/ext/zip/lib/zip_free.c @@ -57,7 +57,9 @@ _zip_free(struct zip *za) if (za->zp) fclose(za->zp); + free(za->default_password); _zip_cdir_free(za->cdir); + free(za->ch_comment); if (za->entry) { for (i=0; i<za->nentry; i++) { diff --git a/ext/zip/lib/zip_get_archive_comment.c b/ext/zip/lib/zip_get_archive_comment.c index ed1324fd5b..fe97e6e8c1 100644 --- a/ext/zip/lib/zip_get_archive_comment.c +++ b/ext/zip/lib/zip_get_archive_comment.c @@ -42,11 +42,11 @@ zip_get_archive_comment(struct zip *za, int *lenp, int flags) { if ((flags & ZIP_FL_UNCHANGED) || (za->ch_comment_len == -1)) { - if (za->cdir) { - if (lenp != NULL) - *lenp = za->cdir->comment_len; - return za->cdir->comment; - } + if (za->cdir) { + if (lenp != NULL) + *lenp = za->cdir->comment_len; + return za->cdir->comment; + } else { if (lenp != NULL) *lenp = -1; diff --git a/ext/zip/lib/zip_get_archive_flag.c b/ext/zip/lib/zip_get_archive_flag.c index a595c51f59..2d46aa39ff 100644 --- a/ext/zip/lib/zip_get_archive_flag.c +++ b/ext/zip/lib/zip_get_archive_flag.c @@ -1,6 +1,6 @@ /* 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. The authors can be contacted at <libzip@nih.at> diff --git a/ext/zip/lib/zip_get_compression_implementation.c b/ext/zip/lib/zip_get_compression_implementation.c new file mode 100644 index 0000000000..197cd49635 --- /dev/null +++ b/ext/zip/lib/zip_get_compression_implementation.c @@ -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; +} diff --git a/ext/zip/lib/zip_get_encryption_implementation.c b/ext/zip/lib/zip_get_encryption_implementation.c new file mode 100644 index 0000000000..783d538d3f --- /dev/null +++ b/ext/zip/lib/zip_get_encryption_implementation.c @@ -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; +} diff --git a/ext/zip/lib/zip_get_file_comment.c b/ext/zip/lib/zip_get_file_comment.c index 57dd9028bc..43c1520e1d 100644 --- a/ext/zip/lib/zip_get_file_comment.c +++ b/ext/zip/lib/zip_get_file_comment.c @@ -38,9 +38,9 @@ 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); return NULL; } diff --git a/ext/zip/lib/zip_get_file_extra.c b/ext/zip/lib/zip_get_file_extra.c new file mode 100644 index 0000000000..a27edd8ee9 --- /dev/null +++ b/ext/zip/lib/zip_get_file_extra.c @@ -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; +} diff --git a/ext/zip/lib/zip_get_name.c b/ext/zip/lib/zip_get_name.c index b58d972058..945e24e150 100644 --- a/ext/zip/lib/zip_get_name.c +++ b/ext/zip/lib/zip_get_name.c @@ -38,7 +38,7 @@ 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); } @@ -46,9 +46,10 @@ zip_get_name(struct zip *za, int idx, int flags) 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); return NULL; } diff --git a/ext/zip/lib/zip_get_num_entries.c b/ext/zip/lib/zip_get_num_entries.c new file mode 100644 index 0000000000..dd392e9095 --- /dev/null +++ b/ext/zip/lib/zip_get_num_entries.c @@ -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; +} diff --git a/ext/zip/lib/zip_name_locate.c b/ext/zip/lib/zip_name_locate.c index 96c4f937e0..08d5b1fbf8 100644 --- a/ext/zip/lib/zip_name_locate.c +++ b/ext/zip/lib/zip_name_locate.c @@ -1,6 +1,6 @@ /* 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. The authors can be contacted at <libzip@nih.at> @@ -17,7 +17,7 @@ 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -55,16 +55,20 @@ _zip_name_locate(struct zip *za, const char *fname, int flags, const char *fn, *p; int i, n; + if (za == NULL) + return -1; + if (fname == NULL) { _zip_error_set(error, ZIP_ER_INVAL, 0); return -1; } - if((flags & ZIP_FL_UNCHANGED) && !za->cdir) { - return -1; + if ((flags & ZIP_FL_UNCHANGED) && za->cdir == NULL) { + _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; for (i=0; i<n; i++) { diff --git a/ext/zip/lib/zip_new.c b/ext/zip/lib/zip_new.c index 3e8ccee644..7ce1237cdb 100644 --- a/ext/zip/lib/zip_new.c +++ b/ext/zip/lib/zip_new.c @@ -65,6 +65,7 @@ _zip_new(struct zip_error *error) za->nfile = za->nfile_alloc = 0; za->file = NULL; za->flags = za->ch_flags = 0; + za->default_password = NULL; return za; } diff --git a/ext/zip/lib/zip_open.c b/ext/zip/lib/zip_open.c index 31e12f4fc5..11c6fe05a6 100644 --- a/ext/zip/lib/zip_open.c +++ b/ext/zip/lib/zip_open.c @@ -1,6 +1,6 @@ /* - zip_open.c -- open zip archive - Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner + zip_open.c -- open zip archive by name + 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> @@ -52,7 +52,7 @@ static int _zip_headercomp(struct zip_dirent *, int, struct zip_dirent *, int); static unsigned char *_zip_memmem(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 *); @@ -61,24 +61,12 @@ ZIP_EXTERN(struct zip *) zip_open(const char *fn, int flags, int *zep) { 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)) { case -1: - if (!(flags & ZIP_OVERWRITE)) { - return NULL; - } - + return NULL; case 0: return _zip_allocate_new(fn, zep); - default: break; } @@ -88,7 +76,23 @@ zip_open(const char *fn, int flags, int *zep) 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); /* 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. */ 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) { struct zip_cdir *cd; unsigned char *cdp, **bufp; int i, comlen, nentry; - unsigned int left; + zip_uint32_t left; comlen = buf + buflen - eocd - EOCDLEN; if (comlen < 0) { @@ -196,14 +200,24 @@ _zip_readcdir(FILE *fp, unsigned char *buf, unsigned char *eocd, int buflen, cd->comment = NULL; 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)) { _zip_error_set(error, ZIP_ER_NOZIP, 0); - free(cd); + cd->nentry = 0; + _zip_cdir_free(cd); return NULL; } if ((flags & ZIP_CHECKCONS) && comlen != cd->comment_len) { _zip_error_set(error, ZIP_ER_INCONS, 0); - free(cd); + cd->nentry = 0; + _zip_cdir_free(cd); 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, cd->comment_len, error)) == NULL) { - free(cd); + cd->nentry = 0; + _zip_cdir_free(cd); return NULL; } } - if (cd->size < (unsigned int)(eocd-buf)) { + if (cd->offset >= buf_offset) { /* if buffer already read in, use it */ - cdp = eocd - cd->size; + cdp = buf + (cd->offset - buf_offset); bufp = &cdp; } 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); else _zip_error_set(error, ZIP_ER_NOZIP, 0); - free(cd); + cd->nentry = 0; + _zip_cdir_free(cd); return NULL; } } left = cd->size; i=0; - do { - 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); - } - + while (i<cd->nentry && left > 0) { if ((_zip_dirent_read(cd->entry+i, fp, bufp, &left, 0, error)) < 0) { cd->nentry = i; _zip_cdir_free(cd); @@ -255,7 +265,18 @@ _zip_readcdir(FILE *fp, unsigned char *buf, unsigned char *eocd, int buflen, } 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; } @@ -434,12 +455,16 @@ _zip_allocate_new(const char *fn, int *zep) set_error(zep, &error, 0); return NULL; } - - za->zn = strdup(fn); - if (!za->zn) { - _zip_free(za); - set_error(zep, NULL, ZIP_ER_MEMORY); - return NULL; + + if (fn == NULL) + za->zn = NULL; + else { + za->zn = strdup(fn); + if (!za->zn) { + _zip_free(za); + set_error(zep, NULL, ZIP_ER_MEMORY); + return NULL; + } } return za; } @@ -481,6 +506,7 @@ _zip_find_central_dir(FILE *fp, int flags, int *zep, off_t len) { struct zip_cdir *cdir, *cdirnew; unsigned char *buf, *match; + off_t buf_offset; int a, best, buflen, i; 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); return NULL; } - + buf_offset = ftello(fp); + /* 64k is too much for stack */ if ((buf=(unsigned char *)malloc(CDBUFSIZE)) == NULL) { 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 */ /* to avoid finding the same match all over again */ 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) continue; diff --git a/ext/zip/lib/zip_rename.c b/ext/zip/lib/zip_rename.c index e40ab27674..6b5a035917 100644 --- a/ext/zip/lib/zip_rename.c +++ b/ext/zip/lib/zip_rename.c @@ -40,16 +40,21 @@ 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; 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); 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) return -1; diff --git a/ext/zip/lib/zip_replace.c b/ext/zip/lib/zip_replace.c index ae69a86f63..6dc3dd5ab5 100644 --- a/ext/zip/lib/zip_replace.c +++ b/ext/zip/lib/zip_replace.c @@ -1,6 +1,6 @@ /* 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. The authors can be contacted at <libzip@nih.at> @@ -38,9 +38,9 @@ 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); return -1; } @@ -54,11 +54,18 @@ zip_replace(struct zip *za, int idx, struct zip_source *source) -int -_zip_replace(struct zip *za, int idx, const char *name, +/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */ + +zip_int64_t +_zip_replace(struct zip *za, zip_uint64_t idx, const char *name, 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) return -1; diff --git a/ext/zip/lib/zip_set_archive_comment.c b/ext/zip/lib/zip_set_archive_comment.c index c4bd070ddc..3cd069c757 100644 --- a/ext/zip/lib/zip_set_archive_comment.c +++ b/ext/zip/lib/zip_set_archive_comment.c @@ -1,6 +1,6 @@ /* 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. 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; } + if (ZIP_IS_RDONLY(za)) { + _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); + return -1; + } + if (len > 0) { if ((tmpcom=(char *)_zip_memdup(comment, len, &za->error)) == NULL) return -1; diff --git a/ext/zip/lib/zip_set_archive_flag.c b/ext/zip/lib/zip_set_archive_flag.c index 20316e4614..07bcfbe304 100644 --- a/ext/zip/lib/zip_set_archive_flag.c +++ b/ext/zip/lib/zip_set_archive_flag.c @@ -40,10 +40,30 @@ ZIP_EXTERN(int) zip_set_archive_flag(struct zip *za, int flag, int value) { + unsigned int new_flags; + if (value) - za->ch_flags |= flag; + new_flags = za->ch_flags | flag; 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; } diff --git a/ext/zip/lib/zip_set_default_password.c b/ext/zip/lib/zip_set_default_password.c new file mode 100644 index 0000000000..c274d1100b --- /dev/null +++ b/ext/zip/lib/zip_set_default_password.c @@ -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; +} diff --git a/ext/zip/lib/zip_set_file_comment.c b/ext/zip/lib/zip_set_file_comment.c index 3d5dd6b5e3..5e63dc2730 100644 --- a/ext/zip/lib/zip_set_file_comment.c +++ b/ext/zip/lib/zip_set_file_comment.c @@ -1,6 +1,6 @@ /* 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. The authors can be contacted at <libzip@nih.at> @@ -40,17 +40,23 @@ 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; - if (idx < 0 || idx >= za->nentry + if (idx >= za->nentry || len < 0 || len > MAXCOMLEN || (len > 0 && comment == 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 ((tmpcom=(char *)_zip_memdup(comment, len, &za->error)) == NULL) return -1; diff --git a/ext/zip/lib/zip_set_file_extra.c b/ext/zip/lib/zip_set_file_extra.c new file mode 100644 index 0000000000..db829e2e0a --- /dev/null +++ b/ext/zip/lib/zip_set_file_extra.c @@ -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; +} diff --git a/ext/zip/lib/zip_set_name.c b/ext/zip/lib/zip_set_name.c index 5c7da3d7c5..2a90601bfe 100644 --- a/ext/zip/lib/zip_set_name.c +++ b/ext/zip/lib/zip_set_name.c @@ -41,12 +41,12 @@ 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; - 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); return -1; } diff --git a/ext/zip/lib/zip_source_buffer.c b/ext/zip/lib/zip_source_buffer.c index 867d3dfa3e..8c9154ce3c 100644 --- a/ext/zip/lib/zip_source_buffer.c +++ b/ext/zip/lib/zip_source_buffer.c @@ -1,6 +1,6 @@ /* 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. The authors can be contacted at <libzip@nih.at> @@ -44,13 +44,12 @@ struct read_data { int freep; }; -static ssize_t read_data(void *state, void *data, size_t len, - enum zip_source_cmd cmd); +static zip_int64_t read_data(void *, void *, zip_uint64_t, enum zip_source_cmd); 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 zip_source *zs; @@ -58,7 +57,7 @@ zip_source_buffer(struct zip *za, const void *data, off_t len, int freep) if (za == NULL) return NULL; - if (len < 0 || (data == NULL && len > 0)) { + if (data == NULL && len > 0) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return NULL; } @@ -83,12 +82,12 @@ zip_source_buffer(struct zip *za, const void *data, off_t len, int freep) -static ssize_t -read_data(void *state, void *data, size_t len, enum zip_source_cmd cmd) +static zip_int64_t +read_data(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd) { struct read_data *z; char *buf; - size_t n; + zip_uint64_t n; z = (struct read_data *)state; buf = (char *)data; @@ -99,6 +98,8 @@ read_data(void *state, void *data, size_t len, enum zip_source_cmd cmd) return 0; case ZIP_SOURCE_READ: + /* XXX: return error if (len > ZIP_INT64_MAX) */ + n = z->end - z->buf; if (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); st->mtime = z->mtime; 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); } diff --git a/ext/zip/lib/zip_source_close.c b/ext/zip/lib/zip_source_close.c new file mode 100644 index 0000000000..a3bf7e5e1d --- /dev/null +++ b/ext/zip/lib/zip_source_close.c @@ -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; +} diff --git a/ext/zip/lib/zip_source_crc.c b/ext/zip/lib/zip_source_crc.c new file mode 100644 index 0000000000..7fd78f5697 --- /dev/null +++ b/ext/zip/lib/zip_source_crc.c @@ -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; + } + +} diff --git a/ext/zip/lib/zip_source_deflate.c b/ext/zip/lib/zip_source_deflate.c new file mode 100644 index 0000000000..5d9c5e67bb --- /dev/null +++ b/ext/zip/lib/zip_source_deflate.c @@ -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); +} diff --git a/ext/zip/lib/zip_source_error.c b/ext/zip/lib/zip_source_error.c new file mode 100644 index 0000000000..ffb4652d33 --- /dev/null +++ b/ext/zip/lib/zip_source_error.c @@ -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]; +} diff --git a/ext/zip/lib/zip_source_file.c b/ext/zip/lib/zip_source_file.c index ab6466dcbd..681cc2f3ea 100644 --- a/ext/zip/lib/zip_source_file.c +++ b/ext/zip/lib/zip_source_file.c @@ -41,15 +41,16 @@ 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) return NULL; - if (fname == NULL || start < 0 || len < -1) { + if (fname == NULL || len < -1) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); 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); } diff --git a/ext/zip/lib/zip_source_filep.c b/ext/zip/lib/zip_source_filep.c index 2a06a9f028..4d896a4c01 100644 --- a/ext/zip/lib/zip_source_filep.c +++ b/ext/zip/lib/zip_source_filep.c @@ -44,19 +44,23 @@ struct read_file { char *fname; /* name of file to copy from */ FILE *f; /* file to copy from */ - off_t off; /* start offset of */ - off_t len; /* lengt of data to copy */ - off_t remain; /* bytes remaining to be copied */ + int closep; /* close f */ + struct zip_stat st; /* stat information passed in */ + + 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 */ }; -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); 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) return NULL; @@ -66,14 +70,15 @@ zip_source_filep(struct zip *za, FILE *file, off_t start, off_t len) 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 * _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 zip_source *zs; @@ -99,7 +104,12 @@ _zip_source_file_or_p(struct zip *za, const char *fname, FILE *file, f->f = file; f->off = start; 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) { free(f); return NULL; @@ -110,8 +120,8 @@ _zip_source_file_or_p(struct zip *za, const char *fname, FILE *file, -static ssize_t -read_file(void *state, void *data, size_t len, enum zip_source_cmd cmd) +static zip_int64_t +read_file(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd) { struct read_file *z; 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) { - z->e[0] = ZIP_ER_SEEK; - z->e[1] = errno; - return -1; + if (z->closep) { + if (fseeko(z->f, (off_t)z->off, SEEK_SET) < 0) { + z->e[0] = ZIP_ER_SEEK; + z->e[1] = errno; + return -1; + } } z->remain = z->len; return 0; case ZIP_SOURCE_READ: + /* XXX: return INVAL if len > size_t max */ if (z->remain != -1) n = len > z->remain ? z->remain : len; else 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) { z->e[0] = ZIP_ER_READ; 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: { - struct zip_stat *st; - struct stat fst; - int err; - - if (len < sizeof(*st)) + if (len < sizeof(z->st)) return -1; - if (z->f) - err = fstat(fileno(z->f), &fst); - else - err = stat(z->fname, &fst); - - if (err != 0) { - z->e[0] = ZIP_ER_READ; /* best match */ - z->e[1] = errno; - return -1; + if (z->st.valid != 0) + memcpy(data, &z->st, sizeof(z->st)); + else { + struct zip_stat *st; + struct stat fst; + int err; + + if (z->f) + err = fstat(fileno(z->f), &fst); + else + err = stat(z->fname, &fst); + + if (err != 0) { + z->e[0] = ZIP_ER_READ; /* best match */ + z->e[1] = errno; + return -1; + } + + st = (struct zip_stat *)data; + + zip_stat_init(st); + 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; + } } - - 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); + return sizeof(z->st); } 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: free(z->fname); - if (z->f) - fclose(z->f); + if (z->closep && z->f) + fclose(z->f); free(z); return 0; diff --git a/ext/zip/lib/zip_source_free.c b/ext/zip/lib/zip_source_free.c index 293e7f7e11..f71c71ed6c 100644 --- a/ext/zip/lib/zip_source_free.c +++ b/ext/zip/lib/zip_source_free.c @@ -1,6 +1,6 @@ /* 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. The authors can be contacted at <libzip@nih.at> @@ -40,12 +40,20 @@ ZIP_EXTERN(void) -zip_source_free(struct zip_source *source) +zip_source_free(struct zip_source *src) { - if (source == NULL) + if (src == NULL) 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); } diff --git a/ext/zip/lib/zip_source_function.c b/ext/zip/lib/zip_source_function.c index fe3e82aa5b..984b107f7b 100644 --- a/ext/zip/lib/zip_source_function.c +++ b/ext/zip/lib/zip_source_function.c @@ -1,6 +1,6 @@ /* 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. 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) return NULL; - if ((zs=(struct zip_source *)malloc(sizeof(*zs))) == NULL) { - _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + if ((zs=_zip_source_new(za)) == NULL) return NULL; - } - zs->f = zcb; + zs->cb.f = zcb; zs->ud = ud; 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; +} diff --git a/ext/zip/lib/zip_source_layered.c b/ext/zip/lib/zip_source_layered.c new file mode 100644 index 0000000000..86ed420407 --- /dev/null +++ b/ext/zip/lib/zip_source_layered.c @@ -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; +} diff --git a/ext/zip/lib/zip_source_open.c b/ext/zip/lib/zip_source_open.c new file mode 100644 index 0000000000..2c768f7f3a --- /dev/null +++ b/ext/zip/lib/zip_source_open.c @@ -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; +} diff --git a/ext/zip/lib/zip_source_pkware.c b/ext/zip/lib/zip_source_pkware.c new file mode 100644 index 0000000000..83b5cc5ad5 --- /dev/null +++ b/ext/zip/lib/zip_source_pkware.c @@ -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); +} diff --git a/ext/zip/lib/zip_source_pop.c b/ext/zip/lib/zip_source_pop.c new file mode 100644 index 0000000000..406093869b --- /dev/null +++ b/ext/zip/lib/zip_source_pop.c @@ -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; +} diff --git a/ext/zip/lib/zip_source_read.c b/ext/zip/lib/zip_source_read.c new file mode 100644 index 0000000000..7246f9ccb5 --- /dev/null +++ b/ext/zip/lib/zip_source_read.c @@ -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; +} diff --git a/ext/zip/lib/zip_source_stat.c b/ext/zip/lib/zip_source_stat.c new file mode 100644 index 0000000000..662779eb6c --- /dev/null +++ b/ext/zip/lib/zip_source_stat.c @@ -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; +} diff --git a/ext/zip/lib/zip_source_zip.c b/ext/zip/lib/zip_source_zip.c index 58119dd39f..228803c717 100644 --- a/ext/zip/lib/zip_source_zip.c +++ b/ext/zip/lib/zip_source_zip.c @@ -1,6 +1,6 @@ /* 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. The authors can be contacted at <libzip@nih.at> @@ -41,17 +41,18 @@ struct read_zip { struct zip_file *zf; 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); ZIP_EXTERN(struct zip_source *) -zip_source_zip(struct zip *za, struct zip *srcza, int srcidx, int flags, - off_t start, off_t len) +zip_source_zip(struct zip *za, struct zip *srcza, zip_uint64_t srcidx, + int flags, zip_uint64_t start, zip_int64_t len) { struct zip_error error; struct zip_source *zs; @@ -62,7 +63,7 @@ zip_source_zip(struct zip *za, struct zip *srcza, int srcidx, int flags, if (za == 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); return NULL; } @@ -115,12 +116,13 @@ zip_source_zip(struct zip *za, struct zip *srcza, int srcidx, int flags, -static ssize_t -read_zip(void *state, void *data, size_t len, enum zip_source_cmd cmd) +static zip_int64_t +read_zip(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd) { struct read_zip *z; char b[8192], *buf; - int i, n; + int i; + zip_uint64_t n; z = (struct read_zip *)state; buf = (char *)data; diff --git a/ext/zip/lib/zip_stat_index.c b/ext/zip/lib/zip_stat_index.c index 26425206ca..8faa8cc394 100644 --- a/ext/zip/lib/zip_stat_index.c +++ b/ext/zip/lib/zip_stat_index.c @@ -1,6 +1,6 @@ /* 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. The authors can be contacted at <libzip@nih.at> @@ -38,11 +38,12 @@ 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; - if (index < 0 || index >= za->nentry) { + if (index >= za->nentry) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); 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 && ZIP_ENTRY_DATA_CHANGED(za->entry+index)) { - if (za->entry[index].source->f(za->entry[index].source->ud, - st, sizeof(*st), ZIP_SOURCE_STAT) < 0) { + if (zip_source_stat(za->entry[index].source, st) < 0) { _zip_error_set(&za->error, ZIP_ER_CHANGED, 0); 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); return -1; } - + + zip_stat_init(st); + st->crc = za->cdir->entry[index].crc; st->size = za->cdir->entry[index].uncomp_size; 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 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->name = name; + st->valid |= ZIP_STAT_INDEX|ZIP_STAT_NAME; return 0; } diff --git a/ext/zip/lib/zip_stat_init.c b/ext/zip/lib/zip_stat_init.c index cb451dc3bc..74e1ffd0b0 100644 --- a/ext/zip/lib/zip_stat_init.c +++ b/ext/zip/lib/zip_stat_init.c @@ -1,6 +1,6 @@ /* 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. The authors can be contacted at <libzip@nih.at> @@ -40,12 +40,13 @@ ZIP_EXTERN(void) zip_stat_init(struct zip_stat *st) { + st->valid = 0; st->name = NULL; - st->index = -1; + st->index = ZIP_UINT64_MAX; st->crc = 0; st->mtime = (time_t)-1; - st->size = -1; - st->comp_size = -1; + st->size = 0; + st->comp_size = 0; st->comp_method = ZIP_CM_STORE; st->encryption_method = ZIP_EM_NONE; } diff --git a/ext/zip/lib/zip_unchange.c b/ext/zip/lib/zip_unchange.c index 7366c9cc71..550e8b9903 100644 --- a/ext/zip/lib/zip_unchange.c +++ b/ext/zip/lib/zip_unchange.c @@ -40,7 +40,7 @@ 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); } @@ -48,11 +48,11 @@ zip_unchange(struct zip *za, int idx) 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; - if (idx < 0 || idx >= za->nentry) { + if (idx >= za->nentry) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return -1; } @@ -72,6 +72,9 @@ _zip_unchange(struct zip *za, int idx, int allow_duplicates) 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); za->entry[idx].ch_comment = NULL; za->entry[idx].ch_comment_len = -1; diff --git a/ext/zip/lib/zip_unchange_archive.c b/ext/zip/lib/zip_unchange_archive.c index fe30a5ad2c..ca2b678544 100644 --- a/ext/zip/lib/zip_unchange_archive.c +++ b/ext/zip/lib/zip_unchange_archive.c @@ -1,6 +1,6 @@ /* 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. The authors can be contacted at <libzip@nih.at> diff --git a/ext/zip/lib/zip_unchange_data.c b/ext/zip/lib/zip_unchange_data.c index 6fe89f4fb2..7dd93b768a 100644 --- a/ext/zip/lib/zip_unchange_data.c +++ b/ext/zip/lib/zip_unchange_data.c @@ -43,8 +43,7 @@ void _zip_unchange_data(struct zip_entry *ze) { if (ze->source) { - (void)ze->source->f(ze->source->ud, NULL, 0, ZIP_SOURCE_FREE); - free(ze->source); + zip_source_free(ze->source); ze->source = NULL; } diff --git a/ext/zip/lib/zipconf.h b/ext/zip/lib/zipconf.h new file mode 100644 index 0000000000..b65d91eb77 --- /dev/null +++ b/ext/zip/lib/zipconf.h @@ -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 */ diff --git a/ext/zip/lib/zipint.h b/ext/zip/lib/zipint.h index d72ed144d4..67fae80ade 100644 --- a/ext/zip/lib/zipint.h +++ b/ext/zip/lib/zipint.h @@ -3,7 +3,7 @@ /* 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. The authors can be contacted at <libzip@nih.at> @@ -38,12 +38,35 @@ #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 #include <windows.h> #include <wchar.h> #define _zip_rename(s, t) \ (!MoveFileExA((s), (t), \ 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 #define _zip_rename rename #endif @@ -52,12 +75,6 @@ # define strcmpi strcasecmp #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 #undef MAXCOMLEN /* defined as 19 on BSD for max command name */ #define MAXCOMLEN 65536 +#define MAXEXTLEN 65536 #define EOCDLEN 22 #define CDBUFSIZE (MAXCOMLEN+EOCDLEN) #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 */ enum zip_state { ZIP_ST_UNCHANGED, ZIP_ST_DELETED, ZIP_ST_REPLACED, 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 */ -#define ZIP_ZF_DECOMP 2 /* decompress data */ -#define ZIP_ZF_CRC 4 /* compute and compare CRC */ +enum zip_les { ZIP_LES_NONE, ZIP_LES_UPPER, ZIP_LES_LOWER, ZIP_LES_INVAL }; /* directory entry: general purpose bit flags */ @@ -114,12 +186,14 @@ struct zip { unsigned int flags; /* 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 */ char *ch_comment; /* changed archive comment */ int ch_comment_len; /* length of changed zip archive * comment, -1 if unchanged */ - int nentry; /* number of entries */ - int nentry_alloc; /* number of entries allocated */ + zip_uint64_t nentry; /* number of entries */ + zip_uint64_t nentry_alloc; /* number of entries allocated */ struct zip_entry *entry; /* entries */ int nfile; /* number of opened files within archive */ int nfile_alloc; /* number of files allocated */ @@ -131,18 +205,8 @@ struct zip { struct zip_file { struct zip *za; /* zip archive containing this file */ struct zip_error error; /* error information */ - int flags; /* -1: eof, >0: error */ - - 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; + int eof; + struct zip_source *src; /* data source */ }; /* zip archive directory entry (central or local) */ @@ -183,8 +247,14 @@ struct zip_cdir { struct zip_source { - zip_source_callback f; + struct zip_source *src; + union { + zip_source_callback f; + zip_source_layered_callback l; + } cb; void *ud; + enum zip_les error_source; + int is_open; }; /* entry in zip archive directory */ @@ -193,6 +263,8 @@ struct zip_entry { enum zip_state state; struct zip_source *source; char *ch_filename; + char *ch_extra; + int ch_extra_len; char *ch_comment; int ch_comment_len; }; @@ -209,6 +281,8 @@ extern const int _zip_err_type[]; ((x)->state == ZIP_ST_REPLACED \ || (x)->state == ZIP_ST_ADDED) +#define ZIP_IS_RDONLY(za) ((za)->ch_flags & ZIP_AFL_RDONLY) + 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_init(struct zip_dirent *); 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 *); 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_init(struct zip_error *); 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 *); 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 *); +struct zip *_zip_open(const char *, FILE *, int, int, int *); + struct zip_source *_zip_source_file_or_p(struct zip *, const char *, FILE *, - off_t, off_t); + 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 *); -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); void *_zip_memdup(const void *, size_t, struct zip_error *); int _zip_name_locate(struct zip *, const char *, int, struct zip_error *); struct zip *_zip_new(struct zip_error *); unsigned short _zip_read2(unsigned char **); unsigned int _zip_read4(unsigned char **); -int _zip_replace(struct zip *, int, const char *, struct zip_source *); -int _zip_set_name(struct zip *, int, const char *); -int _zip_unchange(struct zip *, int, int); +zip_int64_t _zip_replace(struct zip *, zip_uint64_t, const char *, + struct zip_source *); +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 *); #endif /* zipint.h */ |