]> granicus.if.org Git - php/commitdiff
- add ZipArchive::FL_RECOMPRESS, FL_ENCRYPTED, FL_OVERWRITE, FL_LOCAL, FL_CENTRAL...
authorRemi Collet <remi@remirepo.net>
Fri, 28 Feb 2020 14:51:33 +0000 (15:51 +0100)
committerRemi Collet <remi@php.net>
Mon, 2 Mar 2020 15:48:53 +0000 (16:48 +0100)
- add optional "flags" parameter to ZipArchive::addEmptyDir, addFile and addFromString methods
- add "flags" options to ZipArchive::addGlob and addPattern methods
  keeping previous behavior having FL_OVERWRITE by default
- add ZipArchive::replaceFile() method

ext/zip/php_zip.c
ext/zip/php_zip.stub.php
ext/zip/php_zip_arginfo.h
ext/zip/tests/oo_add_encoding.phpt [new file with mode: 0644]
ext/zip/tests/oo_add_from_string.phpt [new file with mode: 0644]
ext/zip/tests/oo_addglob.phpt
ext/zip/tests/oo_addpattern.phpt
ext/zip/tests/oo_replacefile.phpt [new file with mode: 0644]
ext/zip/tests/utils.inc

index e2be7fc6685790250c569ca6fdcc6699dacbbcb7..dce9cb8a27503de74d6004fd40106268e49a1cb8 100644 (file)
@@ -276,7 +276,11 @@ done:
 /* }}} */
 
 static int php_zip_add_file(struct zip *za, const char *filename, size_t filename_len,
-       char *entry_name, size_t entry_name_len, long offset_start, long offset_len) /* {{{ */
+       char *entry_name, size_t entry_name_len, /* unused if replace >= 0 */
+       zip_uint64_t offset_start, zip_uint64_t offset_len,
+       zend_long replace, /* index to replace, add new file if < 0 */
+       zip_flags_t flags
+) /* {{{ */
 {
        struct zip_source *zs;
        char resolved_path[MAXPATHLEN];
@@ -300,17 +304,30 @@ static int php_zip_add_file(struct zip *za, const char *filename, size_t filenam
        if (!zs) {
                return -1;
        }
-       if (zip_file_add(za, entry_name, zs, ZIP_FL_OVERWRITE) < 0) {
-               zip_source_free(zs);
-               return -1;
-       } else {
+       // Replace
+       if (replace >= 0) {
+               if (zip_file_replace(za, replace, zs, flags) < 0) {
+                       zip_source_free(zs);
+                       return -1;
+               }
                zip_error_clear(za);
                return 1;
        }
+       // Add
+       if (zip_file_add(za, entry_name, zs, flags) < 0) {
+               zip_source_free(zs);
+               return -1;
+       }
+       zip_error_clear(za);
+       return 1;
 }
 /* }}} */
 
-static int php_zip_parse_options(zval *options, zend_long *remove_all_path, char **remove_path, size_t *remove_path_len, char **add_path, size_t *add_path_len) /* {{{ */
+static int php_zip_parse_options(zval *options, zend_long *remove_all_path,
+       char **remove_path, size_t *remove_path_len,
+       char **add_path, size_t *add_path_len,
+       zend_long *flags
+) /* {{{ */
 {
        zval *option;
        if ((option = zend_hash_str_find(Z_ARRVAL_P(options), "remove_all_path", sizeof("remove_all_path") - 1)) != NULL) {
@@ -357,6 +374,15 @@ static int php_zip_parse_options(zval *options, zend_long *remove_all_path, char
                *add_path_len = Z_STRLEN_P(option);
                *add_path = Z_STRVAL_P(option);
        }
+
+       if ((option = zend_hash_str_find(Z_ARRVAL_P(options), "flags", sizeof("flags") - 1)) != NULL) {
+               if (Z_TYPE_P(option) != IS_LONG) {
+                       php_error_docref(NULL, E_WARNING, "flags option expected to be a integer");
+                       return -1;
+               }
+               *flags = Z_LVAL_P(option);
+       }
+
        return 1;
 }
 /* }}} */
@@ -1545,7 +1571,7 @@ static ZIPARCHIVE_METHOD(getStatusString)
 }
 /* }}} */
 
-/* {{{ proto bool ZipArchive::createEmptyDir(string dirname)
+/* {{{ proto bool ZipArchive::addEmptyDir(string dirname [, bool flags = 0])
 Returns the index of the entry named filename in the archive */
 static ZIPARCHIVE_METHOD(addEmptyDir)
 {
@@ -1556,11 +1582,12 @@ static ZIPARCHIVE_METHOD(addEmptyDir)
        int idx;
        struct zip_stat sb;
        char *s;
+       zend_long flags = 0;
 
        ZIP_FROM_OBJECT(intern, self);
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS(), "s",
-                               &dirname, &dirname_len) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|l",
+                               &dirname, &dirname_len, &flags) == FAILURE) {
                RETURN_THROWS();
        }
 
