diff --git a/UPGRADING b/UPGRADING index c387c7c3a7f..2f3e868f191 100644 --- a/UPGRADING +++ b/UPGRADING @@ -314,6 +314,7 @@ PHP 8.3 UPGRADE NOTES . ZipArchive::AFL_IS_TORRENTZIP (libzip >= 1.10) . ZipArchive::AFL_WANT_TORRENTZIP (libzip >= 1.10) . ZipArchive::AFL_CREATE_OR_KEEP_FILE_FOR_EMPTY_ARCHIVE (libzip >= 1.10) + . ZipArchive::FL_OPEN_FILE_NOW ======================================== 11. Changes to INI File Handling diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index f970bd8a77e..4c008a1befa 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -299,7 +299,17 @@ static int php_zip_add_file(ze_zip_object *obj, const char *filename, size_t fil return -1; } - zs = zip_source_file(obj->za, resolved_path, offset_start, offset_len); + if (flags & ZIP_FL_OPEN_FILE_NOW) { + FILE *fd; + fd = fopen(resolved_path, "rb"); + if (!fd) { + return -1; + } + flags ^= ZIP_FL_OPEN_FILE_NOW; + zs = zip_source_filep(obj->za, fd, offset_start, offset_len); + } else { + zs = zip_source_file(obj->za, resolved_path, offset_start, offset_len); + } if (!zs) { return -1; } diff --git a/ext/zip/php_zip.h b/ext/zip/php_zip.h index 48c1562bdfb..f7c7a739d36 100644 --- a/ext/zip/php_zip.h +++ b/ext/zip/php_zip.h @@ -31,7 +31,10 @@ extern zend_module_entry zip_module_entry; #define ZIP_OVERWRITE ZIP_TRUNCATE #endif -#define PHP_ZIP_VERSION "1.22.0" +/* Additionnal flags not from libzip */ +#define ZIP_FL_OPEN_FILE_NOW (1u<<30) + +#define PHP_ZIP_VERSION "1.22.1" #ifdef HAVE_LIBZIP_VERSION #define LIBZIP_VERSION_STR zip_libzip_version() diff --git a/ext/zip/php_zip.stub.php b/ext/zip/php_zip.stub.php index 1ea4945876d..b8807a4d56c 100644 --- a/ext/zip/php_zip.stub.php +++ b/ext/zip/php_zip.stub.php @@ -172,6 +172,13 @@ class ZipArchive implements Countable */ public const FL_ENC_CP437 = UNKNOWN; + /** + * Additionnal flags not from libzip + * @var int + * @cvalue ZIP_FL_OPEN_FILE_NOW + */ + public const FL_OPEN_FILE_NOW = UNKNOWN; + /** * @var int * @cvalue ZIP_CM_DEFAULT diff --git a/ext/zip/php_zip_arginfo.h b/ext/zip/php_zip_arginfo.h index ad8ceb43612..e0198435e0f 100644 --- a/ext/zip/php_zip_arginfo.h +++ b/ext/zip/php_zip_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 37a7b865d0fe62419f677382fa713a800d48da5e */ + * Stub hash: fb9b6fa0a8e3da62a85e13b455573ee876ea2d61 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_open, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) @@ -626,6 +626,12 @@ static zend_class_entry *register_class_ZipArchive(zend_class_entry *class_entry zend_declare_class_constant_ex(class_entry, const_FL_ENC_CP437_name, &const_FL_ENC_CP437_value, ZEND_ACC_PUBLIC, NULL); zend_string_release(const_FL_ENC_CP437_name); + zval const_FL_OPEN_FILE_NOW_value; + ZVAL_LONG(&const_FL_OPEN_FILE_NOW_value, ZIP_FL_OPEN_FILE_NOW); + zend_string *const_FL_OPEN_FILE_NOW_name = zend_string_init_interned("FL_OPEN_FILE_NOW", sizeof("FL_OPEN_FILE_NOW") - 1, 1); + zend_declare_class_constant_ex(class_entry, const_FL_OPEN_FILE_NOW_name, &const_FL_OPEN_FILE_NOW_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release(const_FL_OPEN_FILE_NOW_name); + zval const_CM_DEFAULT_value; ZVAL_LONG(&const_CM_DEFAULT_value, ZIP_CM_DEFAULT); zend_string *const_CM_DEFAULT_name = zend_string_init_interned("CM_DEFAULT", sizeof("CM_DEFAULT") - 1, 1); diff --git a/ext/zip/tests/oo_addfile.phpt b/ext/zip/tests/oo_addfile.phpt index f85d9484a8d..00f560e032e 100644 --- a/ext/zip/tests/oo_addfile.phpt +++ b/ext/zip/tests/oo_addfile.phpt @@ -24,6 +24,19 @@ if (!$zip->addFile($dirname . 'utils.inc', 'mini.txt', 12, 34)) { echo "failed\n"; } var_dump($zip->lastId); +if (!$zip->addFile($dirname . 'utils.inc', 'other.txt', 0, 0, ZipArchive::FL_OPEN_FILE_NOW)) { + echo "failed\n"; +} +var_dump($zip->lastId); +$del = $dirname . '__tmp_oo_addfile.txt'; +file_put_contents($del, 'foo'); +if (!$zip->addFile($del, 'deleted.txt', 0, 0, ZipArchive::FL_OPEN_FILE_NOW)) { + echo "failed\n"; +} +if (substr(PHP_OS, 0, 3) != 'WIN') { + unlink($del); +} +var_dump($zip->lastId); if ($zip->status == ZIPARCHIVE::ER_OK) { if (!verify_entries($zip, [ "bar", @@ -31,7 +44,9 @@ if ($zip->status == ZIPARCHIVE::ER_OK) { "foobar/baz", "entry1.txt", "test.php", - "mini.txt" + "mini.txt", + "other.txt", + "deleted.txt" ])) { echo "failed\n"; } else { @@ -46,12 +61,19 @@ if (!$zip->open($file)) { } var_dump(strlen($zip->getFromName('test.php')) == filesize($dirname . 'utils.inc')); var_dump(strlen($zip->getFromName('mini.txt')) == 34); +var_dump(strlen($zip->getFromName('other.txt')) == filesize($dirname . 'utils.inc')); +var_dump($zip->getFromName('deleted.txt') === "foo"); @unlink($file); +@unlink($del); ?> --EXPECT-- int(-1) int(4) int(5) +int(6) +int(7) OK bool(true) bool(true) +bool(true) +bool(true)