diff options
author | Pierre Joye <pajoye@php.net> | 2008-10-23 16:13:51 +0000 |
---|---|---|
committer | Pierre Joye <pajoye@php.net> | 2008-10-23 16:13:51 +0000 |
commit | 047bda3cb82c5b398a610e28433487bd87609383 (patch) | |
tree | 1c719997f4a570e2ba10a958d72b7e22468caa51 | |
parent | 8d916b2ec6ec5be8fe68a1461af87d14826a425a (diff) | |
download | php-git-047bda3cb82c5b398a610e28433487bd87609383.tar.gz |
- MFH
- Update ziplib
- flatten path and make them relative before extraction
- remove unnecessary export
57 files changed, 1188 insertions, 790 deletions
diff --git a/ext/zip/config.m4 b/ext/zip/config.m4 index 271bd2faa0..29705dbf16 100644 --- a/ext/zip/config.m4 +++ b/ext/zip/config.m4 @@ -20,7 +20,7 @@ if test "$PHP_ZIP" != "no"; then PHP_ZLIB_DIR="$PHP_ZLIB_DIR" PHP_ZLIB_INCDIR="$PHP_ZLIB_DIR/include" else - AC_MSG_ERROR([Can't find zlib headers under "$PHP_ZLIB_DIR"]) + AC_MSG_ERROR([Can not find zlib headers under "$PHP_ZLIB_DIR"]) fi else for i in /usr/local /usr; do @@ -52,13 +52,15 @@ if test "$PHP_ZIP" != "no"; then lib/zip_error_get_sys_type.c lib/zip_file_get_offset.c \ lib/zip_get_name.c lib/zip_replace.c lib/zip_source_function.c \ lib/zip_unchange.c lib/zip_dirent.c lib/zip_error_strerror.c \ - lib/zip_file_strerror.c lib/zip_get_num_files.c \ + lib/zip_filerange_crc.c lib/zip_file_strerror.c lib/zip_get_num_files.c \ + lib/zip_get_archive_flag.c lib/zip_set_archive_flag.c \ lib/zip_set_name.c lib/zip_source_zip.c lib/zip_unchange_data.c \ lib/zip_entry_free.c lib/zip_error_to_str.c lib/zip_fopen.c \ lib/zip_name_locate.c lib/zip_source_buffer.c lib/zip_stat.c \ lib/zip_entry_new.c lib/zip_err_str.c lib/zip_fopen_index.c \ - lib/zip_new.c lib/zip_source_file.c lib/zip_stat_index.c lib/zip_get_archive_comment.c \ - lib/zip_get_file_comment.c lib/zip_set_archive_comment.c lib/zip_set_file_comment.c \ + lib/zip_get_archive_comment.c lib/zip_get_file_comment.c \ + lib/zip_new.c lib/zip_source_file.c lib/zip_stat_index.c \ + lib/zip_set_archive_comment.c lib/zip_set_file_comment.c \ lib/zip_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" @@ -66,11 +68,6 @@ if test "$PHP_ZIP" != "no"; then PHP_NEW_EXTENSION(zip, php_zip.c zip_stream.c $PHP_ZIP_SOURCES, $ext_shared) PHP_ADD_BUILD_DIR($ext_builddir/lib, 1) PHP_SUBST(ZIP_SHARED_LIBADD) - ifdef([PHP_INSTALL_HEADERS], - [ - dnl Sadly, this is a complete NOP for pecl extensions - PHP_INSTALL_HEADERS(ext/zip/lib, [lib/zip.h lib/zipint.h lib/zip_alias.h lib/zipint_alias.h]) - ]) dnl so we always include the known-good working hack. PHP_ADD_MAKEFILE_FRAGMENT diff --git a/ext/zip/config.w32 b/ext/zip/config.w32 index a8ae4f1223..0a3dc18db8 100644 --- a/ext/zip/config.w32 +++ b/ext/zip/config.w32 @@ -18,7 +18,8 @@ if (PHP_ZIP != "no") { zip_error_get_sys_type.c zip_file_get_offset.c \ zip_get_name.c zip_replace.c zip_source_function.c \ zip_unchange.c zip_dirent.c zip_error_strerror.c \ - zip_file_strerror.c zip_get_num_files.c \ + zip_filerange_crc.c zip_file_strerror.c zip_get_num_files.c \ + zip_get_archive_flag.c zip_set_archive_flag.c \ zip_set_name.c zip_source_zip.c zip_unchange_data.c \ zip_entry_free.c zip_error_to_str.c zip_fopen.c \ zip_name_locate.c zip_source_buffer.c zip_stat.c \ @@ -31,7 +32,6 @@ if (PHP_ZIP != "no") { AC_DEFINE('HAVE_ZLIB', 1); AC_DEFINE('HAVE_ZIP', 1); - ADD_FLAG("CFLAGS_ZIP", "/D PHP_ZIP_EXPORTS "); } else { WARNING("zip not enabled; libraries and headers not found"); } diff --git a/ext/zip/lib/zip.h b/ext/zip/lib/zip.h index 04ffb1471b..c1e859546b 100644 --- a/ext/zip/lib/zip.h +++ b/ext/zip/lib/zip.h @@ -2,13 +2,11 @@ #define _HAD_ZIP_H /* - $NiH: zip.h,v 1.57 2006/04/24 14:04:19 dillo Exp $ - zip.h -- exported declarations. Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -38,24 +36,26 @@ #include "main/php.h" -/* #defines that rename all zip_ functions and structs */ -#include "zip_alias.h" + #ifdef PHP_WIN32 -#include "zip_win32.h" +# include "zip_win32.h" # ifdef PHP_ZIP_EXPORTS -# define PHPZIPAPI __declspec(dllexport) +# define ZIP_EXTERN(rt) __declspec(dllexport)rt _stdcall # else -# define PHPZIPAPI +# define ZIP_EXTERN(rt) rt # endif +#elif defined(__GNUC__) && __GNUC__ >= 4 +# define ZIP_EXTERN(rt) __attribute__ ((visibility("default"))) rt #else -#define PHPZIPAPI +# define ZIP_EXTERN(rt) rt #endif + BEGIN_EXTERN_C() + #include <sys/types.h> #include <stdio.h> #include <time.h> - /* flags for zip_open */ #define ZIP_CREATE 1 @@ -70,6 +70,11 @@ BEGIN_EXTERN_C() #define ZIP_FL_NODIR 2 /* ignore directory component */ #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 */ + +/* archive global flags flags */ + +#define ZIP_AFL_TORRENT 1 /* torrent zipped */ /* libzip error codes */ @@ -121,6 +126,13 @@ BEGIN_EXTERN_C() #define ZIP_CM_PKWARE_IMPLODE 10 /* PKWARE imploding */ /* 11 - Reserved by PKWARE */ #define ZIP_CM_BZIP2 12 /* compressed using BZIP2 algorithm */ +/* 13 - Reserved by PKWARE */ +#define ZIP_CM_LZMA 14 /* LZMA (EFS) */ +/* 15-17 - Reserved by PKWARE */ +#define ZIP_CM_TERSE 18 /* compressed using IBM TERSE (new) */ +#define ZIP_CM_LZ77 19 /* IBM LZ77 z Architecture (PFS) */ +#define ZIP_CM_WAVPACK 97 /* WavPack compressed data */ +#define ZIP_CM_PPMD 98 /* PPMd version I, Rev 1 */ /* encryption methods */ @@ -170,46 +182,51 @@ struct zip_source; -PHPZIPAPI int zip_add(struct zip *, const char *, struct zip_source *); -PHPZIPAPI int zip_add_dir(struct zip *, const char *); -PHPZIPAPI int zip_close(struct zip *); -PHPZIPAPI int zip_delete(struct zip *, int); -PHPZIPAPI void zip_error_clear(struct zip *); -PHPZIPAPI void zip_error_get(struct zip *, int *, int *); -PHPZIPAPI int zip_error_get_sys_type(int); -PHPZIPAPI int zip_error_to_str(char *, size_t, int, int); -PHPZIPAPI int zip_fclose(struct zip_file *); -PHPZIPAPI void zip_file_error_clear(struct zip_file *); -PHPZIPAPI void zip_file_error_get(struct zip_file *, int *, int *); -PHPZIPAPI const char *zip_file_strerror(struct zip_file *); -PHPZIPAPI struct zip_file *zip_fopen(struct zip *, const char *, int); -PHPZIPAPI struct zip_file *zip_fopen_index(struct zip *, int, int); -PHPZIPAPI ssize_t zip_fread(struct zip_file *, void *, size_t); -PHPZIPAPI const char *zip_get_archive_comment(struct zip *, int *, int); -PHPZIPAPI const char *zip_get_file_comment(struct zip *, int, int *, int); -PHPZIPAPI const char *zip_get_name(struct zip *, int, int); -PHPZIPAPI int zip_get_num_files(struct zip *); -PHPZIPAPI int zip_name_locate(struct zip *, const char *, int); -PHPZIPAPI struct zip *zip_open(const char *, int, int *); -PHPZIPAPI int zip_rename(struct zip *, int, const char *); -PHPZIPAPI int zip_replace(struct zip *, int, struct zip_source *); -PHPZIPAPI int zip_set_archive_comment(struct zip *, const char *, int); -PHPZIPAPI int zip_set_file_comment(struct zip *, int, const char *, int); -PHPZIPAPI struct zip_source *zip_source_buffer(struct zip *, const void *, off_t, int); -PHPZIPAPI struct zip_source *zip_source_file(struct zip *, const char *, off_t, off_t); -PHPZIPAPI struct zip_source *zip_source_filep(struct zip *, FILE *, off_t, off_t); -PHPZIPAPI void zip_source_free(struct zip_source *); -PHPZIPAPI struct zip_source *zip_source_function(struct zip *, +ZIP_EXTERN(int) zip_add(struct zip *, const char *, struct zip_source *); +ZIP_EXTERN(int) zip_add_dir(struct zip *, const char *); +ZIP_EXTERN(int) zip_close(struct zip *); +ZIP_EXTERN(int) zip_delete(struct zip *, int); +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_fclose(struct zip_file *); +ZIP_EXTERN(void) zip_file_error_clear(struct zip_file *); +ZIP_EXTERN(void) zip_file_error_get(struct zip_file *, int *, int *); +ZIP_EXTERN(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(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(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_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(void) zip_source_free(struct zip_source *); +ZIP_EXTERN(struct zip_source *)zip_source_function(struct zip *, zip_source_callback, void *); -PHPZIPAPI struct zip_source *zip_source_zip(struct zip *, struct zip *, int, int, - off_t, off_t); -PHPZIPAPI int zip_stat(struct zip *, const char *, int, struct zip_stat *); -PHPZIPAPI int zip_stat_index(struct zip *, int, int, struct zip_stat *); -PHPZIPAPI void zip_stat_init(struct zip_stat *); -PHPZIPAPI const char *zip_strerror(struct zip *); -PHPZIPAPI int zip_unchange(struct zip *, int); -PHPZIPAPI int zip_unchange_all(struct zip *); -PHPZIPAPI int zip_unchange_archive(struct zip *); +ZIP_EXTERN(struct zip_source *)zip_source_zip(struct zip *, struct zip *, + int, int, off_t, off_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(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_all(struct zip *); +ZIP_EXTERN(int) zip_unchange_archive(struct zip *); END_EXTERN_C(); #endif /* _HAD_ZIP_H */ diff --git a/ext/zip/lib/zip_add.c b/ext/zip/lib/zip_add.c index 70d1162f7f..3afb1768f7 100644 --- a/ext/zip/lib/zip_add.c +++ b/ext/zip/lib/zip_add.c @@ -1,11 +1,9 @@ /* - $NiH: zip_add.c,v 1.14 2004/11/18 15:04:04 wiz Exp $ - zip_add.c -- add file via callback function - Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -35,17 +33,17 @@ -#include "zip.h" #include "zipint.h" -PHPZIPAPI int +ZIP_EXTERN(int) 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); } diff --git a/ext/zip/lib/zip_add_dir.c b/ext/zip/lib/zip_add_dir.c index d4da559ecd..9b23425194 100644 --- a/ext/zip/lib/zip_add_dir.c +++ b/ext/zip/lib/zip_add_dir.c @@ -1,11 +1,9 @@ /* - $NiH: zip_add_dir.c,v 1.1 2006/10/03 12:23:13 dillo Exp $ - zip_add_dir.c -- add directory - Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -38,12 +36,11 @@ #include <stdlib.h> #include <string.h> -#include "zip.h" #include "zipint.h" -PHPZIPAPI int +ZIP_EXTERN(int) zip_add_dir(struct zip *za, const char *name) { int len, ret; diff --git a/ext/zip/lib/zip_close.c b/ext/zip/lib/zip_close.c index 11ba8e2231..9fe0fba919 100644 --- a/ext/zip/lib/zip_close.c +++ b/ext/zip/lib/zip_close.c @@ -1,11 +1,9 @@ /* - $NiH: zip_close.c,v 1.60 2006/05/09 17:21:47 wiz Exp $ - zip_close.c -- close zip archive and update changes - Copyright (C) 1999, 2004, 2005 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -32,31 +30,42 @@ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + + + #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> -#ifndef _MSC_VER -#include <unistd.h> -#endif #include <sys/types.h> #include <sys/stat.h> -#include "zip.h" #include "zipint.h" -static int add_data(struct zip *, int, struct zip_dirent *, FILE *); +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(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 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 *); + + -PHPZIPAPI int +struct filelist { + int idx; + const char *name; +}; + + + +ZIP_EXTERN(int) zip_close(struct zip *za) { int survivors; @@ -66,7 +75,14 @@ zip_close(struct zip *za) mode_t mask; struct zip_cdir *cd; struct zip_dirent de; - int rename_error = 0; + struct filelist *filelist; + int reopen_on_error; + int new_torrentzip; + + reopen_on_error = 0; + + if (za == NULL) + return -1; if (!_zip_changed(za, &survivors)) { _zip_free(za); @@ -75,7 +91,7 @@ zip_close(struct zip *za) /* don't create zip files with no entries */ if (survivors == 0) { - if (za->zn) { + if (za->zn && za->zp) { if (remove(za->zn) != 0) { _zip_error_set(&za->error, ZIP_ER_REMOVE, errno); return -1; @@ -85,52 +101,92 @@ zip_close(struct zip *za) return 0; } - if ((cd=_zip_cdir_new(survivors, &za->error)) == NULL) + if ((filelist=(struct filelist *)malloc(sizeof(filelist[0])*survivors)) + == NULL) + return -1; + + if ((cd=_zip_cdir_new(survivors, &za->error)) == NULL) { + free(filelist); return -1; + } for (i=0; i<survivors; i++) _zip_dirent_init(&cd->entry[i]); + /* archive comment is special for torrentzip */ + if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0)) { + cd->comment = _zip_memdup(TORRENT_SIG "XXXXXXXX", + TORRENT_SIG_LEN + TORRENT_CRC_LEN, + &za->error); + if (cd->comment == NULL) { + _zip_cdir_free(cd); + free(filelist); + return -1; + } + 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); + free(filelist); return -1; } + } if ((temp=_zip_create_temp_output(za, &out)) == NULL) { _zip_cdir_free(cd); return -1; } - error = 0; + + /* create list of files with index into original archive */ for (i=j=0; i<za->nentry; i++) { if (za->entry[i].state == ZIP_ST_DELETED) continue; + filelist[j].idx = i; + filelist[j].name = zip_get_name(za, i, 0); + j++; + } + if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0)) + qsort(filelist, survivors, sizeof(filelist[0]), + _zip_torrentzip_cmp); + + new_torrentzip = (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0) == 1 + && zip_get_archive_flag(za, ZIP_AFL_TORRENT, + ZIP_FL_UNCHANGED) == 0); + error = 0; + for (j=0; j<survivors; j++) { + i = filelist[j].idx; + /* create new local directory entry */ - if (ZIP_ENTRY_DATA_CHANGED(za->entry+i)) { + if (ZIP_ENTRY_DATA_CHANGED(za->entry+i) || new_torrentzip) { _zip_dirent_init(&de); + + if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0)) + _zip_dirent_torrent_normalize(&de); + /* use it as central directory entry */ memcpy(cd->entry+j, &de, sizeof(cd->entry[j])); /* set/update file name */ if (za->entry[i].ch_filename == NULL) { - if (za->entry[i].state == ZIP_ST_REPLACED) { - de.filename = strdup(za->cdir->entry[i].filename); - de.filename_len = strlen(de.filename); - cd->entry[j].filename = za->cdir->entry[i].filename; - cd->entry[j].filename_len = de.filename_len; - } - else { + if (za->entry[i].state == ZIP_ST_ADDED) { de.filename = strdup("-"); de.filename_len = 1; cd->entry[j].filename = "-"; + } + else { + de.filename = strdup(za->cdir->entry[i].filename); + de.filename_len = strlen(de.filename); + cd->entry[j].filename = za->cdir->entry[i].filename; cd->entry[j].filename_len = de.filename_len; } } } else { /* copy existing directory entries */ - if (fseek(za->zp, za->cdir->entry[i].offset, SEEK_SET) != 0) { + if (fseeko(za->zp, za->cdir->entry[i].offset, SEEK_SET) != 0) { _zip_error_set(&za->error, ZIP_ER_SEEK, errno); error = 1; break; @@ -139,11 +195,11 @@ zip_close(struct zip *za) error = 1; break; } - - if (de.bitflags & ZIP_GPBF_USE_DATA_DESCRIPTOR) { - de.crc = (za->cdir->entry+i)->crc; - de.comp_size = (za->cdir->entry+i)->comp_size; - de.uncomp_size = (za->cdir->entry+i)->uncomp_size; + if (de.bitflags & ZIP_GPBF_DATA_DESCRIPTOR) { + de.crc = za->cdir->entry[i].crc; + de.comp_size = za->cdir->entry[i].comp_size; + de.uncomp_size = za->cdir->entry[i].uncomp_size; + de.bitflags &= ~ZIP_GPBF_DATA_DESCRIPTOR; } memcpy(cd->entry+j, za->cdir->entry+i, sizeof(cd->entry[j])); } @@ -159,20 +215,31 @@ zip_close(struct zip *za) cd->entry[j].filename_len = de.filename_len; } - if (za->entry[i].ch_comment_len != -1) { + 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 */ cd->entry[j].comment = za->entry[i].ch_comment; cd->entry[j].comment_len = za->entry[i].ch_comment_len; } - cd->entry[j].offset = ftell(out); + cd->entry[j].offset = ftello(out); + + if (ZIP_ENTRY_DATA_CHANGED(za->entry+i) || new_torrentzip) { + struct zip_source *zs; - if (ZIP_ENTRY_DATA_CHANGED(za->entry+i)) { - if (add_data(za, i, &de, out) < 0) { + 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 (add_data(za, zs ? zs : za->entry[i].source, &de, out) < 0) { + error = 1; + break; + } cd->entry[j].last_mod = de.last_mod; cd->entry[j].comp_method = de.comp_method; cd->entry[j].comp_size = de.comp_size; @@ -185,19 +252,18 @@ zip_close(struct zip *za) break; } /* we just read the local dirent, file is at correct position */ - if (copy_data(za->zp, de.comp_size, out, &za->error) < 0) { + if (copy_data(za->zp, cd->entry[j].comp_size, out, + &za->error) < 0) { error = 1; break; } } - j++; - _zip_dirent_finalize(&de); } if (!error) { - if (_zip_cdir_write(cd, out, &za->error) < 0) + if (write_cdir(za, cd, out) < 0) error = 1; } @@ -223,46 +289,40 @@ zip_close(struct zip *za) if (za->zp) { fclose(za->zp); za->zp = NULL; + reopen_on_error = 1; } - -#ifdef PHP_WIN32 - if (!MoveFileEx(temp, za->zn, MOVEFILE_REPLACE_EXISTING)) { - rename_error = -1; - } -#else - if (rename(temp, za->zn) != 0) { - rename_error = -1; - } -#endif - - if (rename_error < 0) { + if (_zip_rename(temp, za->zn) != 0) { _zip_error_set(&za->error, ZIP_ER_RENAME, errno); remove(temp); free(temp); + if (reopen_on_error) { + /* ignore errors, since we're already in an error case */ + za->zp = fopen(za->zn, "rb"); + } return -1; } - mask = umask(0); umask(mask); chmod(za->zn, 0666&~mask); _zip_free(za); free(temp); + return 0; } static int -add_data(struct zip *za, int idx, struct zip_dirent *de, FILE *ft) +add_data(struct zip *za, struct zip_source *zs, struct zip_dirent *de, FILE *ft) { off_t offstart, offend; zip_source_callback cb; void *ud; struct zip_stat st; - cb = za->entry[idx].source->f; - ud = za->entry[idx].source->ud; + 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); @@ -274,7 +334,7 @@ add_data(struct zip *za, int idx, struct zip_dirent *de, FILE *ft) return -1; } - offstart = ftell(ft); + offstart = ftello(ft); if (_zip_dirent_write(de, ft, 1, &za->error) < 0) return -1; @@ -284,7 +344,7 @@ add_data(struct zip *za, int idx, struct zip_dirent *de, FILE *ft) return -1; } else { - if (add_data_uncomp(cb, ud, &st, ft, &za->error) < 0) + if (add_data_uncomp(za, cb, ud, &st, ft) < 0) return -1; } @@ -293,23 +353,27 @@ add_data(struct zip *za, int idx, struct zip_dirent *de, FILE *ft) return -1; } - offend = ftell(ft); + offend = ftello(ft); - if (fseek(ft, offstart, SEEK_SET) < 0) { + if (fseeko(ft, offstart, SEEK_SET) < 0) { _zip_error_set(&za->error, ZIP_ER_SEEK, errno); return -1; } - de->comp_method = st.comp_method; + 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; + 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 (fseek(ft, offend, SEEK_SET) < 0) { + if (fseeko(ft, offend, SEEK_SET) < 0) { _zip_error_set(&za->error, ZIP_ER_SEEK, errno); return -1; } @@ -346,14 +410,15 @@ add_data_comp(zip_source_callback cb, void *ud, struct zip_stat *st,FILE *ft, static int -add_data_uncomp(zip_source_callback cb, void *ud, struct zip_stat *st, - FILE *ft, struct zip_error *error) +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; @@ -365,8 +430,13 @@ add_data_uncomp(zip_source_callback cb, void *ud, struct zip_stat *st, zstr.avail_in = 0; zstr.avail_out = 0; - /* -15: undocumented feature of zlib to _not_ write a zlib header */ - deflateInit2(&zstr, Z_BEST_COMPRESSION, Z_DEFLATED, -15, 9, + 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; @@ -378,7 +448,7 @@ add_data_uncomp(zip_source_callback cb, void *ud, struct zip_stat *st, while (!end) { if (zstr.avail_in == 0 && !flush) { if ((n=cb(ud, b1, sizeof(b1), ZIP_SOURCE_READ)) < 0) { - ch_set_error(error, cb, ud); + ch_set_error(&za->error, cb, ud); deflateEnd(&zstr); return -1; } @@ -394,7 +464,7 @@ add_data_uncomp(zip_source_callback cb, void *ud, struct zip_stat *st, ret = deflate(&zstr, flush); if (ret != Z_OK && ret != Z_STREAM_END) { - _zip_error_set(error, ZIP_ER_ZLIB, ret); + _zip_error_set(&za->error, ZIP_ER_ZLIB, ret); return -1; } @@ -402,7 +472,7 @@ add_data_uncomp(zip_source_callback cb, void *ud, struct zip_stat *st, n2 = sizeof(b2) - zstr.avail_out; if (fwrite(b2, 1, n2, ft) != n2) { - _zip_error_set(error, ZIP_ER_WRITE, errno); + _zip_error_set(&za->error, ZIP_ER_WRITE, errno); return -1; } @@ -473,6 +543,44 @@ copy_data(FILE *fs, off_t len, FILE *ft, struct zip_error *error) static int +write_cdir(struct zip *za, struct zip_cdir *cd, FILE *out) +{ + off_t offset; + uLong crc; + char buf[TORRENT_CRC_LEN+1]; + + if (_zip_cdir_write(cd, out, &za->error) < 0) + return -1; + + if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0) == 0) + return 0; + + + /* fix up torrentzip comment */ + + offset = ftello(out); + + if (_zip_filerange_crc(out, cd->offset, cd->size, &crc, &za->error) < 0) + return -1; + + snprintf(buf, sizeof(buf), "%08lX", (long)crc); + + if (fseeko(out, offset-TORRENT_CRC_LEN, SEEK_SET) < 0) { + _zip_error_set(&za->error, ZIP_ER_SEEK, errno); + return -1; + } + + if (fwrite(buf, TORRENT_CRC_LEN, 1, out) != 1) { + _zip_error_set(&za->error, ZIP_ER_WRITE, errno); + return -1; + } + + return 0; +} + + + +static int _zip_cdir_set_comment(struct zip_cdir *dest, struct zip *src) { if (src->ch_comment_len != -1) { @@ -503,7 +611,8 @@ _zip_changed(struct zip *za, int *survivorsp) changed = survivors = 0; - if (za->ch_comment_len != -1) + if (za->ch_comment_len != -1 + || za->ch_flags != za->flags) changed = 1; for (i=0; i<za->nentry; i++) { @@ -527,14 +636,13 @@ _zip_create_temp_output(struct zip *za, FILE **outp) char *temp; int tfd; FILE *tfp; - int len = strlen(za->zn) + 8; - if ((temp=(char *)malloc(len)) == NULL) { + if ((temp=(char *)malloc(strlen(za->zn)+8)) == NULL) { _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); return NULL; } - snprintf(temp, len, "%s.XXXXXX", za->zn); + sprintf(temp, "%s.XXXXXX", za->zn); if ((tfd=mkstemp(temp)) == -1) { _zip_error_set(&za->error, ZIP_ER_TMPOPEN, errno); @@ -549,10 +657,16 @@ _zip_create_temp_output(struct zip *za, FILE **outp) free(temp); return NULL; } -#ifdef PHP_WIN32 - _setmode(_fileno(tfp), _O_BINARY ); -#endif *outp = tfp; return temp; } + + + +static int +_zip_torrentzip_cmp(const void *a, const void *b) +{ + return strcasecmp(((const struct filelist *)a)->name, + ((const struct filelist *)b)->name); +} diff --git a/ext/zip/lib/zip_delete.c b/ext/zip/lib/zip_delete.c index eb5055b687..4591ff7f86 100644 --- a/ext/zip/lib/zip_delete.c +++ b/ext/zip/lib/zip_delete.c @@ -1,11 +1,9 @@ /* - $NiH: zip_delete.c,v 1.17 2005/06/09 19:57:09 dillo Exp $ - zip_delete.c -- delete file from zip archive - Copyright (C) 1999, 2004, 2005 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -35,12 +33,11 @@ -#include "zip.h" #include "zipint.h" -PHPZIPAPI int +ZIP_EXTERN(int) zip_delete(struct zip *za, int idx) { if (idx < 0 || idx >= za->nentry) { diff --git a/ext/zip/lib/zip_dirent.c b/ext/zip/lib/zip_dirent.c index f796f8d669..1b2db34dec 100644 --- a/ext/zip/lib/zip_dirent.c +++ b/ext/zip/lib/zip_dirent.c @@ -1,11 +1,9 @@ /* - $NiH: zip_dirent.c,v 1.9 2006/04/23 14:51:45 wiz Exp $ - zip_dirent.c -- read directory entry (local or central), clean dirent - Copyright (C) 1999, 2003, 2004, 2005 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -33,18 +31,15 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "main/php_reentrancy.h" + + #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> -#ifndef _MSC_VER -#include <unistd.h> -#endif #include <sys/types.h> #include <sys/stat.h> -#include "zip.h" #include "zipint.h" static time_t _zip_d2u_time(int, int); @@ -56,7 +51,7 @@ static void _zip_write4(unsigned int, FILE *); -PHPZIPAPI void +void _zip_cdir_free(struct zip_cdir *cd) { int i; @@ -73,7 +68,7 @@ _zip_cdir_free(struct zip_cdir *cd) -PHPZIPAPI struct zip_cdir * +struct zip_cdir * _zip_cdir_new(int nentry, struct zip_error *error) { struct zip_cdir *cd; @@ -102,19 +97,19 @@ _zip_cdir_new(int nentry, struct zip_error *error) -PHPZIPAPI int +int _zip_cdir_write(struct zip_cdir *cd, FILE *fp, struct zip_error *error) { int i; - cd->offset = ftell(fp); + cd->offset = ftello(fp); for (i=0; i<cd->nentry; i++) { if (_zip_dirent_write(cd->entry+i, fp, 0, error) != 0) return -1; } - cd->size = ftell(fp) - cd->offset; + cd->size = ftello(fp) - cd->offset; /* clearerr(fp); */ fwrite(EOCD_MAGIC, 1, 4, fp); @@ -136,7 +131,7 @@ _zip_cdir_write(struct zip_cdir *cd, FILE *fp, struct zip_error *error) -PHPZIPAPI void +void _zip_dirent_finalize(struct zip_dirent *zde) { free(zde->filename); @@ -149,7 +144,7 @@ _zip_dirent_finalize(struct zip_dirent *zde) -PHPZIPAPI void +void _zip_dirent_init(struct zip_dirent *de) { de->version_madeby = 0; @@ -188,7 +183,7 @@ _zip_dirent_init(struct zip_dirent *de) returned. */ -PHPZIPAPI int +int _zip_dirent_read(struct zip_dirent *zde, FILE *fp, unsigned char **bufp, unsigned int left, int localp, struct zip_error *error) @@ -323,6 +318,63 @@ _zip_dirent_read(struct zip_dirent *zde, FILE *fp, +/* _zip_dirent_torrent_normalize(de); + Set values suitable for torrentzip. +*/ + +void +_zip_dirent_torrent_normalize(struct zip_dirent *de) +{ + static struct tm torrenttime; + static time_t last_mod = 0; + + if (last_mod == 0) { +#ifdef HAVE_STRUCT_TM_TM_ZONE + time_t now; + struct tm *l; +#endif + + torrenttime.tm_sec = 0; + torrenttime.tm_min = 32; + torrenttime.tm_hour = 23; + torrenttime.tm_mday = 24; + torrenttime.tm_mon = 11; + torrenttime.tm_year = 96; + torrenttime.tm_wday = 0; + torrenttime.tm_yday = 0; + torrenttime.tm_isdst = 0; + +#ifdef HAVE_STRUCT_TM_TM_ZONE + time(&now); + l = localtime(&now); + torrenttime.tm_gmtoff = l->tm_gmtoff; + torrenttime.tm_zone = l->tm_zone; +#endif + + last_mod = mktime(&torrenttime); + } + + de->version_madeby = 0; + de->version_needed = 20; /* 2.0 */ + de->bitflags = 2; /* maximum compression */ + de->comp_method = ZIP_CM_DEFLATE; + de->last_mod = last_mod; + + de->disk_number = 0; + de->int_attrib = 0; + de->ext_attrib = 0; + de->offset = 0; + + free(de->extrafield); + de->extrafield = NULL; + de->extrafield_len = 0; + free(de->comment); + de->comment = NULL; + de->comment_len = 0; +} + + + /* _zip_dirent_write(zde, fp, localp, error): Writes zip directory entry zde to file fp. @@ -333,7 +385,7 @@ _zip_dirent_read(struct zip_dirent *zde, FILE *fp, returned. */ -PHPZIPAPI int +int _zip_dirent_write(struct zip_dirent *zde, FILE *fp, int localp, struct zip_error *error) { @@ -390,11 +442,13 @@ _zip_dirent_write(struct zip_dirent *zde, FILE *fp, int localp, static time_t _zip_d2u_time(int dtime, int ddate) { - struct tm *tm, tmbuf; + struct tm *tm; time_t now; now = time(NULL); - tm = php_localtime_r(&now, &tmbuf); + tm = localtime(&now); + /* let mktime decide if DST is in effect */ + tm->tm_isdst = -1; tm->tm_year = ((ddate>>9)&127) + 1980 - 1900; tm->tm_mon = ((ddate>>5)&15) - 1; @@ -409,7 +463,7 @@ _zip_d2u_time(int dtime, int ddate) -PHPZIPAPI unsigned short +unsigned short _zip_read2(unsigned char **a) { unsigned short ret; @@ -422,7 +476,7 @@ _zip_read2(unsigned char **a) -PHPZIPAPI unsigned int +unsigned int _zip_read4(unsigned char **a) { unsigned int ret; @@ -519,9 +573,9 @@ _zip_write4(unsigned int i, FILE *fp) static void _zip_u2d_time(time_t time, unsigned short *dtime, unsigned short *ddate) { - struct tm *tm, tmbuf; + struct tm *tm; - tm = php_localtime_r(&time, &tmbuf); + tm = localtime(&time); *ddate = ((tm->tm_year+1900-1980)<<9) + ((tm->tm_mon+1)<<5) + tm->tm_mday; *dtime = ((tm->tm_hour)<<11) + ((tm->tm_min)<<5) diff --git a/ext/zip/lib/zip_entry_free.c b/ext/zip/lib/zip_entry_free.c index 1bab313ed5..c50c9434bd 100644 --- a/ext/zip/lib/zip_entry_free.c +++ b/ext/zip/lib/zip_entry_free.c @@ -1,11 +1,9 @@ /* - $NiH: zip_entry_free.c,v 1.2 2006/04/09 19:05:47 wiz Exp $ - zip_entry_free.c -- free struct zip_entry - Copyright (C) 1999, 2003, 2004, 2006 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -37,12 +35,11 @@ #include <stdlib.h> -#include "zip.h" #include "zipint.h" -PHPZIPAPI void +void _zip_entry_free(struct zip_entry *ze) { free(ze->ch_filename); diff --git a/ext/zip/lib/zip_entry_new.c b/ext/zip/lib/zip_entry_new.c index 67e13fd84a..7059b1b060 100644 --- a/ext/zip/lib/zip_entry_new.c +++ b/ext/zip/lib/zip_entry_new.c @@ -1,11 +1,9 @@ /* - $NiH: zip_entry_new.c,v 1.2 2006/04/09 19:05:47 wiz Exp $ - zip_entry_new.c -- create and init struct zip_entry - Copyright (C) 1999, 2003, 2004, 2006 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -37,12 +35,11 @@ #include <stdlib.h> -#include "zip.h" #include "zipint.h" -PHPZIPAPI struct zip_entry * +struct zip_entry * _zip_entry_new(struct zip *za) { struct zip_entry *ze; diff --git a/ext/zip/lib/zip_err_str.c b/ext/zip/lib/zip_err_str.c index c74538d64a..3fcdf1738a 100644 --- a/ext/zip/lib/zip_err_str.c +++ b/ext/zip/lib/zip_err_str.c @@ -1,12 +1,8 @@ /* This file was generated automatically by ./make_zip_err_str.sh from ./zip.h; make changes there. - - NiH: make_zip_err_str.sh,v 1.8 2004/11/17 21:55:09 wiz Exp - NiH: zip.h,v 1.57 2006/04/24 14:04:19 dillo Exp */ -#include "zip.h" #include "zipint.h" diff --git a/ext/zip/lib/zip_error.c b/ext/zip/lib/zip_error.c index 4816b73aea..aab7079456 100644 --- a/ext/zip/lib/zip_error.c +++ b/ext/zip/lib/zip_error.c @@ -1,11 +1,9 @@ /* - $NiH: zip_error.c,v 1.7 2005/06/09 19:57:09 dillo Exp $ - zip_error.c -- struct zip_error helper functions - Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -37,12 +35,11 @@ #include <stdlib.h> -#include "zip.h" #include "zipint.h" -PHPZIPAPI void +void _zip_error_clear(struct zip_error *err) { err->zip_err = ZIP_ER_OK; @@ -51,7 +48,7 @@ _zip_error_clear(struct zip_error *err) -PHPZIPAPI void +void _zip_error_copy(struct zip_error *dst, struct zip_error *src) { dst->zip_err = src->zip_err; @@ -60,7 +57,7 @@ _zip_error_copy(struct zip_error *dst, struct zip_error *src) -PHPZIPAPI void +void _zip_error_fini(struct zip_error *err) { free(err->str); @@ -69,7 +66,7 @@ _zip_error_fini(struct zip_error *err) -PHPZIPAPI void +void _zip_error_get(struct zip_error *err, int *zep, int *sep) { if (zep) @@ -84,7 +81,7 @@ _zip_error_get(struct zip_error *err, int *zep, int *sep) -PHPZIPAPI void +void _zip_error_init(struct zip_error *err) { err->zip_err = ZIP_ER_OK; @@ -94,7 +91,7 @@ _zip_error_init(struct zip_error *err) -PHPZIPAPI void +void _zip_error_set(struct zip_error *err, int ze, int se) { if (err) { diff --git a/ext/zip/lib/zip_error_clear.c b/ext/zip/lib/zip_error_clear.c index 8a76f44400..34e7dea48e 100644 --- a/ext/zip/lib/zip_error_clear.c +++ b/ext/zip/lib/zip_error_clear.c @@ -1,11 +1,9 @@ /* - $NiH: zip_error_clear.c,v 1.1 2006/10/04 15:21:09 dillo Exp $ - zip_error_clear.c -- clear zip error - Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -35,12 +33,11 @@ -#include "zip.h" #include "zipint.h" -PHPZIPAPI void +ZIP_EXTERN(void) zip_error_clear(struct zip *za) { _zip_error_clear(&za->error); diff --git a/ext/zip/lib/zip_error_get.c b/ext/zip/lib/zip_error_get.c index 888b545693..c15705e32f 100644 --- a/ext/zip/lib/zip_error_get.c +++ b/ext/zip/lib/zip_error_get.c @@ -1,11 +1,9 @@ /* - $NiH: zip_error_get.c,v 1.1 2004/11/18 15:06:20 wiz Exp $ - zip_error_get.c -- get zip error - Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -35,12 +33,11 @@ -#include "zip.h" #include "zipint.h" -PHPZIPAPI void +ZIP_EXTERN(void) zip_error_get(struct zip *za, int *zep, int *sep) { _zip_error_get(&za->error, zep, sep); diff --git a/ext/zip/lib/zip_error_get_sys_type.c b/ext/zip/lib/zip_error_get_sys_type.c index bfe6423836..47aa93e69b 100644 --- a/ext/zip/lib/zip_error_get_sys_type.c +++ b/ext/zip/lib/zip_error_get_sys_type.c @@ -1,11 +1,9 @@ /* - $NiH: zip_error_get_sys_type.c,v 1.1 2004/12/22 15:49:18 wiz Exp $ - zip_error_get_sys_type.c -- return type of system error code - Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -35,12 +33,11 @@ -#include "zip.h" #include "zipint.h" -PHPZIPAPI int +ZIP_EXTERN(int) zip_error_get_sys_type(int ze) { if (ze < 0 || ze >= _zip_nerr_str) diff --git a/ext/zip/lib/zip_error_strerror.c b/ext/zip/lib/zip_error_strerror.c index 06e98c76d8..3d0951cfb1 100644 --- a/ext/zip/lib/zip_error_strerror.c +++ b/ext/zip/lib/zip_error_strerror.c @@ -1,11 +1,9 @@ /* - $NiH: zip_error_strerror.c,v 1.4 2006/02/21 09:41:00 dillo Exp $ - zip_error_sterror.c -- get string representation of struct zip_error - Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -40,12 +38,11 @@ #include <stdlib.h> #include <string.h> -#include "zip.h" #include "zipint.h" -PHPZIPAPI const char * +const char * _zip_error_strerror(struct zip_error *err) { const char *zs, *ss; @@ -54,7 +51,7 @@ _zip_error_strerror(struct zip_error *err) _zip_error_fini(err); if (err->zip_err < 0 || err->zip_err >= _zip_nerr_str) { - snprintf(buf, sizeof(buf), "Unknown error %d", err->zip_err); + sprintf(buf, "Unknown error %d", err->zip_err); zs = NULL; ss = buf; } @@ -78,16 +75,16 @@ _zip_error_strerror(struct zip_error *err) if (ss == NULL) return zs; else { - int l = strlen(ss) + (zs ? strlen(zs)+2 : 0) + 1; - if ((s=(char *)malloc(l)) == NULL) + if ((s=(char *)malloc(strlen(ss) + + (zs ? strlen(zs)+2 : 0) + 1)) == NULL) return _zip_err_str[ZIP_ER_MEMORY]; - snprintf(s, l, "%s%s%s", + sprintf(s, "%s%s%s", (zs ? zs : ""), (zs ? ": " : ""), ss); err->str = s; - return ss; + return s; } } diff --git a/ext/zip/lib/zip_error_to_str.c b/ext/zip/lib/zip_error_to_str.c index 665803472e..4dea4d667a 100644 --- a/ext/zip/lib/zip_error_to_str.c +++ b/ext/zip/lib/zip_error_to_str.c @@ -1,11 +1,9 @@ /* - $NiH: zip_error_to_str.c,v 1.1 2004/11/18 15:06:20 wiz Exp $ - zip_error_to_str.c -- get string representation of zip error code - Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -40,12 +38,11 @@ #include <stdlib.h> #include <string.h> -#include "zip.h" #include "zipint.h" -PHPZIPAPI int +ZIP_EXTERN(int) zip_error_to_str(char *buf, size_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 91f30b7bb9..8f062d9d09 100644 --- a/ext/zip/lib/zip_fclose.c +++ b/ext/zip/lib/zip_fclose.c @@ -1,11 +1,9 @@ /* - $NiH: zip_fclose.c,v 1.14 2005/06/09 19:57:09 dillo Exp $ - zip_fclose.c -- close file in zip archive - Copyright (C) 1999, 2004, 2005 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -37,12 +35,11 @@ #include <stdlib.h> -#include "zip.h" #include "zipint.h" -PHPZIPAPI int +ZIP_EXTERN(int) zip_fclose(struct zip_file *zf) { int i, ret; @@ -51,7 +48,6 @@ zip_fclose(struct zip_file *zf) 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) { diff --git a/ext/zip/lib/zip_file_error_clear.c b/ext/zip/lib/zip_file_error_clear.c index dca33b35f7..6c9c2a02b3 100644 --- a/ext/zip/lib/zip_file_error_clear.c +++ b/ext/zip/lib/zip_file_error_clear.c @@ -1,11 +1,9 @@ /* - $NiH: zip_file_error_clear.c,v 1.4 2006/10/04 18:37:54 wiz Exp $ - zip_file_error_clear.c -- clear zip file error - Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -35,12 +33,11 @@ -#include "zip.h" #include "zipint.h" -PHPZIPAPI void +ZIP_EXTERN(void) zip_file_error_clear(struct zip_file *zf) { _zip_error_clear(&zf->error); diff --git a/ext/zip/lib/zip_file_error_get.c b/ext/zip/lib/zip_file_error_get.c index 05516703c6..a53fa7e003 100644 --- a/ext/zip/lib/zip_file_error_get.c +++ b/ext/zip/lib/zip_file_error_get.c @@ -1,11 +1,9 @@ /* - $NiH: zip_file_error_get.c,v 1.1 2004/11/18 15:06:21 wiz Exp $ - zip_file_error_get.c -- get zip file error - Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -35,12 +33,11 @@ -#include "zip.h" #include "zipint.h" -PHPZIPAPI void +ZIP_EXTERN(void) zip_file_error_get(struct zip_file *zf, int *zep, int *sep) { _zip_error_get(&zf->error, zep, sep); diff --git a/ext/zip/lib/zip_file_get_offset.c b/ext/zip/lib/zip_file_get_offset.c index 4930040235..68f92f1fe6 100644 --- a/ext/zip/lib/zip_file_get_offset.c +++ b/ext/zip/lib/zip_file_get_offset.c @@ -1,11 +1,9 @@ /* - $NiH: zip_file_get_offset.c,v 1.4 2006/04/23 14:51:45 wiz Exp $ - zip_file_get_offset.c -- get offset of file data in archive. - Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -39,13 +37,9 @@ #include <stdlib.h> #include <string.h> #include <errno.h> -#ifndef _MSC_VER -#include <unistd.h> -#endif #include <sys/types.h> #include <sys/stat.h> -#include "zip.h" #include "zipint.h" @@ -56,7 +50,7 @@ On error, fills in za->error and returns 0. */ -PHPZIPAPI unsigned int +unsigned int _zip_file_get_offset(struct zip *za, int idx) { struct zip_dirent de; @@ -64,7 +58,7 @@ _zip_file_get_offset(struct zip *za, int idx) offset = za->cdir->entry[idx].offset; - if (fseek(za->zp, offset, SEEK_SET) != 0) { + if (fseeko(za->zp, offset, SEEK_SET) != 0) { _zip_error_set(&za->error, ZIP_ER_SEEK, errno); return 0; } diff --git a/ext/zip/lib/zip_file_strerror.c b/ext/zip/lib/zip_file_strerror.c index 2cc79c1333..c2864f2ba1 100644 --- a/ext/zip/lib/zip_file_strerror.c +++ b/ext/zip/lib/zip_file_strerror.c @@ -1,11 +1,9 @@ /* - $NiH: zip_file_strerror.c,v 1.1 2003/10/05 16:05:22 dillo Exp $ - zip_file_sterror.c -- get string representation of zip file error - Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -35,12 +33,11 @@ -#include "zip.h" #include "zipint.h" -PHPZIPAPI const char * +ZIP_EXTERN(const char *) zip_file_strerror(struct zip_file *zf) { return _zip_error_strerror(&zf->error); diff --git a/ext/zip/lib/zip_fopen.c b/ext/zip/lib/zip_fopen.c index c05ad45bd6..b4b76049f4 100644 --- a/ext/zip/lib/zip_fopen.c +++ b/ext/zip/lib/zip_fopen.c @@ -1,11 +1,9 @@ /* - $NiH: zip_fopen.c,v 1.12 2005/06/09 19:57:09 dillo Exp $ - zip_fopen.c -- open file in zip archive for reading - Copyright (C) 1999, 2003, 2004, 2005 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -35,12 +33,11 @@ -#include "zip.h" #include "zipint.h" -PHPZIPAPI struct zip_file * +ZIP_EXTERN(struct zip_file *) zip_fopen(struct zip *za, const char *fname, int flags) { int idx; diff --git a/ext/zip/lib/zip_fopen_index.c b/ext/zip/lib/zip_fopen_index.c index 105cefe738..1e7e419897 100644 --- a/ext/zip/lib/zip_fopen_index.c +++ b/ext/zip/lib/zip_fopen_index.c @@ -1,11 +1,9 @@ /* - $NiH: zip_fopen_index.c,v 1.24 2005/05/20 21:54:53 wiz Exp $ - zip_fopen_index.c -- open file in zip archive for reading by index - Copyright (C) 1999, 2004, 2005 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -39,14 +37,13 @@ #include <stdio.h> #include <stdlib.h> -#include "zip.h" #include "zipint.h" static struct zip_file *_zip_file_new(struct zip *za); -PHPZIPAPI struct zip_file * +ZIP_EXTERN(struct zip_file *) zip_fopen_index(struct zip *za, int fileno, int flags) { int len, ret; @@ -141,7 +138,7 @@ zip_fopen_index(struct zip *za, int fileno, int flags) -PHPZIPAPI int +int _zip_file_fillbuf(void *buf, size_t buflen, struct zip_file *zf) { int i, j; @@ -152,7 +149,7 @@ _zip_file_fillbuf(void *buf, size_t buflen, struct zip_file *zf) if ((zf->flags & ZIP_ZF_EOF) || zf->cbytes_left <= 0 || buflen <= 0) return 0; - if (fseek(zf->za->zp, zf->fpos, SEEK_SET) < 0) { + if (fseeko(zf->za->zp, zf->fpos, SEEK_SET) < 0) { _zip_error_set(&zf->error, ZIP_ER_SEEK, errno); return -1; } diff --git a/ext/zip/lib/zip_fread.c b/ext/zip/lib/zip_fread.c index 064d2b97fb..1a2b0e3816 100644 --- a/ext/zip/lib/zip_fread.c +++ b/ext/zip/lib/zip_fread.c @@ -1,11 +1,9 @@ /* - $NiH: zip_fread.c,v 1.21 2006/04/23 14:49:50 wiz Exp $ - zip_fread.c -- read from file - Copyright (C) 1999, 2004, 2005 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -35,12 +33,11 @@ -#include "zip.h" #include "zipint.h" -PHPZIPAPI ssize_t +ZIP_EXTERN(ssize_t) zip_fread(struct zip_file *zf, void *outbuf, size_t toread) { int ret; diff --git a/ext/zip/lib/zip_free.c b/ext/zip/lib/zip_free.c index 534c58eb07..76c3a9673f 100644 --- a/ext/zip/lib/zip_free.c +++ b/ext/zip/lib/zip_free.c @@ -1,11 +1,9 @@ /* - $NiH: zip_free.c,v 1.17 2005/06/09 19:57:10 dillo Exp $ - zip_free.c -- free struct zip - Copyright (C) 1999, 2004, 2005 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -36,7 +34,7 @@ #include <stdlib.h> -#include "zip.h" + #include "zipint.h" @@ -45,7 +43,7 @@ frees the space allocated to a zipfile struct, and closes the corresponding file. */ -PHPZIPAPI void +void _zip_free(struct zip *za) { int i; @@ -59,9 +57,6 @@ _zip_free(struct zip *za) if (za->zp) fclose(za->zp); - if (za->ch_comment) - free(za->ch_comment); - _zip_cdir_free(za->cdir); if (za->entry) { diff --git a/ext/zip/lib/zip_get_archive_comment.c b/ext/zip/lib/zip_get_archive_comment.c index c23597c096..ed1324fd5b 100644 --- a/ext/zip/lib/zip_get_archive_comment.c +++ b/ext/zip/lib/zip_get_archive_comment.c @@ -1,11 +1,9 @@ /* - $NiH: zip_get_archive_comment.c,v 1.4 2006/04/23 16:11:33 wiz Exp $ - zip_get_archive_comment.c -- get archive comment - Copyright (C) 2006 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -35,12 +33,11 @@ -#include "zip.h" #include "zipint.h" -PHPZIPAPI const char * +ZIP_EXTERN(const char *) zip_get_archive_comment(struct zip *za, int *lenp, int flags) { if ((flags & ZIP_FL_UNCHANGED) @@ -50,6 +47,11 @@ zip_get_archive_comment(struct zip *za, int *lenp, int flags) *lenp = za->cdir->comment_len; return za->cdir->comment; } + else { + if (lenp != NULL) + *lenp = -1; + return NULL; + } } if (lenp != NULL) diff --git a/ext/zip/lib/zip_get_file_comment.c b/ext/zip/lib/zip_get_file_comment.c index 476ac7da0b..57dd9028bc 100644 --- a/ext/zip/lib/zip_get_file_comment.c +++ b/ext/zip/lib/zip_get_file_comment.c @@ -1,11 +1,9 @@ /* - $NiH: zip_get_file_comment.c,v 1.2 2006/04/23 13:06:28 wiz Exp $ - zip_get_file_comment.c -- get file comment - Copyright (C) 2006 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -35,12 +33,11 @@ -#include "zip.h" #include "zipint.h" -PHPZIPAPI const char * +ZIP_EXTERN(const char *) zip_get_file_comment(struct zip *za, int idx, int *lenp, int flags) { if (idx < 0 || idx >= za->nentry) { diff --git a/ext/zip/lib/zip_get_name.c b/ext/zip/lib/zip_get_name.c index c2cae2518e..b58d972058 100644 --- a/ext/zip/lib/zip_get_name.c +++ b/ext/zip/lib/zip_get_name.c @@ -1,11 +1,9 @@ /* - $NiH: zip_get_name.c,v 1.13 2005/01/20 21:00:54 dillo Exp $ - zip_get_name.c -- get filename for a file in zip file - Copyright (C) 1999, 2003, 2004, 2005 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -35,12 +33,11 @@ -#include "zip.h" #include "zipint.h" -PHPZIPAPI const char * +ZIP_EXTERN(const char *) zip_get_name(struct zip *za, int idx, int flags) { return _zip_get_name(za, idx, flags, &za->error); @@ -48,7 +45,7 @@ zip_get_name(struct zip *za, int idx, int flags) -PHPZIPAPI const char * +const char * _zip_get_name(struct zip *za, int idx, int flags, struct zip_error *error) { if (idx < 0 || idx >= za->nentry) { diff --git a/ext/zip/lib/zip_get_num_files.c b/ext/zip/lib/zip_get_num_files.c index 05a54fcb6c..a442f293ec 100644 --- a/ext/zip/lib/zip_get_num_files.c +++ b/ext/zip/lib/zip_get_num_files.c @@ -1,11 +1,9 @@ /* - $NiH: zip_get_num_files.c,v 1.2 2003/12/27 22:53:15 wiz Exp $ - zip_get_num_files.c -- get number of files in archive - Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -35,12 +33,11 @@ -#include "zip.h" #include "zipint.h" -PHPZIPAPI int +ZIP_EXTERN(int) zip_get_num_files(struct zip *za) { if (za == NULL) diff --git a/ext/zip/lib/zip_memdup.c b/ext/zip/lib/zip_memdup.c index ebb7426dd2..641125ed2d 100644 --- a/ext/zip/lib/zip_memdup.c +++ b/ext/zip/lib/zip_memdup.c @@ -1,11 +1,9 @@ /* - $NiH: zip_memdup.c,v 1.2 2006/04/24 10:34:39 dillo Exp $ - zip_memdup.c -- internal zip function, "strdup" with len - Copyright (C) 1999, 2003, 2004, 2005, 2006 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -36,12 +34,11 @@ #include <stdlib.h> #include <string.h> -#include "zip.h" #include "zipint.h" -PHPZIPAPI void * +void * _zip_memdup(const void *mem, size_t len, struct zip_error *error) { void *ret; diff --git a/ext/zip/lib/zip_name_locate.c b/ext/zip/lib/zip_name_locate.c index 108db4f609..e8b35ff936 100644 --- a/ext/zip/lib/zip_name_locate.c +++ b/ext/zip/lib/zip_name_locate.c @@ -1,11 +1,9 @@ /* - $NiH: zip_name_locate.c,v 1.19 2005/06/09 19:57:10 dillo Exp $ - zip_name_locate.c -- get index by name - Copyright (C) 1999, 2003, 2004, 2005 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -19,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 @@ -37,12 +35,11 @@ #include <string.h> -#include "zip.h" #include "zipint.h" -PHPZIPAPI int +ZIP_EXTERN(int) zip_name_locate(struct zip *za, const char *fname, int flags) { return _zip_name_locate(za, fname, flags, &za->error); @@ -50,7 +47,7 @@ zip_name_locate(struct zip *za, const char *fname, int flags) -PHPZIPAPI int +int _zip_name_locate(struct zip *za, const char *fname, int flags, struct zip_error *error) { @@ -62,11 +59,8 @@ _zip_name_locate(struct zip *za, const char *fname, int flags, _zip_error_set(error, ZIP_ER_INVAL, 0); return -1; } -#ifdef PHP_WIN32 - cmp = (flags & ZIP_FL_NOCASE) ? stricmp : strcmp; -#else - cmp = (flags & ZIP_FL_NOCASE) ? strcasecmp : strcmp; -#endif + + cmp = (flags & ZIP_FL_NOCASE) ? strcmpi : strcmp; n = (flags & ZIP_FL_UNCHANGED) ? za->cdir->nentry : za->nentry; for (i=0; i<n; i++) { @@ -78,7 +72,7 @@ _zip_name_locate(struct zip *za, const char *fname, int flags, /* newly added (partially filled) entry */ if (fn == NULL) continue; - + if (flags & ZIP_FL_NODIR) { p = strrchr(fn, '/'); if (p) @@ -89,6 +83,7 @@ _zip_name_locate(struct zip *za, const char *fname, int flags, return i; } - _zip_error_set(error, ZIP_ER_NOENT, 0); +/* Look for an entry should not raise an error */ +/* _zip_error_set(error, ZIP_ER_NOENT, 0);*/ return -1; } diff --git a/ext/zip/lib/zip_new.c b/ext/zip/lib/zip_new.c index 378513b6cf..3e8ccee644 100644 --- a/ext/zip/lib/zip_new.c +++ b/ext/zip/lib/zip_new.c @@ -1,11 +1,9 @@ /* - $NiH: zip_new.c,v 1.12 2006/04/23 00:40:47 wiz Exp $ - zip_new.c -- create and init struct zip - Copyright (C) 1999, 2004, 2005 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -36,7 +34,7 @@ #include <stdlib.h> -#include "zip.h" + #include "zipint.h" @@ -45,7 +43,7 @@ creates a new zipfile struct, and sets the contents to zero; returns the new struct. */ -PHPZIPAPI struct zip * +struct zip * _zip_new(struct zip_error *error) { struct zip *za; @@ -66,6 +64,7 @@ _zip_new(struct zip_error *error) za->entry = NULL; za->nfile = za->nfile_alloc = 0; za->file = NULL; + za->flags = za->ch_flags = 0; return za; } diff --git a/ext/zip/lib/zip_open.c b/ext/zip/lib/zip_open.c index 711dcb1cac..cb3e66d2ca 100644 --- a/ext/zip/lib/zip_open.c +++ b/ext/zip/lib/zip_open.c @@ -1,11 +1,9 @@ /* - $NiH: zip_open.c,v 1.38 2006/05/04 00:01:26 dillo Exp $ - zip_open.c -- open zip archive Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -37,18 +35,19 @@ #include <sys/stat.h> #include <errno.h> +#include <limits.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#ifndef _MSC_VER -#include <unistd.h> -#endif -#include <sys/types.h> -#include "zip.h" + #include "zipint.h" static void set_error(int *, struct zip_error *, int); +static struct zip *_zip_allocate_new(const char *, int *); static int _zip_checkcons(FILE *, struct zip_cdir *, struct zip_error *); +static void _zip_check_torrentzip(struct zip *); +static struct zip_cdir *_zip_find_central_dir(FILE *, int, int *, off_t); +static int _zip_file_exists(const char *, int, int *); static int _zip_headercomp(struct zip_dirent *, int, struct zip_dirent *, int); static unsigned char *_zip_memmem(const unsigned char *, int, @@ -58,154 +57,55 @@ static struct zip_cdir *_zip_readcdir(FILE *, unsigned char *, unsigned char *, -PHPZIPAPI struct zip * +ZIP_EXTERN(struct zip *) zip_open(const char *fn, int flags, int *zep) { FILE *fp; - unsigned char *buf, *match; - int a, i, buflen, best; struct zip *za; - struct zip_cdir *cdir, *cdirnew; - long len; - struct stat st; - struct zip_error error, err2; - - if (fn == NULL) { - set_error(zep, NULL, ZIP_ER_INVAL); + struct zip_cdir *cdir; + int i; + off_t len; + + switch (_zip_file_exists(fn, flags, zep)) { + case -1: return NULL; + case 0: + return _zip_allocate_new(fn, zep); + default: + break; } - if (flags & ZIP_OVERWRITE || stat(fn, &st) != 0) { - if ((flags & ZIP_CREATE) || (flags & ZIP_OVERWRITE)) { - if ((za=_zip_new(&error)) == NULL) { - 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; - } - return za; - } - else { - set_error(zep, NULL, ZIP_ER_OPEN); - return NULL; - } - } - else if ((flags & ZIP_EXCL)) { - set_error(zep, NULL, ZIP_ER_EXISTS); + if ((fp=fopen(fn, "rb")) == NULL) { + set_error(zep, NULL, ZIP_ER_OPEN); return NULL; } - /* ZIP_CREATE gets ignored if file exists and not ZIP_EXCL, - just like open() */ - if ((fp=fopen(fn, "rb")) == NULL) { - set_error(zep, NULL, ZIP_ER_OPEN); - return NULL; - } - -#ifdef PHP_WIN32 - _setmode(_fileno(fp), _O_BINARY ); -#endif + fseeko(fp, 0, SEEK_END); + len = ftello(fp); - clearerr(fp); - fseek(fp, 0, SEEK_END); - len = ftell(fp); - i = fseek(fp, -(len < CDBUFSIZE ? len : CDBUFSIZE), SEEK_END); - if (i == -1 && errno != EFBIG) { - /* seek before start of file on my machine */ - set_error(zep, NULL, ZIP_ER_SEEK); - fclose(fp); - return NULL; - } - - /* 64k is too much for stack */ - if ((buf=(unsigned char *)malloc(CDBUFSIZE)) == NULL) { - set_error(zep, NULL, ZIP_ER_MEMORY); - fclose(fp); - return NULL; + /* treat empty files as empty archives */ + if (len == 0) { + if ((za=_zip_allocate_new(fn, zep)) == NULL) + fclose(fp); + else + za->zp = fp; + return za; } - clearerr(fp); - buflen = fread(buf, 1, CDBUFSIZE, fp); - - if (ferror(fp)) { - set_error(zep, NULL, ZIP_ER_READ); - free(buf); + cdir = _zip_find_central_dir(fp, flags, zep, len); + if (cdir == NULL) { fclose(fp); return NULL; } - - best = -2; - cdir = NULL; - match = buf; - while ((match=_zip_memmem(match, buflen-(match-buf)-18, - (const unsigned char *)EOCD_MAGIC, 4))!=NULL) { - /* 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, - &err2)) == NULL) { - if (best == -2) { - set_error(zep, &err2, 0); - best = -1; - } - continue; - } - if (cdir) { - if (best <= 0) - best = _zip_checkcons(fp, cdir, &err2); - a = _zip_checkcons(fp, cdirnew, &err2); - if (best < a) { - _zip_cdir_free(cdir); - cdir = cdirnew; - best = a; - } - else - _zip_cdir_free(cdirnew); - } - else { - cdir = cdirnew; - if (flags & ZIP_CHECKCONS) - best = _zip_checkcons(fp, cdir, &err2); - else - best = 0; - } - cdirnew = NULL; - } - - free(buf); - - if (best < 0) { - /* no consistent eocd found */ - if (best == -2) { - /* no eocd found at all */ - set_error(zep, NULL, ZIP_ER_NOZIP); - } - _zip_cdir_free(cdir); - fclose(fp); - return NULL; - } - - if ((za=_zip_new(&error)) == NULL) { - set_error(zep, &error, 0); + if ((za=_zip_allocate_new(fn, zep)) == NULL) { _zip_cdir_free(cdir); fclose(fp); return NULL; } - za->zp = fp; za->cdir = cdir; - - if ((za->zn=strdup(fn)) == NULL) { - set_error(zep, NULL, ZIP_ER_MEMORY); - _zip_free(za); - return NULL; - } + za->zp = fp; if ((za->entry=(struct zip_entry *)malloc(sizeof(*(za->entry)) * cdir->nentry)) == NULL) { @@ -216,6 +116,9 @@ zip_open(const char *fn, int flags, int *zep) for (i=0; i<cdir->nentry; i++) _zip_entry_new(za); + _zip_check_torrentzip(za); + za->ch_flags = za->flags; + return za; } @@ -295,13 +198,14 @@ _zip_readcdir(FILE *fp, unsigned char *buf, unsigned char *eocd, int buflen, return NULL; } - if (cd->comment_len) + if (cd->comment_len) { if ((cd->comment=(char *)_zip_memdup(eocd+EOCDLEN, cd->comment_len, error)) == NULL) { free(cd); return NULL; } + } cdp = eocd; if (cd->size < (unsigned int)(eocd-buf)) { @@ -313,8 +217,10 @@ _zip_readcdir(FILE *fp, unsigned char *buf, unsigned char *eocd, int buflen, /* go to start of cdir and read it entry by entry */ bufp = NULL; clearerr(fp); - fseek(fp, -(cd->size+cd->comment_len+EOCDLEN), SEEK_END); - if (ferror(fp) || ((unsigned int)ftell(fp) != cd->offset)) { + fseeko(fp, cd->offset, SEEK_SET); + /* possible consistency check: cd->offset = + len-(cd->size+cd->comment_len+EOCDLEN) ? */ + if (ferror(fp) || ((unsigned long)ftello(fp) != cd->offset)) { /* seek error or offset of cdir wrong */ if (ferror(fp)) _zip_error_set(error, ZIP_ER_SEEK, errno); @@ -376,7 +282,7 @@ _zip_checkcons(FILE *fp, struct zip_cdir *cd, struct zip_error *error) return -1; } - if (fseek(fp, cd->entry[i].offset, SEEK_SET) != 0) { + if (fseeko(fp, cd->entry[i].offset, SEEK_SET) != 0) { _zip_error_set(error, ZIP_ER_SEEK, 0); return -1; } @@ -385,7 +291,7 @@ _zip_checkcons(FILE *fp, struct zip_cdir *cd, struct zip_error *error) return -1; if (_zip_headercomp(cd->entry+i, 0, &temp, 1) != 0) { - _zip_error_set(error, ZIP_ER_NOZIP, 0); + _zip_error_set(error, ZIP_ER_INCONS, 0); _zip_dirent_finalize(&temp); return -1; } @@ -397,6 +303,41 @@ _zip_checkcons(FILE *fp, struct zip_cdir *cd, struct zip_error *error) +/* _zip_check_torrentzip: + check wether ZA has a valid TORRENTZIP comment, i.e. is torrentzipped */ + +static void +_zip_check_torrentzip(struct zip *za) +{ + uLong crc_got, crc_should; + char buf[8+1]; + char *end; + + if (za->zp == NULL || za->cdir == NULL) + return; + + if (za->cdir->comment_len != TORRENT_SIG_LEN+8 + || strncmp(za->cdir->comment, TORRENT_SIG, TORRENT_SIG_LEN) != 0) + return; + + memcpy(buf, za->cdir->comment+TORRENT_SIG_LEN, 8); + buf[8] = '\0'; + errno = 0; + crc_should = strtoul(buf, &end, 16); + if ((crc_should == UINT_MAX && errno != 0) || (end && *end)) + return; + + if (_zip_filerange_crc(za->zp, za->cdir->offset, za->cdir->size, + &crc_got, NULL) < 0) + return; + + if (crc_got == crc_should) + za->flags |= ZIP_AFL_TORRENT; +} + + + + /* _zip_headercomp: compares two headers h1 and h2; if they are local headers, set local1p or local2p respectively to 1, else 0. Return 0 if they @@ -414,14 +355,32 @@ _zip_headercomp(struct zip_dirent *h1, int local1p, struct zip_dirent *h2, #endif || (h1->comp_method != h2->comp_method) || (h1->last_mod != h2->last_mod) - || (h1->crc != h2->crc) - || (h1->comp_size != h2->comp_size) - || (h1->uncomp_size != h2->uncomp_size) || (h1->filename_len != h2->filename_len) || !h1->filename || !h2->filename || strcmp(h1->filename, h2->filename)) return -1; + /* check that CRC and sizes are zero if data descriptor is used */ + if ((h1->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) && local1p + && (h1->crc != 0 + || h1->comp_size != 0 + || h1->uncomp_size != 0)) + return -1; + if ((h2->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) && local2p + && (h2->crc != 0 + || h2->comp_size != 0 + || h2->uncomp_size != 0)) + return -1; + + /* check that CRC and sizes are equal if no data descriptor is used */ + if (((h1->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0 || local1p == 0) + && ((h2->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0 || local2p == 0)) { + if ((h1->crc != h2->crc) + || (h1->comp_size != h2->comp_size) + || (h1->uncomp_size != h2->uncomp_size)) + return -1; + } + if ((local1p == local2p) && ((h1->extrafield_len != h2->extrafield_len) || (h1->extrafield_len && h2->extrafield @@ -448,6 +407,137 @@ _zip_headercomp(struct zip_dirent *h1, int local1p, struct zip_dirent *h2, +static struct zip * +_zip_allocate_new(const char *fn, int *zep) +{ + struct zip *za; + struct zip_error error; + + if ((za=_zip_new(&error)) == NULL) { + 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; + } + return za; +} + + + +static int +_zip_file_exists(const char *fn, int flags, int *zep) +{ + struct stat st; + + if (fn == NULL) { + set_error(zep, NULL, ZIP_ER_INVAL); + return -1; + } + + if (stat(fn, &st) != 0) { + if (flags & ZIP_CREATE) + return 0; + else { + set_error(zep, NULL, ZIP_ER_OPEN); + return -1; + } + } + else if ((flags & ZIP_EXCL)) { + set_error(zep, NULL, ZIP_ER_EXISTS); + return -1; + } + /* ZIP_CREATE gets ignored if file exists and not ZIP_EXCL, + just like open() */ + + return 1; +} + + + +static struct zip_cdir * +_zip_find_central_dir(FILE *fp, int flags, int *zep, off_t len) +{ + struct zip_cdir *cdir, *cdirnew; + unsigned char *buf, *match; + int a, best, buflen, i; + struct zip_error zerr; + + i = fseeko(fp, -(len < CDBUFSIZE ? len : CDBUFSIZE), SEEK_END); + if (i == -1 && errno != EFBIG) { + /* seek before start of file on my machine */ + set_error(zep, NULL, ZIP_ER_SEEK); + return NULL; + } + + /* 64k is too much for stack */ + if ((buf=(unsigned char *)malloc(CDBUFSIZE)) == NULL) { + set_error(zep, NULL, ZIP_ER_MEMORY); + return NULL; + } + + clearerr(fp); + buflen = fread(buf, 1, CDBUFSIZE, fp); + + if (ferror(fp)) { + set_error(zep, NULL, ZIP_ER_READ); + free(buf); + return NULL; + } + + best = -1; + cdir = NULL; + match = buf; + _zip_error_set(&zerr, ZIP_ER_NOZIP, 0); + + while ((match=_zip_memmem(match, buflen-(match-buf)-18, + (const unsigned char *)EOCD_MAGIC, 4))!=NULL) { + /* 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, + &zerr)) == NULL) + continue; + + if (cdir) { + if (best <= 0) + best = _zip_checkcons(fp, cdir, &zerr); + a = _zip_checkcons(fp, cdirnew, &zerr); + if (best < a) { + _zip_cdir_free(cdir); + cdir = cdirnew; + best = a; + } + else + _zip_cdir_free(cdirnew); + } + else { + cdir = cdirnew; + if (flags & ZIP_CHECKCONS) + best = _zip_checkcons(fp, cdir, &zerr); + else + best = 0; + } + cdirnew = NULL; + } + + free(buf); + + if (best < 0) { + set_error(zep, &zerr, 0); + _zip_cdir_free(cdir); + return NULL; + } + + return cdir; +} + + + static unsigned char * _zip_memmem(const unsigned char *big, int biglen, const unsigned char *little, int littlelen) diff --git a/ext/zip/lib/zip_rename.c b/ext/zip/lib/zip_rename.c index 8141dc46a6..e57e50c390 100644 --- a/ext/zip/lib/zip_rename.c +++ b/ext/zip/lib/zip_rename.c @@ -1,11 +1,9 @@ /* - $NiH: zip_rename.c,v 1.15 2004/11/30 22:19:38 wiz Exp $ - zip_rename.c -- rename file in zip archive - Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -35,15 +33,30 @@ -#include "zip.h" +#include <string.h> + #include "zipint.h" -PHPZIPAPI int +ZIP_EXTERN(int) zip_rename(struct zip *za, int idx, const char *name) { - if (idx >= za->nentry || idx < 0) { + const char *old_name; + int old_is_dir, new_is_dir; + + if (idx >= za->nentry || idx < 0 || name[0] == '\0') { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if ((old_name=zip_get_name(za, idx, 0)) == NULL) + return -1; + + new_is_dir = (name[strlen(name)-1] == '/'); + old_is_dir = (old_name[strlen(old_name)-1] == '/'); + + if (new_is_dir != old_is_dir) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return -1; } diff --git a/ext/zip/lib/zip_replace.c b/ext/zip/lib/zip_replace.c index 12db005f28..ae69a86f63 100644 --- a/ext/zip/lib/zip_replace.c +++ b/ext/zip/lib/zip_replace.c @@ -1,11 +1,9 @@ /* - $NiH: zip_replace.c,v 1.20 2006/04/09 14:52:02 wiz Exp $ - zip_replace.c -- replace file via callback function - Copyright (C) 1999, 2003, 2004, 2006 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -35,12 +33,11 @@ -#include "zip.h" #include "zipint.h" -PHPZIPAPI int +ZIP_EXTERN(int) zip_replace(struct zip *za, int idx, struct zip_source *source) { if (idx < 0 || idx >= za->nentry || source == NULL) { @@ -57,23 +54,22 @@ zip_replace(struct zip *za, int idx, struct zip_source *source) -PHPZIPAPI int +int _zip_replace(struct zip *za, int idx, const char *name, struct zip_source *source) { - if (idx == -1) { - if (_zip_entry_new(za) == NULL) - return -1; - idx = za->nentry - 1; - } + if (idx == -1) { + if (_zip_entry_new(za) == NULL) + return -1; - + idx = za->nentry - 1; + } + _zip_unchange_data(za->entry+idx); if (name && _zip_set_name(za, idx, name) != 0) - return -1; - - + return -1; + za->entry[idx].state = ((za->cdir == NULL || idx >= za->cdir->nentry) ? ZIP_ST_ADDED : ZIP_ST_REPLACED); za->entry[idx].source = source; diff --git a/ext/zip/lib/zip_set_archive_comment.c b/ext/zip/lib/zip_set_archive_comment.c index 7649a80de9..c4bd070ddc 100644 --- a/ext/zip/lib/zip_set_archive_comment.c +++ b/ext/zip/lib/zip_set_archive_comment.c @@ -1,11 +1,9 @@ /* - $NiH: zip_set_archive_comment.c,v 1.3 2006/04/24 10:34:39 dillo Exp $ - zip_set_archive_comment.c -- set archive comment - Copyright (C) 2006 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -37,12 +35,11 @@ #include <stdlib.h> -#include "zip.h" #include "zipint.h" -PHPZIPAPI int +ZIP_EXTERN(int) zip_set_archive_comment(struct zip *za, const char *comment, int len) { char *tmpcom; @@ -60,7 +57,7 @@ zip_set_archive_comment(struct zip *za, const char *comment, int len) else tmpcom = NULL; - if (za->ch_comment) free(za->ch_comment); + free(za->ch_comment); za->ch_comment = tmpcom; za->ch_comment_len = len; diff --git a/ext/zip/lib/zip_set_file_comment.c b/ext/zip/lib/zip_set_file_comment.c index 5454aa21da..3d5dd6b5e3 100644 --- a/ext/zip/lib/zip_set_file_comment.c +++ b/ext/zip/lib/zip_set_file_comment.c @@ -1,11 +1,9 @@ /* - $NiH: zip_set_file_comment.c,v 1.4 2006/04/24 10:34:39 dillo Exp $ - zip_set_file_comment.c -- set comment for file in archive - Copyright (C) 2006 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -37,12 +35,11 @@ #include <stdlib.h> -#include "zip.h" #include "zipint.h" -PHPZIPAPI int +ZIP_EXTERN(int) zip_set_file_comment(struct zip *za, int idx, const char *comment, int len) { char *tmpcom; diff --git a/ext/zip/lib/zip_set_name.c b/ext/zip/lib/zip_set_name.c index 8a401faaca..5c7da3d7c5 100644 --- a/ext/zip/lib/zip_set_name.c +++ b/ext/zip/lib/zip_set_name.c @@ -1,11 +1,9 @@ /* - $NiH: zip_set_name.c,v 1.16 2004/11/30 23:02:47 wiz Exp $ - zip_set_name.c -- rename helper function - Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -37,12 +35,12 @@ #include <stdlib.h> #include <string.h> -#include "zip.h" + #include "zipint.h" -PHPZIPAPI int +int _zip_set_name(struct zip *za, int idx, const char *name) { char *s; diff --git a/ext/zip/lib/zip_source_buffer.c b/ext/zip/lib/zip_source_buffer.c index 95875b74c1..867d3dfa3e 100644 --- a/ext/zip/lib/zip_source_buffer.c +++ b/ext/zip/lib/zip_source_buffer.c @@ -1,11 +1,9 @@ /* - $NiH: zip_source_buffer.c,v 1.8 2006/04/23 14:50:49 wiz Exp $ - zip_source_buffer.c -- create zip data source from buffer - Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -38,7 +36,6 @@ #include <stdlib.h> #include <string.h> -#include "zip.h" #include "zipint.h" struct read_data { @@ -52,7 +49,7 @@ static ssize_t read_data(void *state, void *data, size_t len, -PHPZIPAPI struct zip_source * +ZIP_EXTERN(struct zip_source *) zip_source_buffer(struct zip *za, const void *data, off_t len, int freep) { struct read_data *f; @@ -84,6 +81,8 @@ zip_source_buffer(struct zip *za, const void *data, off_t len, int freep) return zs; } + + static ssize_t read_data(void *state, void *data, size_t len, enum zip_source_cmd cmd) { @@ -103,8 +102,6 @@ read_data(void *state, void *data, size_t len, enum zip_source_cmd cmd) n = z->end - z->buf; if (n > len) n = len; - if (n < 0) - n = 0; if (n) { memcpy(buf, z->buf, n); diff --git a/ext/zip/lib/zip_source_file.c b/ext/zip/lib/zip_source_file.c index 486e1900d9..a42be670e9 100644 --- a/ext/zip/lib/zip_source_file.c +++ b/ext/zip/lib/zip_source_file.c @@ -1,11 +1,9 @@ /* - $NiH: zip_source_file.c,v 1.2 2004/11/18 16:28:13 wiz Exp $ - zip_source_file.c -- create data source from file - Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -38,17 +36,13 @@ #include <errno.h> #include <stdio.h> -#include "zip.h" #include "zipint.h" -PHPZIPAPI struct zip_source * +ZIP_EXTERN(struct zip_source *) zip_source_file(struct zip *za, const char *fname, off_t start, off_t len) { - struct zip_source *zs; - FILE *fp; - if (za == NULL) return NULL; @@ -57,19 +51,5 @@ zip_source_file(struct zip *za, const char *fname, off_t start, off_t len) return NULL; } - if ((fp=fopen(fname, "rb")) == NULL) { - _zip_error_set(&za->error, ZIP_ER_OPEN, errno); - return NULL; - } - -#ifdef PHP_WIN32 - _setmode(_fileno(fp), _O_BINARY ); -#endif - - if ((zs=zip_source_filep(za, fp, start, len)) == NULL) { - fclose(fp); - return NULL; - } - - return zs; + return _zip_source_file_or_p(za, fname, NULL, start, len); } diff --git a/ext/zip/lib/zip_source_filep.c b/ext/zip/lib/zip_source_filep.c index 8a33042655..10f9602e1e 100644 --- a/ext/zip/lib/zip_source_filep.c +++ b/ext/zip/lib/zip_source_filep.c @@ -1,11 +1,9 @@ /* - $NiH: zip_source_filep.c,v 1.6 2005/06/09 19:57:10 dillo Exp $ - zip_source_filep.c -- create data source from FILE * Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -41,10 +39,10 @@ #include <stdlib.h> #include <string.h> -#include "zip.h" #include "zipint.h" 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 */ @@ -57,12 +55,9 @@ static ssize_t read_file(void *state, void *data, size_t len, -PHPZIPAPI struct zip_source * +ZIP_EXTERN(struct zip_source *) zip_source_filep(struct zip *za, FILE *file, off_t start, off_t len) { - struct read_file *f; - struct zip_source *zs; - if (za == NULL) return NULL; @@ -71,11 +66,36 @@ 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); +} + + + +struct zip_source * +_zip_source_file_or_p(struct zip *za, const char *fname, FILE *file, + off_t start, off_t len) +{ + struct read_file *f; + struct zip_source *zs; + + if (file == NULL && fname == NULL) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + if ((f=(struct read_file *)malloc(sizeof(struct read_file))) == NULL) { _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); return NULL; } + f->fname = NULL; + if (fname) { + if ((f->fname=strdup(fname)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + free(f); + return NULL; + } + } f->f = file; f->off = start; f->len = (len ? len : -1); @@ -102,6 +122,14 @@ read_file(void *state, void *data, size_t len, enum zip_source_cmd cmd) switch (cmd) { case ZIP_SOURCE_OPEN: + if (z->fname) { + if ((z->f=fopen(z->fname, "rb")) == NULL) { + z->e[0] = ZIP_ER_OPEN; + z->e[1] = errno; + return -1; + } + } + if (fseeko(z->f, z->off, SEEK_SET) < 0) { z->e[0] = ZIP_ER_SEEK; z->e[1] = errno; @@ -128,17 +156,27 @@ read_file(void *state, void *data, size_t len, enum zip_source_cmd cmd) return i; case ZIP_SOURCE_CLOSE: + if (z->fname) { + fclose(z->f); + z->f = NULL; + } return 0; case ZIP_SOURCE_STAT: { struct zip_stat *st; struct stat fst; + int err; if (len < sizeof(*st)) return -1; - if (fstat(fileno(z->f), &fst) != 0) { + 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; @@ -164,6 +202,8 @@ read_file(void *state, void *data, size_t len, enum zip_source_cmd cmd) return sizeof(int)*2; case ZIP_SOURCE_FREE: + free(z->fname); + if (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 707309c913..293e7f7e11 100644 --- a/ext/zip/lib/zip_source_free.c +++ b/ext/zip/lib/zip_source_free.c @@ -1,11 +1,9 @@ /* - $NiH: zip_source_free.c,v 1.2 2004/12/22 16:32:00 dillo Exp $ - zip_source_free.c -- free zip data source - Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -37,12 +35,11 @@ #include <stdlib.h> -#include "zip.h" #include "zipint.h" -PHPZIPAPI void +ZIP_EXTERN(void) zip_source_free(struct zip_source *source) { if (source == NULL) diff --git a/ext/zip/lib/zip_source_function.c b/ext/zip/lib/zip_source_function.c index 4ab1109244..fe3e82aa5b 100644 --- a/ext/zip/lib/zip_source_function.c +++ b/ext/zip/lib/zip_source_function.c @@ -1,11 +1,9 @@ /* - $NiH: zip_source_function.c,v 1.4 2006/02/21 09:41:00 dillo Exp $ - zip_source_function.c -- create zip data source from callback function - Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -37,12 +35,11 @@ #include <stdlib.h> -#include "zip.h" #include "zipint.h" -PHPZIPAPI struct zip_source * +ZIP_EXTERN(struct zip_source *) zip_source_function(struct zip *za, zip_source_callback zcb, void *ud) { struct zip_source *zs; diff --git a/ext/zip/lib/zip_source_zip.c b/ext/zip/lib/zip_source_zip.c index 75e6564021..58119dd39f 100644 --- a/ext/zip/lib/zip_source_zip.c +++ b/ext/zip/lib/zip_source_zip.c @@ -1,11 +1,9 @@ /* - $NiH: zip_source_zip.c,v 1.7 2006/02/21 09:41:00 dillo Exp $ - zip_source_zip.c -- create data source from zip file - Copyright (C) 1999, 2003, 2004, 2005 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -38,7 +36,6 @@ #include <stdlib.h> #include <string.h> -#include "zip.h" #include "zipint.h" struct read_zip { @@ -52,7 +49,7 @@ static ssize_t read_zip(void *st, void *data, size_t len, -PHPZIPAPI struct zip_source * +ZIP_EXTERN(struct zip_source *) zip_source_zip(struct zip *za, struct zip *srcza, int srcidx, int flags, off_t start, off_t len) { @@ -60,6 +57,8 @@ zip_source_zip(struct zip *za, struct zip *srcza, int srcidx, int flags, struct zip_source *zs; struct read_zip *p; + /* XXX: ZIP_FL_RECOMPRESS */ + if (za == NULL) return NULL; @@ -77,7 +76,7 @@ zip_source_zip(struct zip *za, struct zip *srcza, int srcidx, int flags, if (len == 0) len = -1; - if (start == 0 && len == -1) + if (start == 0 && len == -1 && (flags & ZIP_FL_RECOMPRESS) == 0) flags |= ZIP_FL_COMPRESSED; else flags &= ~ZIP_FL_COMPRESSED; diff --git a/ext/zip/lib/zip_stat.c b/ext/zip/lib/zip_stat.c index 7c6cbf00d2..c8a25e1d84 100644 --- a/ext/zip/lib/zip_stat.c +++ b/ext/zip/lib/zip_stat.c @@ -1,11 +1,9 @@ /* - $NiH: zip_stat.c,v 1.3 2004/04/16 09:40:30 dillo Exp $ - zip_stat.c -- get information about file by name - Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -35,12 +33,11 @@ -#include "zip.h" #include "zipint.h" -PHPZIPAPI int +ZIP_EXTERN(int) zip_stat(struct zip *za, const char *fname, int flags, struct zip_stat *st) { int idx; diff --git a/ext/zip/lib/zip_stat_index.c b/ext/zip/lib/zip_stat_index.c index cf55565ef5..26425206ca 100644 --- a/ext/zip/lib/zip_stat_index.c +++ b/ext/zip/lib/zip_stat_index.c @@ -1,11 +1,9 @@ /* - $NiH: zip_stat_index.c,v 1.10 2006/04/24 14:04:19 dillo Exp $ - zip_stat_index.c -- get information about file by index - Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -35,12 +33,11 @@ -#include "zip.h" #include "zipint.h" -PHPZIPAPI int +ZIP_EXTERN(int) zip_stat_index(struct zip *za, int index, int flags, struct zip_stat *st) { const char *name; @@ -67,7 +64,7 @@ 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; } - + st->crc = za->cdir->entry[index].crc; st->size = za->cdir->entry[index].uncomp_size; st->mtime = za->cdir->entry[index].last_mod; diff --git a/ext/zip/lib/zip_stat_init.c b/ext/zip/lib/zip_stat_init.c index e9c056dfc5..cb451dc3bc 100644 --- a/ext/zip/lib/zip_stat_init.c +++ b/ext/zip/lib/zip_stat_init.c @@ -1,11 +1,9 @@ /* - $NiH: zip_stat_init.c,v 1.1 2006/10/31 12:03:04 dillo Exp $ - zip_stat_init.c -- initialize struct zip_stat. - Copyright (C) 2006 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -39,7 +37,7 @@ -PHPZIPAPI void +ZIP_EXTERN(void) zip_stat_init(struct zip_stat *st) { st->name = NULL; diff --git a/ext/zip/lib/zip_strerror.c b/ext/zip/lib/zip_strerror.c index f3e5aa9fe8..ad23bafed6 100644 --- a/ext/zip/lib/zip_strerror.c +++ b/ext/zip/lib/zip_strerror.c @@ -1,11 +1,9 @@ /* - $NiH: zip_strerror.c,v 1.1 2003/10/05 16:05:22 dillo Exp $ - zip_sterror.c -- get string representation of zip error - Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -35,12 +33,10 @@ -#include "zip.h" #include "zipint.h" - -PHPZIPAPI const char * +ZIP_EXTERN(const char *) zip_strerror(struct zip *za) { return _zip_error_strerror(&za->error); diff --git a/ext/zip/lib/zip_unchange.c b/ext/zip/lib/zip_unchange.c index 80070e7a3b..7366c9cc71 100644 --- a/ext/zip/lib/zip_unchange.c +++ b/ext/zip/lib/zip_unchange.c @@ -1,11 +1,9 @@ /* - $NiH: zip_unchange.c,v 1.19 2006/04/23 13:21:18 wiz Exp $ - zip_unchange.c -- undo changes to file in zip archive - Copyright (C) 1999, 2004, 2006 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -36,12 +34,12 @@ #include <stdlib.h> -#include "zip.h" + #include "zipint.h" -PHPZIPAPI int +ZIP_EXTERN(int) zip_unchange(struct zip *za, int idx) { return _zip_unchange(za, idx, 0); @@ -49,7 +47,7 @@ zip_unchange(struct zip *za, int idx) -PHPZIPAPI int +int _zip_unchange(struct zip *za, int idx, int allow_duplicates) { int i; diff --git a/ext/zip/lib/zip_unchange_all.c b/ext/zip/lib/zip_unchange_all.c index 2d4459c823..01282f89db 100644 --- a/ext/zip/lib/zip_unchange_all.c +++ b/ext/zip/lib/zip_unchange_all.c @@ -1,11 +1,9 @@ /* - $NiH: zip_unchange_all.c,v 1.10 2006/04/23 13:14:46 wiz Exp $ - zip_unchange.c -- undo changes to all files in zip archive - Copyright (C) 1999, 2006 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -36,12 +34,12 @@ #include <stdlib.h> -#include "zip.h" + #include "zipint.h" -PHPZIPAPI int +ZIP_EXTERN(int) zip_unchange_all(struct zip *za) { int ret, i; @@ -49,7 +47,7 @@ zip_unchange_all(struct zip *za) ret = 0; for (i=0; i<za->nentry; i++) ret |= _zip_unchange(za, i, 1); - + ret |= zip_unchange_archive(za); return ret; diff --git a/ext/zip/lib/zip_unchange_archive.c b/ext/zip/lib/zip_unchange_archive.c index 6c2bc6dcb3..ca2b678544 100644 --- a/ext/zip/lib/zip_unchange_archive.c +++ b/ext/zip/lib/zip_unchange_archive.c @@ -1,11 +1,9 @@ /* - $NiH: zip_unchange_archive.c,v 1.1 2006/04/23 13:14:46 wiz Exp $ - zip_unchange_archive.c -- undo global changes to ZIP archive - Copyright (C) 2006 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 <nih@giga.or.at> + 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 @@ -36,17 +34,19 @@ #include <stdlib.h> -#include "zip.h" + #include "zipint.h" -PHPZIPAPI int +ZIP_EXTERN(int) zip_unchange_archive(struct zip *za) { free(za->ch_comment); za->ch_comment = NULL; za->ch_comment_len = -1; + za->ch_flags = za->flags; + return 0; } diff --git a/ext/zip/lib/zip_unchange_data.c b/ext/zip/lib/zip_unchange_data.c index dfa2ea545f..6fe89f4fb2 100644 --- a/ext/zip/lib/zip_unchange_data.c +++ b/ext/zip/lib/zip_unchange_data.c @@ -1,11 +1,11 @@ /* - $NiH: zip_unchange_data.c,v 1.15 2004/12/22 16:32:00 dillo Exp $ + $NiH: zip_unchange_data.c,v 1.14 2004/11/30 23:02:47 wiz Exp $ zip_unchange_data.c -- undo helper function Copyright (C) 1999, 2004 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -39,7 +39,7 @@ #include "zipint.h" -PHPZIPAPI void +void _zip_unchange_data(struct zip_entry *ze) { if (ze->source) { diff --git a/ext/zip/lib/zip_win32.h b/ext/zip/lib/zip_win32.h index ea3860d602..ff28d2878c 100644 --- a/ext/zip/lib/zip_win32.h +++ b/ext/zip/lib/zip_win32.h @@ -2,16 +2,25 @@ #include <windows.h> #include <io.h> #include <fcntl.h> +#include <string.h> +#include <zconf.h> + +#ifndef strcasecmp +# define strcmpi _strcmpi +#endif #ifndef ssize_t # define ssize_t SSIZE_T #endif + #ifndef mode_t # define mode_t int #endif + #ifndef snprintf # define snprintf _snprintf #endif + #ifndef mkstemp # define mkstemp(t) _creat(_mktemp(t), _S_IREAD|_S_IWRITE) #endif diff --git a/ext/zip/lib/zipint.h b/ext/zip/lib/zipint.h index 33632aca4e..25d6bec98f 100644 --- a/ext/zip/lib/zipint.h +++ b/ext/zip/lib/zipint.h @@ -2,13 +2,11 @@ #define _HAD_ZIPINT_H /* - $NiH: zipint.h,v 1.48 2006/04/24 14:04:19 dillo Exp $ - zipint.h -- internal declarations. - Copyright (C) 1999, 2003, 2004, 2005, 2006 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <nih@giga.or.at> + 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 @@ -22,7 +20,7 @@ 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -39,18 +37,38 @@ #include <zlib.h> #include "zip.h" -/* #defines that rename all zip_ functions and structs */ -#include "zipint_alias.h" -BEGIN_EXTERN_C() +#ifdef PHP_WIN32 +#include <windows.h> +#include <wchar.h> +#define _zip_rename(s, t) \ + (!MoveFileExA((s), (t), \ + MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING)) +#else +#define _zip_rename rename +#endif + +#ifndef strcasecmp +# 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 + + #define CENTRAL_MAGIC "PK\1\2" #define LOCAL_MAGIC "PK\3\4" #define EOCD_MAGIC "PK\5\6" #define DATADES_MAGIC "PK\7\8" +#define TORRENT_SIG "TORRENTZIPPED-" +#define TORRENT_SIG_LEN 14 +#define TORRENT_CRC_LEN 8 +#define TORRENT_MEM_LEVEL 8 #define CDENTRYSIZE 46u #define LENTRYSIZE 30 #define MAXCOMLEN 65536 @@ -74,8 +92,8 @@ enum zip_state { ZIP_ST_UNCHANGED, ZIP_ST_DELETED, ZIP_ST_REPLACED, /* directory entry: general purpose bit flags */ #define ZIP_GPBF_ENCRYPTED 0x0001 /* is encrypted */ +#define ZIP_GPBF_DATA_DESCRIPTOR 0x0008 /* crc/size after file data */ #define ZIP_GPBF_STRONG_ENCRYPTION 0x0040 /* uses strong encryption */ -#define ZIP_GPBF_USE_DATA_DESCRIPTOR 0x0008 /* uses crc and size from data header */ /* error information */ @@ -92,6 +110,9 @@ struct zip { FILE *zp; /* file */ struct zip_error error; /* error information */ + unsigned int flags; /* archive global flags */ + unsigned int ch_flags; /* changed archive global flags */ + struct zip_cdir *cdir; /* central directory */ char *ch_comment; /* changed archive comment */ int ch_comment_len; /* length of changed zip archive @@ -112,13 +133,13 @@ struct zip_file { int flags; /* -1: eof, >0: error */ int method; /* compression method */ - long fpos; /* position within zip file (fread/fwrite) */ + 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; }; @@ -189,43 +210,49 @@ extern const int _zip_err_type[]; -PHPZIPAPI void _zip_cdir_free(struct zip_cdir *); -PHPZIPAPI struct zip_cdir *_zip_cdir_new(int, struct zip_error *); -PHPZIPAPI int _zip_cdir_write(struct zip_cdir *, FILE *, struct zip_error *); +int _zip_cdir_compute_crc(struct zip *, uLong *); +void _zip_cdir_free(struct zip_cdir *); +struct zip_cdir *_zip_cdir_new(int, struct zip_error *); +int _zip_cdir_write(struct zip_cdir *, FILE *, struct zip_error *); -PHPZIPAPI void _zip_dirent_finalize(struct zip_dirent *); -PHPZIPAPI void _zip_dirent_init(struct zip_dirent *); -PHPZIPAPI int _zip_dirent_read(struct zip_dirent *, FILE *, +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 *); -PHPZIPAPI int _zip_dirent_write(struct zip_dirent *, FILE *, int, struct zip_error *); - -PHPZIPAPI void _zip_entry_free(struct zip_entry *); -PHPZIPAPI void _zip_entry_init(struct zip *, int); -PHPZIPAPI struct zip_entry *_zip_entry_new(struct zip *); - -PHPZIPAPI void _zip_error_clear(struct zip_error *); -PHPZIPAPI void _zip_error_copy(struct zip_error *, struct zip_error *); -PHPZIPAPI void _zip_error_fini(struct zip_error *); -PHPZIPAPI void _zip_error_get(struct zip_error *, int *, int *); -PHPZIPAPI void _zip_error_init(struct zip_error *); -PHPZIPAPI void _zip_error_set(struct zip_error *, int, int); -PHPZIPAPI const char *_zip_error_strerror(struct zip_error *); - -PHPZIPAPI int _zip_file_fillbuf(void *, size_t, struct zip_file *); -PHPZIPAPI unsigned int _zip_file_get_offset(struct zip *, int); - -PHPZIPAPI void _zip_free(struct zip *); -PHPZIPAPI const char *_zip_get_name(struct zip *, int, int, struct zip_error *); -PHPZIPAPI int _zip_local_header_read(struct zip *, int); -PHPZIPAPI void *_zip_memdup(const void *, size_t, struct zip_error *); -PHPZIPAPI int _zip_name_locate(struct zip *, const char *, int, struct zip_error *); -PHPZIPAPI struct zip *_zip_new(struct zip_error *); -PHPZIPAPI unsigned short _zip_read2(unsigned char **); -PHPZIPAPI unsigned int _zip_read4(unsigned char **); -PHPZIPAPI int _zip_replace(struct zip *, int, const char *, struct zip_source *); -PHPZIPAPI int _zip_set_name(struct zip *, int, const char *); -PHPZIPAPI int _zip_unchange(struct zip *, int, int); -PHPZIPAPI void _zip_unchange_data(struct zip_entry *); - -END_EXTERN_C(); +void _zip_dirent_torrent_normalize(struct zip_dirent *); +int _zip_dirent_write(struct zip_dirent *, FILE *, int, struct zip_error *); + +void _zip_entry_free(struct zip_entry *); +void _zip_entry_init(struct zip *, int); +struct zip_entry *_zip_entry_new(struct zip *); + +void _zip_error_clear(struct zip_error *); +void _zip_error_copy(struct zip_error *, struct zip_error *); +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); +const char *_zip_error_strerror(struct zip_error *); + +int _zip_file_fillbuf(void *, size_t, struct zip_file *); +unsigned int _zip_file_get_offset(struct zip *, int); + +int _zip_filerange_crc(FILE *, off_t, off_t, uLong *, struct zip_error *); + +struct zip_source *_zip_source_file_or_p(struct zip *, const char *, FILE *, + off_t, off_t); + +void _zip_free(struct zip *); +const char *_zip_get_name(struct zip *, int, 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); +void _zip_unchange_data(struct zip_entry *); + #endif /* zipint.h */ diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index 0dcbf2a8a7..e6fb77511e 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -79,81 +79,152 @@ static int le_zip_entry; RETURN_FALSE; \ } \ RETURN_TRUE; +/* }}} */ + +#if (PHP_MAJOR_VERSION < 6) +# define add_ascii_assoc_string add_assoc_string +# define add_ascii_assoc_long add_assoc_long +#endif + +/* Flatten a path by creating a relative path (to .) */ +static char * php_zip_make_relative_path(char *path, int path_len) /* {{{ */ +{ + char *path_begin = path; + int prev_is_slash = 0; + char *e = path + path_len - 1; + size_t pos = path_len - 1; + size_t i; + + if (IS_SLASH(path[0])) { + return path + 1; + } + + if (path_len < 1 || path == NULL) { + return NULL; + } + i = path_len; + + while (1) { + while (i > 0 && !IS_SLASH(path[i])) { + i--; + } + + if (!i) { + return path; + } + + if (i >= 2 && (path[i -1] == '.' || path[i -1] == ':')) { + /* i is the position of . or :, add 1 for / */ + path_begin = path + i + 1; + break; + } + i--; + } + + return path_begin; +} /* }}} */ /* {{{ php_zip_extract_file */ -/* TODO: Simplify it */ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int file_len TSRMLS_DC) { php_stream_statbuf ssb; struct zip_file *zf; struct zip_stat sb; char b[8192]; - int n, len, ret; - php_stream *stream; - char *fullpath; char *file_dirname_fullpath; char file_dirname[MAXPATHLEN]; size_t dir_len; - char *file_basename; size_t file_basename_len; int is_dir_only = 0; + char *path_cleaned; + size_t path_cleaned_len; + cwd_state new_state; + + new_state.cwd = (char*)malloc(1); + new_state.cwd[0] = '\0'; + new_state.cwd_length = 0; - if (file_len >= MAXPATHLEN || zip_stat(za, file, 0, &sb) != 0) { + /* Clean/normlize the path and then transform any path (absolute or relative) + to a path relative to cwd (../../mydir/foo.txt > mydir/foo.txt) + */ + virtual_file_ex(&new_state, file, NULL, CWD_EXPAND); + path_cleaned = php_zip_make_relative_path(new_state.cwd, new_state.cwd_length); + path_cleaned_len = strlen(path_cleaned); + + if (path_cleaned_len >= MAXPATHLEN || zip_stat(za, file, 0, &sb) != 0) { return 0; } - if (file_len > 1 && file[file_len - 1] == '/') { + /* it is a directory only, see #40228 */ + if (path_cleaned_len > 1 && IS_SLASH(path_cleaned[path_cleaned_len - 1])) { len = spprintf(&file_dirname_fullpath, 0, "%s/%s", dest, file); is_dir_only = 1; } else { - memcpy(file_dirname, file, file_len); - dir_len = php_dirname(file_dirname, file_len); + memcpy(file_dirname, path_cleaned, path_cleaned_len); + dir_len = php_dirname(file_dirname, path_cleaned_len); - if (dir_len > 0) { - len = spprintf(&file_dirname_fullpath, 0, "%s/%s", dest, file_dirname); - } else { + if (dir_len <= 0 || (dir_len == 1 && file_dirname[0] == '.')) { len = spprintf(&file_dirname_fullpath, 0, "%s", dest); + } else { + len = spprintf(&file_dirname_fullpath, 0, "%s/%s", dest, file_dirname); } - php_basename(file, file_len, NULL, 0, &file_basename, (size_t *)&file_basename_len TSRMLS_CC); + php_basename(path_cleaned, path_cleaned_len, NULL, 0, &file_basename, (unsigned int *)&file_basename_len TSRMLS_CC); if (OPENBASEDIR_CHECKPATH(file_dirname_fullpath)) { efree(file_dirname_fullpath); efree(file_basename); + free(new_state.cwd); return 0; } } /* let see if the path already exists */ if (php_stream_stat_path(file_dirname_fullpath, &ssb) < 0) { - ret = php_stream_mkdir(file_dirname_fullpath, 0777, PHP_STREAM_MKDIR_RECURSIVE, NULL); + +#if defined(PHP_WIN32) && (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 1) + char *e; + e = file_dirname_fullpath; + while (*e) { + if (*e == '/') { + *e = DEFAULT_SLASH; + } + e++; + } +#endif + + ret = php_stream_mkdir(file_dirname_fullpath, 0777, PHP_STREAM_MKDIR_RECURSIVE|REPORT_ERRORS, NULL); if (!ret) { efree(file_dirname_fullpath); + if (!is_dir_only) { efree(file_basename); + free(new_state.cwd); + } return 0; } } /* it is a standalone directory, job done */ - if (file[file_len - 1] == '/') { + if (is_dir_only) { efree(file_dirname_fullpath); - if (!is_dir_only) { - efree(file_basename); - } + free(new_state.cwd); return 1; } - len = spprintf(&fullpath, 0, "%s/%s/%s", dest, file_dirname, file_basename); + len = spprintf(&fullpath, 0, "%s/%s", file_dirname_fullpath, file_basename); if (!len) { efree(file_dirname_fullpath); efree(file_basename); + free(new_state.cwd); return 0; + } else if (len > MAXPATHLEN) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Full extraction path exceed MAXPATHLEN (%i)", MAXPATHLEN); } /* check again the full path, not sure if it @@ -164,6 +235,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil efree(fullpath); efree(file_dirname_fullpath); efree(file_basename); + free(new_state.cwd); return 0; } @@ -172,10 +244,15 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil efree(fullpath); efree(file_dirname_fullpath); efree(file_basename); + free(new_state.cwd); return 0; } +#if (PHP_MAJOR_VERSION < 6) stream = php_stream_open_wrapper(fullpath, "w+b", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL); +#else + stream = php_stream_open_wrapper(fullpath, "w+b", REPORT_ERRORS, NULL); +#endif n = 0; if (stream) { while ((n=zip_fread(zf, b, sizeof(b))) > 0) php_stream_write(stream, b, n); @@ -186,6 +263,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil efree(fullpath); efree(file_basename); efree(file_dirname_fullpath); + free(new_state.cwd); if (n<0) { return 0; @@ -195,6 +273,111 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil } /* }}} */ +static int php_zip_add_file(struct zip *za, const char *filename, int filename_len, + char *entry_name, int entry_name_len, long offset_start, long offset_len TSRMLS_DC) /* {{{ */ +{ + struct zip_source *zs; + int cur_idx; + char resolved_path[MAXPATHLEN]; + + + if (OPENBASEDIR_CHECKPATH(filename)) { + return -1; + } + + if (!expand_filepath(filename, resolved_path TSRMLS_CC)) { + return -1; + } + + zs = zip_source_file(za, resolved_path, offset_start, offset_len); + if (!zs) { + return -1; + } + + cur_idx = zip_name_locate(za, (const char *)entry_name, 0); + /* TODO: fix _zip_replace */ + if (cur_idx<0) { + /* reset the error */ + if (za->error.str) { + _zip_error_fini(&za->error); + } + _zip_error_init(&za->error); + } else { + if (zip_delete(za, cur_idx) == -1) { + zip_source_free(zs); + return -1; + } + } + + if (zip_add(za, entry_name, zs) == -1) { + return -1; + } else { + return 1; + } +} +/* }}} */ + +static int php_zip_parse_options(zval *options, long *remove_all_path, + char **remove_path, int *remove_path_len, char **add_path, int *add_path_len TSRMLS_DC) /* {{{ */ +{ + zval **option; + if (zend_hash_find(HASH_OF(options), "remove_all_path", sizeof("remove_all_path"), (void **)&option) == SUCCESS) { + long opt; + if (Z_TYPE_PP(option) != IS_LONG) { + zval tmp = **option; + zval_copy_ctor(&tmp); + convert_to_long(&tmp); + opt = Z_LVAL(tmp); + } else { + opt = Z_LVAL_PP(option); + } + *remove_all_path = opt; + } + + /* If I add more options, it would make sense to create a nice static struct and loop over it. */ + if (zend_hash_find(HASH_OF(options), "remove_path", sizeof("remove_path"), (void **)&option) == SUCCESS) { + if (Z_TYPE_PP(option) != IS_STRING) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "remove_path option expected to be a string"); + return -1; + } + + if (Z_STRLEN_PP(option) < 1) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Empty string given as remove_path option"); + return -1; + } + + if (Z_STRLEN_PP(option) >= MAXPATHLEN) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "remove_path string is too long (max: %i, %i given)", + MAXPATHLEN - 1, Z_STRLEN_PP(option)); + return -1; + } + *remove_path_len = Z_STRLEN_PP(option); + *remove_path = Z_STRVAL_PP(option); + } + + if (zend_hash_find(HASH_OF(options), "add_path", sizeof("add_path"), (void **)&option) == SUCCESS) { + if (Z_TYPE_PP(option) != IS_STRING) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "add_path option expected to be a string"); + return -1; + } + + if (Z_STRLEN_PP(option) < 1) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Empty string given as the add_path option"); + return -1; + } + + if (Z_STRLEN_PP(option) >= MAXPATHLEN) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "add_path string too long (max: %i, %i given)", + MAXPATHLEN - 1, Z_STRLEN_PP(option)); + return -1; + } + *add_path_len = Z_STRLEN_PP(option); + *add_path = Z_STRVAL_PP(option); + } + return 1; +} +/* }}} */ + /* {{{ REGISTER_ZIP_CLASS_CONST_LONG */ #define REGISTER_ZIP_CLASS_CONST_LONG(const_name, value) \ zend_declare_class_constant_long(zip_class_entry, const_name, sizeof(const_name)-1, (long)value TSRMLS_CC); @@ -216,13 +399,13 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil #define RETURN_SB(sb) \ { \ array_init(return_value); \ - add_assoc_string(return_value, "name", (char *)(sb)->name, 1); \ - add_assoc_long(return_value, "index", (long) (sb)->index); \ - add_assoc_long(return_value, "crc", (long) (sb)->crc); \ - add_assoc_long(return_value, "size", (long) (sb)->size); \ - add_assoc_long(return_value, "mtime", (long) (sb)->mtime); \ - add_assoc_long(return_value, "comp_size", (long) (sb)->comp_size); \ - add_assoc_long(return_value, "comp_method", (long) (sb)->comp_method); \ + add_ascii_assoc_string(return_value, "name", (char *)(sb)->name, 1); \ + add_ascii_assoc_long(return_value, "index", (long) (sb)->index); \ + add_ascii_assoc_long(return_value, "crc", (long) (sb)->crc); \ + add_ascii_assoc_long(return_value, "size", (long) (sb)->size); \ + add_ascii_assoc_long(return_value, "mtime", (long) (sb)->mtime); \ + add_ascii_assoc_long(return_value, "comp_size", (long) (sb)->comp_size); \ + add_ascii_assoc_long(return_value, "comp_method", (long) (sb)->comp_method); \ } /* }}} */ @@ -290,6 +473,7 @@ static zend_function_entry zip_functions[] = { /* }}} */ /* {{{ ZE2 OO definitions */ +#ifdef ZEND_ENGINE_2_1 static zend_class_entry *zip_class_entry; static zend_object_handlers zip_object_handlers; @@ -306,8 +490,10 @@ typedef struct _zip_prop_handler { int type; } zip_prop_handler; +#endif /* }}} */ +#ifdef ZEND_ENGINE_2_1 static void php_zip_register_prop_handler(HashTable *prop_handler, char *name, zip_read_int_t read_int_func, zip_read_const_char_t read_char_func, zip_read_const_char_from_ze_t read_char_from_obj_func, int rettype TSRMLS_DC) /* {{{ */ { zip_prop_handler hnd; @@ -434,7 +620,7 @@ static zval* php_zip_read_property(zval *object, zval *member, int type TSRMLS_D ret = php_zip_property_reader(obj, hnd, &retval, 1 TSRMLS_CC); if (ret == SUCCESS) { /* ensure we're creating a temporary variable */ - retval->refcount = 0; + Z_SET_REFCOUNT_P(retval, 0); } else { retval = EG(uninitialized_zval_ptr); } @@ -478,8 +664,8 @@ static int php_zip_has_property(zval *object, zval *member, int type TSRMLS_DC) if (type == 2) { retval = 1; } else if (php_zip_property_reader(obj, hnd, &tmp, 1 TSRMLS_CC) == SUCCESS) { - tmp->refcount = 1; - tmp->is_ref = 0; + Z_SET_REFCOUNT_P(tmp, 1); + Z_UNSET_ISREF_P(tmp); if (type == 1) { retval = zend_is_true(tmp); } else if (type == 0) { @@ -580,7 +766,14 @@ static zend_object_value php_zip_object_new(zend_class_entry *class_type TSRMLS_ intern->buffers_cnt = 0; intern->prop_handler = &zip_prop_handlers; +#if ((PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 1 && PHP_RELEASE_VERSION > 2)) zend_object_std_init(&intern->zo, class_type TSRMLS_CC); +#else + ALLOC_HASHTABLE(intern->zo.properties); + zend_hash_init(intern->zo.properties, 0, NULL, ZVAL_PTR_DTOR, 0); + intern->zo.ce = class_type; +#endif + zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); @@ -594,6 +787,7 @@ static zend_object_value php_zip_object_new(zend_class_entry *class_type TSRMLS_ return retval; } /* }}} */ +#endif /* {{{ Resource dtors */ @@ -636,7 +830,7 @@ static void php_zip_free_entry(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* }}}*/ /* reset macro */ -#undef zip + /* {{{ function prototypes */ static PHP_MINIT_FUNCTION(zip); static PHP_MSHUTDOWN_FUNCTION(zip); @@ -654,7 +848,7 @@ zend_module_entry zip_module_entry = { NULL, NULL, PHP_MINFO(zip), - "2.0.0", + PHP_ZIP_VERSION_STRING, STANDARD_MODULE_PROPERTIES }; /* }}} */ @@ -663,7 +857,6 @@ zend_module_entry zip_module_entry = { ZEND_GET_MODULE(zip) #endif /* set macro */ -#define zip php_ziplib__zip /* {{{ proto resource zip_open(string filename) Create new zip using source uri for output */ @@ -694,7 +887,7 @@ static PHP_NAMED_FUNCTION(zif_zip_open) rsrc_int = (zip_rsrc *)emalloc(sizeof(zip_rsrc)); - rsrc_int->za = zip_open(filename, 0, &err); + rsrc_int->za = zip_open(resolved_path, 0, &err); if (rsrc_int->za == NULL) { efree(rsrc_int); RETURN_LONG((long)err); @@ -749,7 +942,7 @@ static PHP_NAMED_FUNCTION(zif_zip_read) if (ret != 0) { efree(zr_rsrc); - RETURN_LONG((long)ret); + RETURN_FALSE; } zr_rsrc->zf = zip_fopen_index(rsrc_int->za, rsrc_int->index_current, 0); @@ -944,6 +1137,7 @@ static PHP_NAMED_FUNCTION(zif_zip_entry_compressionmethod) } /* }}} */ +#ifdef ZEND_ENGINE_2_1 /* {{{ proto mixed ZipArchive::open(string source [, int flags]) Create new zip using source uri for output, return TRUE on success or the error code */ static ZIPARCHIVE_METHOD(open) @@ -991,6 +1185,7 @@ static ZIPARCHIVE_METHOD(open) efree(ze_obj->filename); ze_obj->filename = NULL; } + intern = zip_open(resolved_path, flags, &err); if (!intern || err) { RETURN_LONG((long)err); @@ -1031,6 +1226,28 @@ static ZIPARCHIVE_METHOD(close) } /* }}} */ +/* {{{ proto string ZipArchive::getStatusString() + * Returns the status error message, system and/or zip messages */ +static ZIPARCHIVE_METHOD(getStatusString) +{ + struct zip *intern; + zval *this = getThis(); + int zep, syp, len; + char error_string[128]; + + if (!this) { + RETURN_FALSE; + } + + ZIP_FROM_OBJECT(intern, this); + + zip_error_get(intern, &zep, &syp); + + len = zip_error_to_str(error_string, 128, zep, syp); + RETVAL_STRINGL(error_string, len, 1); +} +/* }}} */ + /* {{{ proto bool ZipArchive::createEmptyDir(string dirname) Returns the index of the entry named filename in the archive */ static ZIPARCHIVE_METHOD(addEmptyDir) @@ -1071,17 +1288,10 @@ static ZIPARCHIVE_METHOD(addEmptyDir) if (idx >= 0) { RETVAL_FALSE; } else { - /* reset the error */ - if (intern->error.str) { - _zip_error_fini(&intern->error); - } - _zip_error_init(&intern->error); - if (zip_add_dir(intern, (const char *)s) == -1) { RETVAL_FALSE; - } else { - RETVAL_TRUE; } + RETVAL_TRUE; } if (s != dirname) { @@ -1100,10 +1310,7 @@ static ZIPARCHIVE_METHOD(addFile) int filename_len; char *entry_name = NULL; int entry_name_len = 0; - struct zip_source *zs; long offset_start = 0, offset_len = 0; - int cur_idx; - char resolved_path[MAXPATHLEN]; if (!this) { RETURN_FALSE; @@ -1126,35 +1333,8 @@ static ZIPARCHIVE_METHOD(addFile) entry_name_len = filename_len; } - if (OPENBASEDIR_CHECKPATH(filename)) { - RETURN_FALSE; - } - - if (!expand_filepath(filename, resolved_path TSRMLS_CC)) { - RETURN_FALSE; - } - - zs = zip_source_file(intern, resolved_path, 0, 0); - if (!zs) { - RETURN_FALSE; - } - - cur_idx = zip_name_locate(intern, (const char *)entry_name, 0); - /* TODO: fix _zip_replace */ - if (cur_idx<0) { - /* reset the error */ - if (intern->error.str) { - _zip_error_fini(&intern->error); - } - _zip_error_init(&intern->error); - - } else { - if (zip_delete(intern, cur_idx) == -1) { - RETURN_FALSE; - } - } - - if (zip_add(intern, entry_name, zs) == -1) { + if (php_zip_add_file(intern, filename, filename_len, + entry_name, entry_name_len, 0, 0 TSRMLS_CC) < 0) { RETURN_FALSE; } else { RETURN_TRUE; @@ -1206,14 +1386,7 @@ static ZIPARCHIVE_METHOD(addFromString) cur_idx = zip_name_locate(intern, (const char *)name, 0); /* TODO: fix _zip_replace */ - if (cur_idx<0) { - /* reset the error */ - if (intern->error.str) { - _zip_error_fini(&intern->error); - } - _zip_error_init(&intern->error); - - } else { + if (cur_idx >= 0) { if (zip_delete(intern, cur_idx) == -1) { RETURN_FALSE; } @@ -1310,15 +1483,10 @@ static ZIPARCHIVE_METHOD(locateName) idx = (long)zip_name_locate(intern, (const char *)name, flags); - if (idx<0) { - /* reset the error */ - if (intern->error.str) { - _zip_error_fini(&intern->error); - } - _zip_error_init(&intern->error); - RETURN_FALSE; - } else { + if (idx >= 0) { RETURN_LONG(idx); + } else { + RETURN_FALSE; } } /* }}} */ @@ -1979,6 +2147,7 @@ static ZIPARCHIVE_METHOD(getStream) static zend_function_entry zip_class_functions[] = { ZIPARCHIVE_ME(open, NULL, ZEND_ACC_PUBLIC) ZIPARCHIVE_ME(close, NULL, ZEND_ACC_PUBLIC) + ZIPARCHIVE_ME(getStatusString, NULL, ZEND_ACC_PUBLIC) ZIPARCHIVE_ME(addEmptyDir, NULL, ZEND_ACC_PUBLIC) ZIPARCHIVE_ME(addFromString, NULL, ZEND_ACC_PUBLIC) ZIPARCHIVE_ME(addFile, NULL, ZEND_ACC_PUBLIC) @@ -2007,11 +2176,10 @@ static zend_function_entry zip_class_functions[] = { {NULL, NULL, NULL} }; /* }}} */ +#endif /* {{{ PHP_MINIT_FUNCTION */ -#undef zip static PHP_MINIT_FUNCTION(zip) -#define zip php_ziplib__zip { zend_class_entry ce; @@ -2092,9 +2260,7 @@ static PHP_MINIT_FUNCTION(zip) /* {{{ PHP_MSHUTDOWN_FUNCTION */ -#undef zip static PHP_MSHUTDOWN_FUNCTION(zip) -#define zip php_ziplib__zip { zend_hash_destroy(&zip_prop_handlers); php_unregister_url_stream_wrapper("zip" TSRMLS_CC); @@ -2105,7 +2271,6 @@ static PHP_MSHUTDOWN_FUNCTION(zip) /* {{{ PHP_MINFO_FUNCTION */ -#undef zip static PHP_MINFO_FUNCTION(zip) { php_info_print_table_start(); @@ -2113,7 +2278,7 @@ static PHP_MINFO_FUNCTION(zip) php_info_print_table_row(2, "Zip", "enabled"); php_info_print_table_row(2, "Extension Version","$Id$"); php_info_print_table_row(2, "Zip version", PHP_ZIP_VERSION_STRING); - php_info_print_table_row(2, "Libzip version", "0.8.0-compatible"); + php_info_print_table_row(2, "Libzip version", "0.9.0"); php_info_print_table_end(); } diff --git a/ext/zip/php_zip.h b/ext/zip/php_zip.h index dfcf8cc398..9713408e64 100644 --- a/ext/zip/php_zip.h +++ b/ext/zip/php_zip.h @@ -32,6 +32,19 @@ extern zend_module_entry zip_module_entry; #define PHP_ZIP_VERSION_STRING "1.8.11" +#ifndef ZEND_ENGINE_2_1 +# if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 0) || PHP_MAJOR_VERSION == 6 +# define ZEND_ENGINE_2_1 +# endif +#endif + +#ifndef Z_SET_REFCOUNT_P +# if PHP_MAJOR_VERSION < 6 && (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 3) +# define Z_SET_REFCOUNT_P(pz, rc) pz->refcount = rc +# define Z_UNSET_ISREF_P(pz) pz->is_ref = 0 +# endif +#endif + /* {{{ OPENBASEDIR_CHECKPATH(filename) */ #if (PHP_MAJOR_VERSION < 6) #define OPENBASEDIR_CHECKPATH(filename) \ @@ -55,6 +68,7 @@ typedef struct _ze_zip_read_rsrc { struct zip_stat sb; } zip_read_rsrc; +#ifdef ZEND_ENGINE_2_1 #define ZIPARCHIVE_ME(name, arg_info, flags) ZEND_FENTRY(name, c_ziparchive_ ##name, arg_info, flags) #define ZIPARCHIVE_METHOD(name) ZEND_NAMED_FUNCTION(c_ziparchive_##name) @@ -73,6 +87,7 @@ php_stream *php_stream_zip_opener(php_stream_wrapper *wrapper, char *path, char php_stream *php_stream_zip_open(char *filename, char *path, char *mode STREAMS_DC TSRMLS_DC); extern php_stream_wrapper php_stream_zip_wrapper; +#endif #endif /* PHP_ZIP_H */ |