@@ -1581,7 +1608,7 @@ static ZIPARCHIVE_METHOD(addEmptyDir)
        if (idx >= 0) {
                RETVAL_FALSE;
        } else {
-               if (zip_dir_add(intern, (const char *)s, 0) == -1) {
+               if (zip_dir_add(intern, (const char *)s, flags) == -1) {
                        RETVAL_FALSE;
                } else {
                        zip_error_clear(intern);
@@ -1604,7 +1631,8 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
        char *add_path = NULL;
        size_t  add_path_len, remove_path_len = 0, path_len = 1;
        zend_long remove_all_path = 0;
-       zend_long flags = 0;
+       zend_long glob_flags = 0;
+       zend_long zip_flags = ZIP_FL_OVERWRITE;
        zval *options = NULL;
        int found;
        zend_string *pattern;
@@ -1613,7 +1641,7 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
        /* 1 == glob, 2 == pcre */
        if (type == 1) {
                if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|la",
-                                       &pattern, &flags, &options) == FAILURE) {
+                                       &pattern, &glob_flags, &options) == FAILURE) {
                        RETURN_THROWS();
                }
        } else {
@@ -1628,7 +1656,7 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
                RETURN_FALSE;
        }
        if (options && (php_zip_parse_options(options, &remove_all_path, &remove_path, &remove_path_len,
-                       &add_path, &add_path_len) < 0)) {
+                       &add_path, &add_path_len, &zip_flags) < 0)) {
                RETURN_FALSE;
        }
 
@@ -1642,7 +1670,7 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
        }
 
        if (type == 1) {
-               found = php_zip_glob(ZSTR_VAL(pattern), ZSTR_LEN(pattern), flags, return_value);
+               found = php_zip_glob(ZSTR_VAL(pattern), ZSTR_LEN(pattern), glob_flags, return_value);
        } else {
                found = php_zip_pcre(pattern, path, path_len, return_value);
        }
@@ -1690,7 +1718,7 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
                                }
 
                                if (php_zip_add_file(intern, Z_STRVAL_P(zval_file), Z_STRLEN_P(zval_file),
-                                       entry_name, entry_name_len, 0, 0) < 0) {
+                                       entry_name, entry_name_len, 0, 0, -1, zip_flags) < 0) {
                                        zend_array_destroy(Z_ARR_P(return_value));
                                        RETURN_FALSE;
                                }
@@ -1719,7 +1747,7 @@ static ZIPARCHIVE_METHOD(addPattern)
 }
 /* }}} */
 
