diff --git a/ext/zip/TODO b/ext/zip/TODO index cb540ce7afa..c1baba97edb 100644 --- a/ext/zip/TODO +++ b/ext/zip/TODO @@ -1,4 +1,3 @@ -- fix _zip_replace (add two entries with the same name segfaults) - add pattern support to extract or add files - stream to add or modify entries - crypt support for zip (read and write) diff --git a/ext/zip/config.m4 b/ext/zip/config.m4 index 5208cff2950..e7907be21e6 100644 --- a/ext/zip/config.m4 +++ b/ext/zip/config.m4 @@ -59,7 +59,8 @@ if test "$PHP_ZIP" != "no"; then 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_unchange_archive.c lib/zip_memdup.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" AC_DEFINE(HAVE_ZIP,1,[ ]) PHP_NEW_EXTENSION(zip, php_zip.c zip_stream.c $PHP_ZIP_SOURCES, $ext_shared) diff --git a/ext/zip/config.w32 b/ext/zip/config.w32 index 1a99217b595..2880f6b216d 100644 --- a/ext/zip/config.w32 +++ b/ext/zip/config.w32 @@ -26,7 +26,8 @@ if (PHP_ZIP != "no") { zip_new.c zip_source_file.c zip_stat_index.c \ zip_get_archive_comment.c zip_get_file_comment.c \ zip_set_archive_comment.c zip_set_file_comment.c \ - zip_unchange_archive.c zip_memdup.c", "zip"); + zip_unchange_archive.c zip_memdup.c zip_stat_init.c \ + zip_add_dir.c zip_file_error_clear.c zip_error_clear.c", "zip"); AC_DEFINE('HAVE_ZLIB', 1); AC_DEFINE('HAVE_ZIP', 1); diff --git a/ext/zip/lib/zip.h b/ext/zip/lib/zip.h index 8cf690cad3f..70c54f38ba3 100644 --- a/ext/zip/lib/zip.h +++ b/ext/zip/lib/zip.h @@ -163,12 +163,15 @@ struct zip_source; int zip_add(struct zip *, const char *, struct zip_source *); +int zip_add_dir(struct zip *, const char *); int zip_close(struct zip *); int zip_delete(struct zip *, int); +void zip_error_clear(struct zip *); void zip_error_get(struct zip *, int *, int *); int zip_error_get_sys_type(int); int zip_error_to_str(char *, size_t, int, int); int zip_fclose(struct zip_file *); +void zip_file_error_clear(struct zip_file *); void zip_file_error_get(struct zip_file *, int *, int *); const char *zip_file_strerror(struct zip_file *); struct zip_file *zip_fopen(struct zip *, const char *, int); @@ -194,6 +197,7 @@ struct zip_source *zip_source_zip(struct zip *, struct zip *, int, int, off_t, off_t); int zip_stat(struct zip *, const char *, int, struct zip_stat *); int zip_stat_index(struct zip *, int, int, struct zip_stat *); +void zip_stat_init(struct zip_stat *); const char *zip_strerror(struct zip *); int zip_unchange(struct zip *, int); int zip_unchange_all(struct zip *); diff --git a/ext/zip/lib/zip_add_dir.c b/ext/zip/lib/zip_add_dir.c new file mode 100644 index 00000000000..6cc05ed0541 --- /dev/null +++ b/ext/zip/lib/zip_add_dir.c @@ -0,0 +1,83 @@ +/* + $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-2006 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include +#include + +#include "zip.h" +#include "zipint.h" + + + +int +zip_add_dir(struct zip *za, const char *name) +{ + int len, ret; + char *s; + struct zip_source *source; + + if (name == NULL) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + s = NULL; + len = strlen(name); + + if (name[len-1] != '/') { + if ((s=(char *)malloc(len+2)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; + } + strcpy(s, name); + s[len] = '/'; + s[len+1] = '\0'; + } + + if ((source=zip_source_buffer(za, NULL, 0, 0)) == NULL) { + free(s); + return -1; + } + + ret = _zip_replace(za, -1, s ? s : name, source); + + free(s); + if (ret < 0) + zip_source_free(source); + + return ret; +} diff --git a/ext/zip/lib/zip_error.c b/ext/zip/lib/zip_error.c index 33a8f3374a7..6d2cd00904f 100644 --- a/ext/zip/lib/zip_error.c +++ b/ext/zip/lib/zip_error.c @@ -2,7 +2,7 @@ $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, 2003, 2004, 2005 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2006 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -42,6 +42,15 @@ +void +_zip_error_clear(struct zip_error *err) +{ + err->zip_err = ZIP_ER_OK; + err->sys_err = 0; +} + + + void _zip_error_copy(struct zip_error *dst, struct zip_error *src) { @@ -78,7 +87,7 @@ _zip_error_get(struct zip_error *err, int *zep, int *sep) void _zip_error_init(struct zip_error *err) { - err->zip_err = 0; + err->zip_err = ZIP_ER_OK; err->sys_err = 0; err->str = NULL; } diff --git a/ext/zip/lib/zip_error_clear.c b/ext/zip/lib/zip_error_clear.c new file mode 100644 index 00000000000..7d37ecf977d --- /dev/null +++ b/ext/zip/lib/zip_error_clear.c @@ -0,0 +1,47 @@ +/* + $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-2006 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zip.h" +#include "zipint.h" + + + +void +zip_error_clear(struct zip *za) +{ + _zip_error_clear(&za->error); +} diff --git a/ext/zip/lib/zip_file_error_clear.c b/ext/zip/lib/zip_file_error_clear.c new file mode 100644 index 00000000000..c7645c30cb7 --- /dev/null +++ b/ext/zip/lib/zip_file_error_clear.c @@ -0,0 +1,47 @@ +/* + $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-2006 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zip.h" +#include "zipint.h" + + + +void +zip_file_error_clear(struct zip_file *zf) +{ + _zip_error_clear(&zf->error); +} diff --git a/ext/zip/lib/zip_get_archive_comment.c b/ext/zip/lib/zip_get_archive_comment.c index 40feb4eba13..7844c5e1912 100644 --- a/ext/zip/lib/zip_get_archive_comment.c +++ b/ext/zip/lib/zip_get_archive_comment.c @@ -47,7 +47,7 @@ zip_get_archive_comment(struct zip *za, int *lenp, int flags) || (za->ch_comment_len == -1)) { if (za->cdir) { if (lenp != NULL) - *lenp = za->cdir->comment_len; + *lenp = za->cdir->comment_len; return za->cdir->comment; } } diff --git a/ext/zip/lib/zip_source_buffer.c b/ext/zip/lib/zip_source_buffer.c index ada9ae85fbc..9263d47638b 100644 --- a/ext/zip/lib/zip_source_buffer.c +++ b/ext/zip/lib/zip_source_buffer.c @@ -2,7 +2,7 @@ $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, 2003, 2004, 2005 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2006 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -125,11 +125,9 @@ read_data(void *state, void *data, size_t len, enum zip_source_cmd cmd) st = (struct zip_stat *)data; + zip_stat_init(st); st->mtime = z->mtime; - st->crc = 0; st->size = z->end - z->data; - st->comp_size = -1; - st->comp_method = ZIP_CM_STORE; return sizeof(*st); } diff --git a/ext/zip/lib/zip_source_filep.c b/ext/zip/lib/zip_source_filep.c index 9c7383cf29c..da08ba42bba 100644 --- a/ext/zip/lib/zip_source_filep.c +++ b/ext/zip/lib/zip_source_filep.c @@ -2,7 +2,7 @@ $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, 2003, 2004, 2005 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2006 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -138,24 +138,20 @@ read_file(void *state, void *data, size_t len, enum zip_source_cmd cmd) if (len < sizeof(*st)) return -1; - st = (struct zip_stat *)data; - if (fstat(fileno(z->f), &fst) != 0) { z->e[0] = ZIP_ER_READ; /* best match */ z->e[1] = errno; return -1; } + st = (struct zip_stat *)data; + + zip_stat_init(st); st->mtime = fst.st_mtime; - st->crc = 0; if (z->len != -1) st->size = z->len; else if ((fst.st_mode&S_IFMT) == S_IFREG) st->size = fst.st_size; - else - st->size = -1; - st->comp_size = -1; - st->comp_method = ZIP_CM_STORE; return sizeof(*st); } diff --git a/ext/zip/lib/zip_stat_index.c b/ext/zip/lib/zip_stat_index.c index 837d639077e..bab79a74ba7 100644 --- a/ext/zip/lib/zip_stat_index.c +++ b/ext/zip/lib/zip_stat_index.c @@ -67,8 +67,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->index = index; + st->crc = za->cdir->entry[index].crc; st->size = za->cdir->entry[index].uncomp_size; st->mtime = za->cdir->entry[index].last_mod; @@ -87,6 +86,7 @@ zip_stat_index(struct zip *za, int index, int flags, struct zip_stat *st) /* st->bitflags = za->cdir->entry[index].bitflags; */ } + st->index = index; st->name = name; return 0; diff --git a/ext/zip/lib/zip_stat_init.c b/ext/zip/lib/zip_stat_init.c new file mode 100644 index 00000000000..7ab0f4da75a --- /dev/null +++ b/ext/zip/lib/zip_stat_init.c @@ -0,0 +1,53 @@ +/* + $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 + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zipint.h" + + + +void +zip_stat_init(struct zip_stat *st) +{ + st->name = NULL; + st->index = -1; + st->crc = 0; + st->mtime = (time_t)-1; + st->size = -1; + st->comp_size = -1; + st->comp_method = ZIP_CM_STORE; + st->encryption_method = ZIP_EM_NONE; +} diff --git a/ext/zip/lib/zipint.h b/ext/zip/lib/zipint.h index 9efaf06a330..ebf2743f991 100644 --- a/ext/zip/lib/zipint.h +++ b/ext/zip/lib/zipint.h @@ -199,6 +199,7 @@ 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 *); diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index 73dbad9e373..720d31d0476 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -70,7 +70,8 @@ static int le_zip_entry; } \ } else if (zip_set_file_comment(intern, index, comment, comment_len) < 0) { \ RETURN_FALSE; \ - } + } \ + RETURN_TRUE; /* }}} */ @@ -202,7 +203,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file TSRMLS_D #define RETURN_SB(sb) \ { \ array_init(return_value); \ - add_assoc_string(return_value, "name", estrdup((sb)->name), 0); \ + 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); \ @@ -257,7 +258,6 @@ static char * php_zipobj_get_zip_comment(struct zip *za, int *len TSRMLS_DC) /* return NULL; } /* }}} */ - #endif /* {{{ zend_function_entry */ @@ -888,7 +888,6 @@ ZIPARCHIVE_METHOD(open) ze_zip_object *ze_obj = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &filename, &filename_len, &flags) == FAILURE) { - WRONG_PARAM_COUNT; return; } @@ -924,7 +923,7 @@ ZIPARCHIVE_METHOD(open) } /* }}} */ -/* {{{ proto resource close() +/* {{{ proto bool close() close the zip archive */ ZIPARCHIVE_METHOD(close) { @@ -953,6 +952,35 @@ ZIPARCHIVE_METHOD(close) } /* }}} */ +/* {{{ proto bool createEmptyDir(string dirname) U +Returns the index of the entry named filename in the archive */ +ZIPARCHIVE_METHOD(addEmptyDir) +{ + struct zip *intern; + zval *this = getThis(); + char *dirname; + int dirname_len; + + if (!this) { + RETURN_FALSE; + } + + ZIP_FROM_OBJECT(intern, this); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", + &dirname, &dirname_len) == FAILURE) { + return; + } + if (dirname_len<1) { + RETURN_FALSE; + } + + if (zip_add_dir(intern, (const char *)dirname) < 0) { + RETURN_FALSE; + } +} +/* }}} */ + /* {{{ proto bool addFile(string filepath[, string entryname[, int start [, int length]]]) Add a file in a Zip archive using its path and the name to use. */ ZIPARCHIVE_METHOD(addFile) @@ -1026,7 +1054,7 @@ ZIPARCHIVE_METHOD(addFile) } /* }}} */ -/* {{{ proto resource addFromString(string name, string content) +/* {{{ proto bool addFromString(string name, string content) Add a file using content and the entry name */ ZIPARCHIVE_METHOD(addFromString) { @@ -1047,7 +1075,6 @@ ZIPARCHIVE_METHOD(addFromString) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &name, &name_len, &buffer, &buffer_len) == FAILURE) { - WRONG_PARAM_COUNT; return; } @@ -1092,7 +1119,7 @@ ZIPARCHIVE_METHOD(addFromString) } /* }}} */ -/* {{{ proto resource statName(string filename[, int flags]) +/* {{{ proto array statName(string filename[, int flags]) Returns the information about a the zip entry filename */ ZIPARCHIVE_METHOD(statName) { @@ -1111,7 +1138,6 @@ ZIPARCHIVE_METHOD(statName) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &name, &name_len, &flags) == FAILURE) { - WRONG_PARAM_COUNT; return; } @@ -1139,7 +1165,6 @@ ZIPARCHIVE_METHOD(statIndex) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &index, &flags) == FAILURE) { - WRONG_PARAM_COUNT; return; } @@ -1150,7 +1175,7 @@ ZIPARCHIVE_METHOD(statIndex) } /* }}} */ -/* {{{ proto resource locateName(string filename[, int flags]) +/* {{{ proto int locateName(string filename[, int flags]) Returns the index of the entry named filename in the archive */ ZIPARCHIVE_METHOD(locateName) { @@ -1169,7 +1194,6 @@ ZIPARCHIVE_METHOD(locateName) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &name, &name_len, &flags) == FAILURE) { - WRONG_PARAM_COUNT; return; } if (name_len<1) { @@ -1191,7 +1215,7 @@ ZIPARCHIVE_METHOD(locateName) } /* }}} */ -/* {{{ proto resource getNameIndex(int index [, int flags]) +/* {{{ proto string getNameIndex(int index [, int flags]) Returns the name of the file at position index */ ZIPARCHIVE_METHOD(getNameIndex) { @@ -1208,7 +1232,6 @@ ZIPARCHIVE_METHOD(getNameIndex) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &index, &flags) == FAILURE) { - WRONG_PARAM_COUNT; return; } @@ -1222,7 +1245,7 @@ ZIPARCHIVE_METHOD(getNameIndex) } /* }}} */ -/* {{{ proto resource setArchiveComment(string name, string comment) +/* {{{ proto bool setArchiveComment(string name, string comment) Set or remove (NULL/'') the comment of the archive */ ZIPARCHIVE_METHOD(setArchiveComment) { @@ -1238,7 +1261,6 @@ ZIPARCHIVE_METHOD(setArchiveComment) ZIP_FROM_OBJECT(intern, this); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &comment, &comment_len) == FAILURE) { - WRONG_PARAM_COUNT; return; } if (zip_set_archive_comment(intern, (const char *)comment, (int)comment_len)) { @@ -1249,7 +1271,7 @@ ZIPARCHIVE_METHOD(setArchiveComment) } /* }}} */ -/* {{{ proto resource getArchiveComment() +/* {{{ proto string getArchiveComment() Returns the comment of an entry using its index */ ZIPARCHIVE_METHOD(getArchiveComment) { @@ -1266,16 +1288,15 @@ ZIPARCHIVE_METHOD(getArchiveComment) ZIP_FROM_OBJECT(intern, this); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flags) == FAILURE) { - WRONG_PARAM_COUNT; return; } comment = zip_get_archive_comment(intern, &comment_len, (int)flags); - RETURN_STRINGL((char *)comment, comment_len, 1); + RETURN_STRINGL((char *)comment, (long)comment_len, 1); } /* }}} */ -/* {{{ proto resource setCommentName(string name, string comment) +/* {{{ proto bool setCommentName(string name, string comment) Set or remove (NULL/'') the comment of an entry using its Name */ ZIPARCHIVE_METHOD(setCommentName) { @@ -1283,7 +1304,7 @@ ZIPARCHIVE_METHOD(setCommentName) zval *this = getThis(); int comment_len, name_len; char * comment, *name; - struct zip_stat sb; + int idx; if (!this) { RETURN_FALSE; @@ -1293,17 +1314,22 @@ ZIPARCHIVE_METHOD(setCommentName) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &name, &name_len, &comment, &comment_len) == FAILURE) { - WRONG_PARAM_COUNT; return; } + if (name_len < 1) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Empty string as entry name"); + } - PHP_ZIP_STAT_PATH(intern, name, name_len, 0, sb); - PHP_ZIP_SET_FILE_COMMENT(intern, sb.index, comment, comment_len); + idx = zip_name_locate(intern, name, 0); + if (idx < 0) { + RETURN_FALSE; + } + PHP_ZIP_SET_FILE_COMMENT(intern, idx, comment, comment_len); } /* }}} */ -/* {{{ proto resource setCommentIndex(int index, string comment) +/* {{{ proto bool setCommentIndex(int index, string comment) Set or remove (NULL/'') the comment of an entry using its index */ ZIPARCHIVE_METHOD(setCommentIndex) { @@ -1322,7 +1348,6 @@ ZIPARCHIVE_METHOD(setCommentIndex) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &index, &comment, &comment_len) == FAILURE) { - WRONG_PARAM_COUNT; return; } @@ -1331,18 +1356,17 @@ ZIPARCHIVE_METHOD(setCommentIndex) } /* }}} */ -/* {{{ proto resource getCommentName(string name) +/* {{{ proto string getCommentName(string name) Returns the comment of an entry using its name */ ZIPARCHIVE_METHOD(getCommentName) { struct zip *intern; zval *this = getThis(); - int name_len; + int name_len, idx; long flags = 0; int comment_len = 0; const char * comment; char *name; - struct zip_stat sb; if (!this) { RETURN_FALSE; @@ -1351,18 +1375,25 @@ ZIPARCHIVE_METHOD(getCommentName) ZIP_FROM_OBJECT(intern, this); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", - &name, &name_len, &flags) == FAILURE) { - WRONG_PARAM_COUNT; + &name, &name_len, &flags) == FAILURE) {; return; } + if (name_len < 1) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Empty string as entry name"); + RETURN_FALSE; + } - PHP_ZIP_STAT_PATH(intern, name, name_len, 0, sb); - comment = zip_get_file_comment(intern, sb.index, &comment_len, (int)flags); - RETURN_STRINGL((char *)comment, comment_len, 1); + idx = zip_name_locate(intern, name, 0); + if (idx < 0) { + RETURN_FALSE; + } + + comment = zip_get_file_comment(intern, idx, &comment_len, (int)flags); + RETURN_STRINGL((char *)comment, (long)comment_len, 1); } /* }}} */ -/* {{{ proto resource getCommentIndex(int index) +/* {{{ proto string getCommentIndex(int index) Returns the comment of an entry using its index */ ZIPARCHIVE_METHOD(getCommentIndex) { @@ -1381,17 +1412,16 @@ ZIPARCHIVE_METHOD(getCommentIndex) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &index, &flags) == FAILURE) { - WRONG_PARAM_COUNT; return; } PHP_ZIP_STAT_INDEX(intern, index, 0, sb); comment = zip_get_file_comment(intern, index, &comment_len, (int)flags); - RETURN_STRINGL((char *)comment, comment_len, 1); + RETURN_STRINGL((char *)comment, (long)comment_len, 1); } /* }}} */ -/* {{{ proto resource deleteIndex(int index) +/* {{{ proto bool deleteIndex(int index) Delete a file using its index */ ZIPARCHIVE_METHOD(deleteIndex) { @@ -1406,7 +1436,6 @@ ZIPARCHIVE_METHOD(deleteIndex) ZIP_FROM_OBJECT(intern, this); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == FAILURE) { - WRONG_PARAM_COUNT; return; } @@ -1422,7 +1451,7 @@ ZIPARCHIVE_METHOD(deleteIndex) } /* }}} */ -/* {{{ proto resource deleteName(string name) +/* {{{ proto bool deleteName(string name) Delete a file using its index */ ZIPARCHIVE_METHOD(deleteName) { @@ -1439,7 +1468,6 @@ ZIPARCHIVE_METHOD(deleteName) ZIP_FROM_OBJECT(intern, this); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) { - WRONG_PARAM_COUNT; return; } if (name_len < 1) { @@ -1454,7 +1482,7 @@ ZIPARCHIVE_METHOD(deleteName) } /* }}} */ -/* {{{ proto resource renameIndex(int index, string new_name) +/* {{{ proto bool renameIndex(int index, string new_name) Rename an entry selected by its index to new_name */ ZIPARCHIVE_METHOD(renameIndex) { @@ -1472,7 +1500,6 @@ ZIPARCHIVE_METHOD(renameIndex) ZIP_FROM_OBJECT(intern, this); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &index, &new_name, &new_name_len) == FAILURE) { - WRONG_PARAM_COUNT; return; } @@ -1491,7 +1518,7 @@ ZIPARCHIVE_METHOD(renameIndex) } /* }}} */ -/* {{{ proto resource renameName(string name, string new_name) +/* {{{ proto bool renameName(string name, string new_name) Rename an entry selected by its name to new_name */ ZIPARCHIVE_METHOD(renameName) { @@ -1508,7 +1535,6 @@ ZIPARCHIVE_METHOD(renameName) ZIP_FROM_OBJECT(intern, this); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &name, &name_len, &new_name, &new_name_len) == FAILURE) { - WRONG_PARAM_COUNT; return; } @@ -1526,7 +1552,7 @@ ZIPARCHIVE_METHOD(renameName) } /* }}} */ -/* {{{ proto resource unchangeIndex(int index) +/* {{{ proto bool unchangeIndex(int index) Changes to the file at position index are reverted */ ZIPARCHIVE_METHOD(unchangeIndex) { @@ -1541,7 +1567,6 @@ ZIPARCHIVE_METHOD(unchangeIndex) ZIP_FROM_OBJECT(intern, this); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == FAILURE) { - WRONG_PARAM_COUNT; return; } @@ -1557,7 +1582,7 @@ ZIPARCHIVE_METHOD(unchangeIndex) } /* }}} */ -/* {{{ proto resource unchangeName(string name) +/* {{{ proto bool unchangeName(string name) Changes to the file named 'name' are reverted */ ZIPARCHIVE_METHOD(unchangeName) { @@ -1574,7 +1599,6 @@ ZIPARCHIVE_METHOD(unchangeName) ZIP_FROM_OBJECT(intern, this); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) { - WRONG_PARAM_COUNT; return; } @@ -1592,7 +1616,7 @@ ZIPARCHIVE_METHOD(unchangeName) } /* }}} */ -/* {{{ proto resource unchangeAll() +/* {{{ proto bool unchangeAll() All changes to files and global information in archive are reverted */ ZIPARCHIVE_METHOD(unchangeAll) { @@ -1613,7 +1637,7 @@ ZIPARCHIVE_METHOD(unchangeAll) } /* }}} */ -/* {{{ proto resource unchangeAll() +/* {{{ proto bool unchangeAll() Revert all global changes to the archive archive. For now, this only reverts archive comment changes. */ ZIPARCHIVE_METHOD(unchangeArchive) { @@ -1634,7 +1658,7 @@ ZIPARCHIVE_METHOD(unchangeArchive) } /* }}} */ -/* {{{ array resource extractTo(string pathto[, mixed files]) +/* {{{ array bool extractTo(string pathto[, mixed files]) Extract one or more file from a zip archive */ /* TODO: * - allow index or array of indeces @@ -1661,7 +1685,6 @@ ZIPARCHIVE_METHOD(extractTo) } if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &pathto, &pathto_len, &zval_files) == FAILURE) { - WRONG_PARAM_COUNT; return; } @@ -1757,13 +1780,11 @@ static void php_zip_get_from(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */ if (type == 1) { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &filename, &filename_len, &len, &flags) == FAILURE) { - WRONG_PARAM_COUNT; return; } PHP_ZIP_STAT_PATH(intern, filename, filename_len, flags, sb); } else { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|ll", &index, &len, &flags) == FAILURE) { - WRONG_PARAM_COUNT; return; } PHP_ZIP_STAT_INDEX(intern, index, 0, sb); @@ -1798,7 +1819,7 @@ static void php_zip_get_from(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */ } /* }}} */ -/* {{{ proto resource getFromName(string entryname[, int len [, int flags]]) +/* {{{ proto string getFromName(string entryname[, int len [, int flags]]) get the contents of an entry using its name */ ZIPARCHIVE_METHOD(getFromName) { @@ -1806,7 +1827,7 @@ ZIPARCHIVE_METHOD(getFromName) } /* }}} */ -/* {{{ proto resource getFromIndex(string entryname[, int len [, int flags]]) +/* {{{ proto string getFromIndex(string entryname[, int len [, int flags]]) get the contents of an entry using its index */ ZIPARCHIVE_METHOD(getFromIndex) { @@ -1834,7 +1855,6 @@ ZIPARCHIVE_METHOD(getStream) ZIP_FROM_OBJECT(intern, this); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) { - WRONG_PARAM_COUNT; return; } @@ -1855,6 +1875,7 @@ 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(addEmptyDir, NULL, ZEND_ACC_PUBLIC) ZIPARCHIVE_ME(addFromString, NULL, ZEND_ACC_PUBLIC) ZIPARCHIVE_ME(addFile, NULL, ZEND_ACC_PUBLIC) ZIPARCHIVE_ME(renameIndex, NULL, ZEND_ACC_PUBLIC) diff --git a/ext/zip/tests/oo_addemptydir.phpt b/ext/zip/tests/oo_addemptydir.phpt new file mode 100644 index 00000000000..cb57b5b2122 --- /dev/null +++ b/ext/zip/tests/oo_addemptydir.phpt @@ -0,0 +1,36 @@ +--TEST-- +ziparchive::addEmptyDir +--SKIPIF-- + +--FILE-- +open($file)) { + exit('failed'); +} + +$zip->addEmptyDir('emptydir'); +if ($zip->status == ZIPARCHIVE::ER_OK) { + dump_entries_name($zip); + $zip->close(); +} else { + echo "failed\n"; +} +@unlink($file); +?> +--EXPECTF-- +0 bar +1 foobar/ +2 foobar/baz +3 entry1.txt +4 emptydir/ diff --git a/ext/zip/tests/oo_extract.phpt b/ext/zip/tests/oo_extract.phpt new file mode 100644 index 00000000000..7ca39eeab84 --- /dev/null +++ b/ext/zip/tests/oo_extract.phpt @@ -0,0 +1,95 @@ +--TEST-- +extractTo +--SKIPIF-- + +--FILE-- +open($file) !== TRUE) { + echo "open failed.\n"; + exit('failed'); +} + +$zip->extractTo($dirname . '__oo_extract_tmp'); +if (!is_dir($dirname . '__oo_extract_tmp')) { + echo "failed. mkdir\n"; +} + +if (!is_dir($dirname .'__oo_extract_tmp/foobar')) { + echo "failed. mkdir foobar\n"; +} + +if (!file_exists($dirname . '__oo_extract_tmp/foobar/baz')) { + echo "failed. extract foobar/baz\n"; +} else { + echo file_get_contents($dirname . '__oo_extract_tmp/foobar/baz') . "\n"; +} + +if (!file_exists($dirname . '__oo_extract_tmp/bar')) { + echo "failed. bar file\n"; +} else { + echo file_get_contents($dirname . '__oo_extract_tmp/bar') . "\n"; +} + +if (!file_exists($dirname . '__oo_extract_tmp/foo')) { + echo "failed. foo file\n"; +} else { + echo file_get_contents($dirname . '__oo_extract_tmp/foo') . "\n"; +} + + +/* extract one file */ +$zip->extractTo($dirname . '__oo_extract_tmp', 'bar'); +if (!file_exists($dirname . '__oo_extract_tmp/bar')) { + echo "failed. extract bar file\n"; +} else { + echo file_get_contents($dirname . '__oo_extract_tmp/bar') . "\n"; +} + +/* extract two files */ +$zip->extractTo($dirname . '__oo_extract_tmp', array('bar','foo')); +if (!file_exists($dirname . '__oo_extract_tmp/bar')) { + echo "failed. extract bar file\n"; +} else { + echo file_get_contents($dirname . '__oo_extract_tmp/bar') . "\n"; +} +if (!file_exists($dirname . '__oo_extract_tmp/foo')) { + echo "failed. extract foo file\n"; +} else { + echo file_get_contents($dirname . '__oo_extract_tmp/foo') . "\n"; +} + +rmdir_rf($dirname . '__oo_extract_tmp'); +?> +--EXPECTF-- +blabla laber rababer sülz + +bar + +foo + + +bar + +bar + +foo +--UEXPECTF-- +blabla laber rababer sülz + +bar + +foo + + +bar + +bar + +foo diff --git a/ext/zip/tests/oo_get_comment.phpt b/ext/zip/tests/oo_get_comment.phpt new file mode 100644 index 00000000000..2bcbe295438 --- /dev/null +++ b/ext/zip/tests/oo_get_comment.phpt @@ -0,0 +1,26 @@ +--TEST-- +Get Comment +--SKIPIF-- + +--FILE-- +open($file)) { + exit('failed'); +} +$idx = $zip->locateName('foo'); +echo $zip->getCommentName('foo') . "\n"; +echo $zip->getCommentIndex($idx); + +$zip->close(); + +?> +--EXPECTF-- +foo comment +foo comment diff --git a/ext/zip/tests/oo_getnameindex.phpt b/ext/zip/tests/oo_getnameindex.phpt new file mode 100644 index 00000000000..cd4c9dbe30b --- /dev/null +++ b/ext/zip/tests/oo_getnameindex.phpt @@ -0,0 +1,47 @@ +--TEST-- +getNameIndex +--SKIPIF-- + +--FILE-- +open($file, ZIPARCHIVE::CREATE)) { + exit('failed'); +} + +$zip->addFromString('entry1.txt', 'entry #1'); +$zip->addFromString('entry2.txt', 'entry #2'); +$zip->addFromString('dir/entry2d.txt', 'entry #2'); + +if (!$zip->status == ZIPARCHIVE::ER_OK) { + echo "failed to write zip\n"; +} +$zip->close(); + +if (!$zip->open($file)) { + exit('failed'); +} + + +var_dump($zip->getNameIndex(0)); +var_dump($zip->getNameIndex(1)); +var_dump($zip->getNameIndex(2)); +var_dump($zip->getNameIndex(3)); + +$zip->close(); + +?> +--EXPECTF-- +string(10) "entry1.txt" +string(10) "entry2.txt" +string(15) "dir/entry2d.txt" +bool(false) diff --git a/ext/zip/tests/oo_setcomment.phpt b/ext/zip/tests/oo_setcomment.phpt new file mode 100644 index 00000000000..89d6e8ef6b1 --- /dev/null +++ b/ext/zip/tests/oo_setcomment.phpt @@ -0,0 +1,71 @@ +--TEST-- +setComment +--SKIPIF-- + +--FILE-- +open($file, ZIPARCHIVE::CREATE)) { + exit('failed'); +} + +$zip->addFromString('entry1.txt', 'entry #1'); +$zip->addFromString('entry2.txt', 'entry #2'); +$zip->addFromString('dir/entry2d.txt', 'entry #2'); +$zip->addFromString('entry4.txt', 'entry #1'); +$zip->addFromString('entry5.txt', 'entry #2'); + + +var_dump($zip->setCommentName('entry1.txt', 'entry1.txt')); +var_dump($zip->setCommentName('entry2.txt', 'entry2.txt')); +var_dump($zip->setCommentName('dir/entry2d.txt', 'dir/entry2d.txt')); +var_dump($zip->setArchiveComment('archive')); + +var_dump($zip->setCommentIndex(3, 'entry4.txt')); +var_dump($zip->setCommentIndex(4, 'entry5.txt')); +var_dump($zip->setArchiveComment('archive')); + +if (!$zip->status == ZIPARCHIVE::ER_OK) { + echo "failed to write zip\n"; +} +$zip->close(); + +if (!$zip->open($file)) { + @unlink($file); + exit('failed'); +} + +var_dump($zip->getCommentIndex(0)); +var_dump($zip->getCommentIndex(1)); +var_dump($zip->getCommentIndex(2)); +var_dump($zip->getCommentIndex(3)); +var_dump($zip->getCommentIndex(4)); +var_dump($zip->getArchiveComment()); + +$zip->close(); +@unlink($file); + +?> +--EXPECTF-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +string(10) "entry1.txt" +string(10) "entry2.txt" +string(15) "dir/entry2d.txt" +string(10) "entry4.txt" +string(10) "entry5.txt" +string(7) "archive" diff --git a/ext/zip/tests/oo_stream.phpt b/ext/zip/tests/oo_stream.phpt new file mode 100644 index 00000000000..126e78f6f7f --- /dev/null +++ b/ext/zip/tests/oo_stream.phpt @@ -0,0 +1,50 @@ +--TEST-- +getStream +--SKIPIF-- + +--FILE-- +open($file)) { + exit('failed'); +} +$fp = $zip->getStream('foo'); + +var_dump($fp); +if(!$fp) exit("\n"); +$contents = ''; +while (!feof($fp)) { + $contents .= fread($fp, 255); +} + +fclose($fp); +$zip->close(); +var_dump($contents); + + +$fp = fopen('zip://' . dirname(__FILE__) . '/test_with_comment.zip#foo', 'rb'); +if (!$fp) { + exit("cannot open\n"); +} +$contents = ''; +while (!feof($fp)) { + $contents .= fread($fp, 2); +} +var_dump($contents); +fclose($fp); + +?> +--EXPECTF-- +resource(%d) of type (stream) +string(5) "foo + +" +string(5) "foo + +" diff --git a/ext/zip/tests/test_with_comment.zip b/ext/zip/tests/test_with_comment.zip new file mode 100644 index 00000000000..d68f76157a3 Binary files /dev/null and b/ext/zip/tests/test_with_comment.zip differ diff --git a/ext/zip/tests/utils.inc b/ext/zip/tests/utils.inc index 41a27912664..02e37f6d544 100644 --- a/ext/zip/tests/utils.inc +++ b/ext/zip/tests/utils.inc @@ -6,3 +6,19 @@ function dump_entries_name($z) { echo $i . ' ' . $sb['name'] . "\n"; } } +/* recursively remove a directoryy */ +function rmdir_rf($dir) { + if ($handle = opendir($dir)) { + while (false !== ($item = readdir($handle))) { + if ($item != "." && $item != "..") { + if (is_dir($dir . '/' . $item)) { + rmdir_rf($dir . '/' . $item); + } else { + unlink($dir . '/' . $item); + } + } + } + closedir($handle); + rmdir($dir); + } +} diff --git a/ext/zip/tests/zip_entry_open.phpt b/ext/zip/tests/zip_entry_open.phpt index b79e39108fc..c32fe57407e 100644 --- a/ext/zip/tests/zip_entry_open.phpt +++ b/ext/zip/tests/zip_entry_open.phpt @@ -10,6 +10,7 @@ if(!extension_loaded('zip')) die('skip'); $zip = zip_open(dirname(__FILE__)."/test_procedural.zip"); $entry = zip_read($zip); echo zip_entry_open($zip, $entry, "r") ? "OK" : "Failure"; +zip_entry_close($entry); zip_close($zip); ?> diff --git a/ext/zip/tests/zip_entry_read.phpt b/ext/zip/tests/zip_entry_read.phpt index 94dde59cbd2..d876f03fb51 100644 --- a/ext/zip/tests/zip_entry_read.phpt +++ b/ext/zip/tests/zip_entry_read.phpt @@ -11,6 +11,7 @@ $zip = zip_open(dirname(__FILE__)."/test_procedural.zip"); $entry = zip_read($zip); if (!zip_entry_open($zip, $entry, "r")) die("Failure"); echo zip_entry_read($entry); +zip_entry_close($entry); zip_close($zip); ?>