diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index 552d3a7571de5..66f651e46e384 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -1832,6 +1832,11 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /* } #ifdef HAVE_ENCRYPTION if (opts.enc_method >= 0) { + if (UNEXPECTED(zip_file_set_encryption(ze_obj->za, ze_obj->last_id, ZIP_EM_NONE, NULL) < 0)) { + zend_array_destroy(Z_ARR_P(return_value)); + php_error_docref(NULL, E_WARNING, "password reset failed"); + RETURN_FALSE; + } if (zip_file_set_encryption(ze_obj->za, ze_obj->last_id, opts.enc_method, opts.enc_password)) { zend_array_destroy(Z_ARR_P(return_value)); RETURN_FALSE; diff --git a/ext/zip/tests/oo_addglob_leak.phpt b/ext/zip/tests/oo_addglob_leak.phpt new file mode 100644 index 0000000000000..9040c5565f842 --- /dev/null +++ b/ext/zip/tests/oo_addglob_leak.phpt @@ -0,0 +1,51 @@ +--TEST-- +ZipArchive::addGlob() method leaking after several calls when encryption is set. +--EXTENSIONS-- +zip +--SKIPIF-- + +--FILE-- +open($file, ZipArchive::CREATE | ZipArchive::OVERWRITE)) { + exit('failed'); +} + +$options = [ + 'remove_all_path' => true, + 'comp_method' => ZipArchive::CM_STORE, + 'comp_flags' => 5, + 'enc_method' => ZipArchive::EM_AES_256, + 'enc_password' => 'secret', +]; +var_dump($zip->addGlob($dirname . 'bar.*', GLOB_BRACE, $options)); +var_dump($zip->addGlob($dirname . 'bar.*', GLOB_BRACE, $options)); +?> +--CLEAN-- + +--EXPECTF-- +array(1) { + [0]=> + string(%d) "%s" +} +array(1) { + [0]=> + string(%d) "%s" +}