-/* {{{ proto bool ZipArchive::addFile(string filepath[, string entryname[, int start [, int length]]])
+/* {{{ proto bool ZipArchive::addFile(string filepath[, string entryname[, int start [, int length [, int flags = FL_OVERWRITE]]]])
 Add a file in a Zip archive using its path and the name to use. */
 static ZIPARCHIVE_METHOD(addFile)
 {
@@ -1729,11 +1757,12 @@ static ZIPARCHIVE_METHOD(addFile)
        size_t entry_name_len = 0;
        zend_long offset_start = 0, offset_len = 0;
        zend_string *filename;
+       zend_long flags = ZIP_FL_OVERWRITE;
 
        ZIP_FROM_OBJECT(intern, self);
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|sll",
-                       &filename, &entry_name, &entry_name_len, &offset_start, &offset_len) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|slll",
+                       &filename, &entry_name, &entry_name_len, &offset_start, &offset_len, &flags) == FAILURE) {
                RETURN_THROWS();
        }
 
@@ -1748,7 +1777,44 @@ static ZIPARCHIVE_METHOD(addFile)
        }
 
        if (php_zip_add_file(intern, ZSTR_VAL(filename), ZSTR_LEN(filename),
-                       entry_name, entry_name_len, offset_start, offset_len) < 0) {
+                       entry_name, entry_name_len, offset_start, offset_len, -1, flags) < 0) {
+               RETURN_FALSE;
+       } else {
+               RETURN_TRUE;
+       }
+}
+/* }}} */
+
+/* {{{ proto bool ZipArchive::replaceFile(string filepath, int index[, int start [, int length [, int flags = 0]]])
+Add a file in a Zip archive using its path and the name to use. */
+static ZIPARCHIVE_METHOD(replaceFile)
+{
+       struct zip *intern;
+       zval *self = ZEND_THIS;
+       zend_long index;
+       zend_long offset_start = 0, offset_len = 0;
+       zend_string *filename;
+       zend_long flags = ZIP_FL_OVERWRITE;
+
+       ZIP_FROM_OBJECT(intern, self);
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS(), "Pl|lll",
+                       &filename, &index, &offset_start, &offset_len, &flags) == FAILURE) {
+               RETURN_THROWS();
+       }
+
+       if (ZSTR_LEN(filename) == 0) {
+               php_error_docref(NULL, E_NOTICE, "Empty string as filename");
+               RETURN_FALSE;
+       }
+
+       if (index < 0) {
+               php_error_docref(NULL, E_NOTICE, "Invalid negative index");
+               RETURN_FALSE;
+       }
+
+       if (php_zip_add_file(intern, ZSTR_VAL(filename), ZSTR_LEN(filename),
+                       NULL, 0, offset_start, offset_len, index, flags) < 0) {
                RETURN_FALSE;
        } else {
                RETURN_TRUE;
@@ -1756,7 +1822,7 @@ static ZIPARCHIVE_METHOD(addFile)
 }
 /* }}} */
 
-/* {{{ proto bool ZipArchive::addFromString(string name, string content)
+/* {{{ proto bool ZipArchive::addFromString(string name, string content [, int flags = FL_OVERWRITE])
 Add a file using content and the entry name */
 static ZIPARCHIVE_METHOD(addFromString)
 {
@@ -1768,12 +1834,12 @@ static ZIPARCHIVE_METHOD(addFromString)
        ze_zip_object *ze_obj;
        struct zip_source *zs;
        int pos = 0;
-       int cur_idx;
+       zend_long flags = ZIP_FL_OVERWRITE;
 
        ZIP_FROM_OBJECT(intern, self);
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS(), "sS",
-                       &name, &name_len, &buffer) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS(), "sS|l",
+                       &name, &name_len, &buffer, &flags) == FAILURE) {
                RETURN_THROWS();
        }
 
@@ -1795,16 +1861,7 @@ static ZIPARCHIVE_METHOD(addFromString)
                RETURN_FALSE;
        }
 
