- fix possible leak in statName and statIndex
 - add addEmptyDir() method
 - add zip_stat_init,zip_clear_error and zip_file_clear_error
 - add tests
 - Fix protos (Hannes)
 - setComment return value on success (Hannes)
This commit is contained in:
Pierre Joye 2006-11-03 16:46:19 +00:00
parent c002606a88
commit 8ad0c6d543
25 changed files with 681 additions and 78 deletions

View File

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

View File

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

View File

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

View File

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

83
ext/zip/lib/zip_add_dir.c Normal file
View File

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

View File

@ -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 <nih@giga.or.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;
}

View File

@ -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 <nih@giga.or.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);
}

View File

@ -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 <nih@giga.or.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);
}

View File

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

View File

@ -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 <nih@giga.or.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);
}

View File

@ -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 <nih@giga.or.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);
}

View File

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

View File

@ -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 <nih@giga.or.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;
}

View File

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

View File

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

View File

@ -0,0 +1,36 @@
--TEST--
ziparchive::addEmptyDir
--SKIPIF--
<?php
/* $Id$ */
if(!extension_loaded('zip')) die('skip');
?>
--FILE--
<?php
$dirname = dirname(__FILE__) . '/';
include $dirname . 'utils.inc';
$file = $dirname . '__tmp_oo_addfile.zip';
copy($dirname . 'test.zip', $file);
$zip = new ZipArchive;
if (!$zip->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/

View File

@ -0,0 +1,95 @@
--TEST--
extractTo
--SKIPIF--
<?php
/* $Id$ */
if(!extension_loaded('zip')) die('skip');
?>
--FILE--
<?php
$dirname = dirname(__FILE__) . '/';
$file = $dirname . 'test_with_comment.zip';
include $dirname . 'utils.inc';
$zip = new ZipArchive;
if ($zip->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

View File

@ -0,0 +1,26 @@
--TEST--
Get Comment
--SKIPIF--
<?php
/* $Id$ */
if(!extension_loaded('zip')) die('skip');
?>
--FILE--
<?php
$dirname = dirname(__FILE__) . '/';
$file = $dirname . 'test_with_comment.zip';
include $dirname . 'utils.inc';
$zip = new ZipArchive;
if (!$zip->open($file)) {
exit('failed');
}
$idx = $zip->locateName('foo');
echo $zip->getCommentName('foo') . "\n";
echo $zip->getCommentIndex($idx);
$zip->close();
?>
--EXPECTF--
foo comment
foo comment

View File

@ -0,0 +1,47 @@
--TEST--
getNameIndex
--SKIPIF--
<?php
/* $Id$ */
if(!extension_loaded('zip')) die('skip');
?>
--FILE--
<?php
$dirname = dirname(__FILE__) . '/';
include $dirname . 'utils.inc';
$file = $dirname . '__tmp_oo_rename.zip';
@unlink($file);
$zip = new ZipArchive;
if (!$zip->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)

View File

@ -0,0 +1,71 @@
--TEST--
setComment
--SKIPIF--
<?php
/* $Id$ */
if(!extension_loaded('zip')) die('skip');
?>
--FILE--
<?php
$dirname = dirname(__FILE__) . '/';
include $dirname . 'utils.inc';
$file = $dirname . '__tmp_oo_set_comment.zip';
@unlink($file);
$zip = new ZipArchive;
if (!$zip->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"

View File

@ -0,0 +1,50 @@
--TEST--
getStream
--SKIPIF--
<?php
/* $Id$ */
if(!extension_loaded('zip')) die('skip');
?>
--FILE--
<?php
$dirname = dirname(__FILE__) . '/';
$file = $dirname . 'test_with_comment.zip';
include $dirname . 'utils.inc';
$zip = new ZipArchive;
if (!$zip->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
"

Binary file not shown.

View File

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

View File

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

View File

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