@@ -659,7 +659,6 @@ static bool php_zipobj_close(ze_zip_object *obj, zend_string **out_str) /* {{{ *
659659 if (intern ) {
660660 archive -> close = true;
661661 int err = zip_close (intern );
662- archive -> close = false;
663662 if (err ) {
664663 php_error_docref (NULL , E_WARNING , "%s" , zip_strerror (intern ));
665664 /* Save error for property reader */
@@ -698,6 +697,7 @@ static bool php_zipobj_close(ze_zip_object *obj, zend_string **out_str) /* {{{ *
698697
699698 if (archive ) {
700699 archive -> za = NULL ;
700+ archive -> close = false;
701701 bailout = archive -> bailout_callback ;
702702 archive -> bailout_callback = false;
703703 obj -> archive = NULL ;
@@ -1128,6 +1128,10 @@ static void php_zip_progress_callback_free(void *ptr)
11281128{
11291129 php_zip_archive * archive = ptr ;
11301130
1131+ if (UNEXPECTED (!EG (active ) || archive -> bailout_callback )) {
1132+ return ;
1133+ }
1134+
11311135 if (ZEND_FCC_INITIALIZED (archive -> progress_callback )) {
11321136 zend_fcc_dtor (& archive -> progress_callback );
11331137 }
@@ -1139,6 +1143,10 @@ static void php_zip_cancel_callback_free(void *ptr)
11391143{
11401144 php_zip_archive * archive = ptr ;
11411145
1146+ if (UNEXPECTED (!EG (active ) || archive -> bailout_callback )) {
1147+ return ;
1148+ }
1149+
11421150 if (ZEND_FCC_INITIALIZED (archive -> cancel_callback )) {
11431151 zend_fcc_dtor (& archive -> cancel_callback );
11441152 }
@@ -1169,7 +1177,12 @@ bool php_zip_archive_release(php_zip_archive *archive)
11691177 }
11701178
11711179 if (archive -> za ) {
1172- if (zip_close (archive -> za ) != 0 ) {
1180+ /* Guard against a re-entrant close() or open() from a progress/cancel
1181+ * callback fired during zip_close(), which would run a nested zip_close()
1182+ * on the same archive (see php_zipobj_close()). */
1183+ archive -> close = true;
1184+ int err = zip_close (archive -> za );
1185+ if (err != 0 ) {
11731186 if (!archive -> bailout_callback ) {
11741187 php_error_docref (NULL , E_WARNING , "Cannot destroy the zip context: %s" , zip_strerror (archive -> za ));
11751188 }
@@ -3131,6 +3144,10 @@ static void php_zip_get_stream(INTERNAL_FUNCTION_PARAMETERS, int type, bool acce
31313144
31323145 ZIP_FROM_OBJECT (intern , self );
31333146
3147+ if (php_zipobj_closing (Z_ZIP_P (self ))) {
3148+ RETURN_THROWS ();
3149+ }
3150+
31343151 if (type ) {
31353152 PHP_ZIP_STAT_PATH (intern , ZSTR_VAL (filename ), ZSTR_LEN (filename ), flags , sb );
31363153 } else {
0 commit comments