-       cur_idx = zip_name_locate(intern, (const char *)name, 0);
-       /* TODO: fix  _zip_replace */
-       if (cur_idx >= 0) {
-               if (zip_delete(intern, cur_idx) == -1) {
-                       zip_source_free(zs);
-                       RETURN_FALSE;
-               }
-       }
-
-       if (zip_file_add(intern, name, zs, 0) == -1) {
+       if (zip_file_add(intern, name, zs, flags) == -1) {
                zip_source_free(zs);
                RETURN_FALSE;
        } else {
@@ -2939,6 +2996,7 @@ static const zend_function_entry zip_class_functions[] = {
        ZIPARCHIVE_ME(addPattern,                       arginfo_class_ZipArchive_addPattern, ZEND_ACC_PUBLIC)
        ZIPARCHIVE_ME(renameIndex,                      arginfo_class_ZipArchive_renameIndex, ZEND_ACC_PUBLIC)
        ZIPARCHIVE_ME(renameName,                       arginfo_class_ZipArchive_renameName, ZEND_ACC_PUBLIC)
+       ZIPARCHIVE_ME(replaceFile,                      arginfo_class_ZipArchive_replaceFile, ZEND_ACC_PUBLIC)
        ZIPARCHIVE_ME(setArchiveComment,        arginfo_class_ZipArchive_setArchiveComment, ZEND_ACC_PUBLIC)
        ZIPARCHIVE_ME(getArchiveComment,        arginfo_class_ZipArchive_getArchiveComment, ZEND_ACC_PUBLIC)
        ZIPARCHIVE_ME(setCommentIndex,          arginfo_class_ZipArchive_setCommentIndex, ZEND_ACC_PUBLIC)
@@ -3030,23 +3088,18 @@ static PHP_MINIT_FUNCTION(zip)
        REGISTER_ZIP_CLASS_CONST_LONG("FL_NODIR", ZIP_FL_NODIR);
        REGISTER_ZIP_CLASS_CONST_LONG("FL_COMPRESSED", ZIP_FL_COMPRESSED);
        REGISTER_ZIP_CLASS_CONST_LONG("FL_UNCHANGED", ZIP_FL_UNCHANGED);
+       REGISTER_ZIP_CLASS_CONST_LONG("FL_RECOMPRESS", ZIP_FL_RECOMPRESS);
+       REGISTER_ZIP_CLASS_CONST_LONG("FL_ENCRYPTED", ZIP_FL_ENCRYPTED);
+       REGISTER_ZIP_CLASS_CONST_LONG("FL_OVERWRITE", ZIP_FL_OVERWRITE);
+       REGISTER_ZIP_CLASS_CONST_LONG("FL_LOCAL", ZIP_FL_LOCAL);
+       REGISTER_ZIP_CLASS_CONST_LONG("FL_CENTRAL", ZIP_FL_CENTRAL);
 
-#ifdef ZIP_FL_ENC_GUESS
        /* Default filename encoding policy. */
        REGISTER_ZIP_CLASS_CONST_LONG("FL_ENC_GUESS", ZIP_FL_ENC_GUESS);
-#endif
-#ifdef ZIP_FL_ENC_RAW
        REGISTER_ZIP_CLASS_CONST_LONG("FL_ENC_RAW", ZIP_FL_ENC_RAW);
-#endif
-#ifdef ZIP_FL_ENC_STRICT
        REGISTER_ZIP_CLASS_CONST_LONG("FL_ENC_STRICT", ZIP_FL_ENC_STRICT);
-#endif
-#ifdef ZIP_FL_ENC_UTF_8
        REGISTER_ZIP_CLASS_CONST_LONG("FL_ENC_UTF_8", ZIP_FL_ENC_UTF_8);
-#endif
-#ifdef ZIP_FL_ENC_CP437
        REGISTER_ZIP_CLASS_CONST_LONG("FL_ENC_CP437", ZIP_FL_ENC_CP437);
-#endif
 
        REGISTER_ZIP_CLASS_CONST_LONG("CM_DEFAULT", ZIP_CM_DEFAULT);
        REGISTER_ZIP_CLASS_CONST_LONG("CM_STORE", ZIP_CM_STORE);
index 3e49c4641378581665a97c46e11099096520ab1f..1e3ceb6d073b089dd291d4cb5f897a9260821577 100644 (file)
@@ -58,13 +58,16 @@ class ZipArchive
     public function getStatusString() {}
 
     /** @return bool */
-    public function addEmptyDir(string $dirname) {}
+    public function addEmptyDir(string $dirname, int $flags = 0) {}
 
     /** @return bool */
-    public function addFromString(string $name, string $content) {}
+    public function addFromString(string $name, string $content, int $flags = ZipArchive::FL_OVERWRITE) {}
 
     /** @return bool */
-    public function addFile(string $filepath, string $entryname = UNKNOWN, int $start = 0, int $length = 0) {}
+    public function addFile(string $filepath, string $entryname = UNKNOWN, int $start = 0, int $length = 0, int $flags = ZipArchive::FL_OVERWRITE) {}
+
+    /** @return bool */
+    public function replaceFile(string $filepath, string $index, int $start = 0, int $length = 0, int $flags = 0) {}
 
     /** @return array|false */
     public function addGlob(string $pattern, int $flags = 0, $options = UNKNOWN) {}
index 2f788d8c308de761b96838fcef8af7179ee9e2ec..a90b7681719ea2a10f6d28f106f3586ed6f7fee5 100644 (file)
@@ -57,11 +57,13 @@ ZEND_END_ARG_INFO()
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZipArchive_addEmptyDir, 0, 0, 1)
        ZEND_ARG_TYPE_INFO(0, dirname, IS_STRING, 0)
+       ZEND_ARG_TYPE_INFO(0, flags, IS_LONG, 0)
 ZEND_END_ARG_INFO()
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZipArchive_addFromString, 0, 0, 2)
        ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0)
        ZEND_ARG_TYPE_INFO(0, content, IS_STRING, 0)
