diff --git a/ext/zip/lib/zip.h b/ext/zip/lib/zip.h index 93c791f14cc..8cf690cad3f 100644 --- a/ext/zip/lib/zip.h +++ b/ext/zip/lib/zip.h @@ -53,6 +53,7 @@ extern "C" { #define ZIP_CREATE 1 #define ZIP_EXCL 2 #define ZIP_CHECKCONS 4 +#define ZIP_OVERWRITE 8 /* flags for zip_name_locate, zip_fopen, zip_stat, ... */ diff --git a/ext/zip/lib/zip_open.c b/ext/zip/lib/zip_open.c index 65ba8a5b9f6..0a14abda583 100644 --- a/ext/zip/lib/zip_open.c +++ b/ext/zip/lib/zip_open.c @@ -74,9 +74,9 @@ zip_open(const char *fn, int flags, int *zep) set_error(zep, NULL, ZIP_ER_INVAL); return NULL; } - - if (stat(fn, &st) != 0) { - if (flags & ZIP_CREATE) { + + 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; @@ -99,14 +99,15 @@ zip_open(const char *fn, int flags, int *zep) set_error(zep, NULL, ZIP_ER_EXISTS); 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; - } - + if ((fp=fopen(fn, "rb")) == NULL) { + set_error(zep, NULL, ZIP_ER_OPEN); + return NULL; + } + clearerr(fp); fseek(fp, 0, SEEK_END); len = ftell(fp); diff --git a/ext/zip/lib/zip_replace.c b/ext/zip/lib/zip_replace.c index 011bbc2af08..ae78e62b800 100644 --- a/ext/zip/lib/zip_replace.c +++ b/ext/zip/lib/zip_replace.c @@ -66,11 +66,14 @@ _zip_replace(struct zip *za, int idx, const char *name, return -1; idx = za->nentry - 1; } - + + _zip_unchange_data(za->entry+idx); if (name && _zip_set_name(za, idx, name) != 0) 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/php_zip.c b/ext/zip/php_zip.c index d405ffd44f9..27f0bb2dd75 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -113,7 +113,11 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file TSRMLS_D php_basename(file, file_len, NULL, 0, &file_basename, &file_basename_len TSRMLS_CC); - SAFEMODE_CHECKFILE(file_dirname_fullpath); + if (SAFEMODE_CHECKFILE(file_dirname_fullpath)) { + efree(file_dirname_fullpath); + efree(file_basename); + return 0; + } /* let see if the path already exists */ if (php_stream_stat_path(file_dirname_fullpath, &ssb) < 0) { @@ -143,7 +147,11 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file TSRMLS_D * is required, does a file can have a different * safemode status as its parent folder? */ - SAFEMODE_CHECKFILE(fullpath); + if (SAFEMODE_CHECKFILE(fullpath)) { + efree(file_dirname_fullpath); + efree(file_basename); + return 0; + } zf = zip_fopen(za, file, 0); if (zf == NULL) { @@ -1880,6 +1888,8 @@ PHP_MINIT_FUNCTION(zip) REGISTER_ZIP_CLASS_CONST_LONG("CREATE", ZIP_CREATE); REGISTER_ZIP_CLASS_CONST_LONG("EXCL", ZIP_EXCL); REGISTER_ZIP_CLASS_CONST_LONG("CHECKCONS", ZIP_CHECKCONS); + REGISTER_ZIP_CLASS_CONST_LONG("OVERWRITE", ZIP_OVERWRITE); + REGISTER_ZIP_CLASS_CONST_LONG("FL_NOCASE", ZIP_FL_NOCASE); REGISTER_ZIP_CLASS_CONST_LONG("FL_NODIR", ZIP_FL_NODIR); REGISTER_ZIP_CLASS_CONST_LONG("FL_COMPRESSED", ZIP_FL_COMPRESSED);