+       ZEND_ARG_TYPE_INFO(0, flags, IS_LONG, 0)
 ZEND_END_ARG_INFO()
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZipArchive_addFile, 0, 0, 1)
@@ -69,6 +71,15 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZipArchive_addFile, 0, 0, 1)
        ZEND_ARG_TYPE_INFO(0, entryname, IS_STRING, 0)
        ZEND_ARG_TYPE_INFO(0, start, IS_LONG, 0)
        ZEND_ARG_TYPE_INFO(0, length, IS_LONG, 0)
+       ZEND_ARG_TYPE_INFO(0, flags, IS_LONG, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZipArchive_replaceFile, 0, 0, 2)
+       ZEND_ARG_TYPE_INFO(0, filepath, IS_STRING, 0)
+       ZEND_ARG_TYPE_INFO(0, index, IS_STRING, 0)
+       ZEND_ARG_TYPE_INFO(0, start, IS_LONG, 0)
+       ZEND_ARG_TYPE_INFO(0, length, IS_LONG, 0)
+       ZEND_ARG_TYPE_INFO(0, flags, IS_LONG, 0)
 ZEND_END_ARG_INFO()
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZipArchive_addGlob, 0, 0, 1)
diff --git a/ext/zip/tests/oo_add_encoding.phpt b/ext/zip/tests/oo_add_encoding.phpt
new file mode 100644 (file)
index 0000000..43e9110
--- /dev/null
@@ -0,0 +1,48 @@
+--TEST--
+ziparchive::addEmptyDir with encoding option
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+
+include __DIR__ . '/utils.inc';
+$dirname = __DIR__ . '/oo_add_encoding_dir/';
+$file = $dirname . 'tmp.zip';
+
+@mkdir($dirname);
+$zip = new ZipArchive;
+if (!$zip->open($file, ZipArchive::CREATE)) {
+       exit('failed');
+}
+
+$zip->addEmptyDir('foo');
+$zip->addEmptyDir(chr(0x82), ZipArchive::FL_ENC_CP437);
+$zip->addEmptyDir('è', ZipArchive::FL_ENC_UTF_8);
+
+$zip->addFromString('bar', __FILE__);
+$zip->addFromString(chr(0x91), __FILE__, ZipArchive::FL_ENC_CP437);
+$zip->addFromString('€', __FILE__, ZipArchive::FL_ENC_UTF_8);
+
+if ($zip->status == ZIPARCHIVE::ER_OK) {
+       dump_entries_name($zip);
+       $zip->close();
+} else {
+       echo "failed\n";
+}
+?>
+--CLEAN--
+<?php
+$dirname = __DIR__ . '/oo_add_encoding_dir/';
+unlink($dirname . 'tmp.zip');
+rmdir($dirname);
+?>
+--EXPECTF--
+0 foo/
+1 é/
+2 è/
+3 bar
+4 æ
+5 €
diff --git a/ext/zip/tests/oo_add_from_string.phpt b/ext/zip/tests/oo_add_from_string.phpt
new file mode 100644 (file)
index 0000000..6ddc6ff
--- /dev/null
@@ -0,0 +1,58 @@
+--TEST--
+ziparchive::addFromString and FL_OVERWRITE
+--SKIPIF--
+<?php
+/* $Id$ */
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+
+include __DIR__ . '/utils.inc';
+$dirname = __DIR__ . '/oo_add_from_string_dir/';
+$file = $dirname . 'tmp.zip';
+
+@mkdir($dirname);
+copy(__DIR__ . '/test.zip', $file);
+
+$zip = new ZipArchive();
+if (!$zip->open($file)) {
+        exit('failed');
+}
+
+// New file
+var_dump($zip->addFromString('bar', __FILE__));
+var_dump($zip->status == ZipArchive::ER_OK);
+// Fails to add existing file
+var_dump($zip->addFromString('entry1.txt', __FILE__, 0));
+var_dump($zip->status == ZipArchive::ER_EXISTS);
+// Overwrite
+var_dump($zip->addFromString('entry1.txt', __FILE__, ZipArchive::FL_OVERWRITE));
+var_dump($zip->status == ZipArchive::ER_OK);
+
+if ($zip->status == ZipArchive::ER_OK) {
+       dump_entries_name($zip);
+       $zip->close();
+} else {
+       echo "failed\n";
+}
+?>
+Done
+--CLEAN--
+<?php
+$dirname = __DIR__ . '/oo_add_from_string_dir/';
+unlink($dirname . 'tmp.zip');
+rmdir($dirname);
+?>
+--EXPECTF--
+bool(true)
+bool(true)
+bool(false)
+bool(true)
+bool(true)
+bool(true)
+0 bar
+1 foobar/
+2 foobar/baz
+3 entry1.txt
+Done
index b20d4ab07a656302a4c08f10dcaa0ec74db2f8a5..a648cd7c054327e895bd8d594aa22977b88698a1 100644 (file)
@@ -26,7 +26,18 @@ if (!$zip->open($file)) {
 }
 $options = array('add_path' => 'baz/', 'remove_all_path' => TRUE);
 if (!$zip->addGlob($dirname . '*.{txt,baz}', GLOB_BRACE, $options)) {
-        echo "failed1\n";
+       echo "failed 1\n";
+}
+if (!$zip->addGlob($dirname . '*.{txt,baz}', GLOB_BRACE, $options)) {
+       echo "failed 2\n";
+}
+$options['flags'] = 0; // clean FL_OVERWRITE
+if (!$zip->addGlob($dirname . '*.{txt,baz}', GLOB_BRACE, $options)) {
+       var_dump($zip->getStatusString());
+}
+$options['flags'] = ZipArchive::FL_OVERWRITE;
+if (!$zip->addGlob($dirname . '*.{txt,baz}', GLOB_BRACE, $options)) {
+       echo "failed 3\n";
 }
 if ($zip->status == ZIPARCHIVE::ER_OK) {
         if (!verify_entries($zip, [
@@ -43,7 +54,7 @@ if ($zip->status == ZIPARCHIVE::ER_OK) {
         }
         $zip->close();
 } else {
-        echo "failed3\n";
+        echo "failed 4\n";
 }
 ?>
 --CLEAN--
@@ -55,4 +66,5 @@ unlink($dirname . 'bar.baz');
 rmdir($dirname);
 ?>
 --EXPECT--
+string(19) "File already exists"
 OK
index 19453bee491546e6c2d4308ede843acb5a356284..227a89bb178f9f6793dd28ff6a35e1f0e3577962 100644 (file)
@@ -27,8 +27,17 @@ if (!$zip->open($file)) {
 $dir = realpath($dirname);
 $options = array('add_path' => 'baz', 'remove_path' => $dir);
 if (!$zip->addPattern('/\.txt$/', $dir, $options)) {
-        echo "failed\n";
+       echo "failed 1\n";
 }
+$options['flags'] = 0; // clean FL_OVERWRITE
+if (!$zip->addPattern('/\.txt$/', $dir, $options)) {
+       var_dump($zip->getStatusString());
+}
+$options['flags'] = ZipArchive::FL_OVERWRITE;
+if (!$zip->addPattern('/\.txt$/', $dir, $options)) {
+       echo "failed 2\n";
+}
+
 if ($zip->status == ZIPARCHIVE::ER_OK) {
         if (!verify_entries($zip, [
             "bar",
@@ -56,4 +65,5 @@ unlink($dirname . 'bar.txt');
 rmdir($dirname);
 ?>
 --EXPECT--
+string(19) "File already exists"
 OK
diff --git a/ext/zip/tests/oo_replacefile.phpt b/ext/zip/tests/oo_replacefile.phpt
new file mode 100644 (file)
index 0000000..486928c
--- /dev/null
@@ -0,0 +1,54 @@
+--TEST--
+ziparchive::replaceFile() function
+--SKIPIF--
+<?php
+if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+
+$dirname = __DIR__ . '/';
+include $dirname . 'utils.inc';
+$file = $dirname . 'oo_replacefile.zip';
+
+copy($dirname . 'test.zip', $file);
+
+$zip = new ZipArchive;
+if (!$zip->open($file)) {
+    exit('open failed');
+}
+if ($zip->replaceFile($dirname . 'utils.inc', 5)) {
+    echo "replace 5 succeed\n";
+}
+if (!$zip->replaceFile($dirname . 'utils.inc', 0)) {
+    echo "replace 0 failed\n";
+}
+if (!$zip->replaceFile($dirname . 'utils.inc', 2, 12, 42)) {
+    echo "replace 2 failed\n";
+}
+if ($zip->status == ZIPARCHIVE::ER_OK) {
+    if (!verify_entries($zip, [
+        "bar",
+        "foobar/",
+        "foobar/baz",
+        "entry1.txt",
+    ])) {
+        echo "verify failed\n";
+    } else {
+        echo "OK\n";
+    }
+    $zip->close();
+} else {
+    echo "failed\n";
+}
+if (!$zip->open($file)) {
+       exit('re-open failed');
+}
+var_dump(strlen($zip->getFromName('bar')) == filesize($dirname . 'utils.inc'));
+var_dump(strlen($zip->getFromName('foobar/baz')) == 42);
+@unlink($file);
+?>
+--EXPECT--
+OK
+bool(true)
+bool(true)
index 6d5049e558fe1214e1aefeff8d2b4fc3cf00c815..93158b05b2602aeb6bc5e85e87999a217752972a 100644 (file)
@@ -1,4 +1,11 @@
 <?php
+function dump_entries_name($z) {
+       for($i=0; $i<$z->numFiles; $i++) {
+           $sb = $z->statIndex($i);
+           echo $i . ' ' . $sb['name'] . "\n";
+       }
+}
+
 function verify_entries($zip, $entries = []) {
     $verified = true;
     $found    = [];