Fix GH-18431: Registering ZIP progress callback twice doesn't work

Libzip already cleans up the previous callback, so when that means:
1. The callback zval being already copied over the previous one causes
   libzip to clean up the new callback object. This is the root cause.
2. Our own code to clean the old callback is redundant.

Closes GH-18432.
This commit is contained in:
Niels Dossche 2025-04-26 12:40:38 +02:00
parent a91d913901
commit b066ac0b23
No known key found for this signature in database
GPG key ID: B8A8AD166DF0E2E5
3 changed files with 28 additions and 8 deletions

4
NEWS
View file

@ -14,6 +14,10 @@ PHP NEWS
- Standard:
. Fixed bug GH-17403 (Potential deadlock when putenv fails). (nielsdos)
- Zip:
. Fixed bug GH-18431 (Registering ZIP progress callback twice doesn't work).
(nielsdos)
08 May 2025, PHP 8.3.21
- Core:

View file

@ -3048,14 +3048,11 @@ PHP_METHOD(ZipArchive, registerProgressCallback)
obj = Z_ZIP_P(self);
/* free if called twice */
_php_zip_progress_callback_free(obj);
/* register */
ZVAL_COPY(&obj->progress_callback, &fci.function_name);
if (zip_register_progress_callback_with_state(intern, rate, _php_zip_progress_callback, _php_zip_progress_callback_free, obj)) {
RETURN_FALSE;
}
ZVAL_COPY(&obj->progress_callback, &fci.function_name);
RETURN_TRUE;
}
@ -3093,14 +3090,11 @@ PHP_METHOD(ZipArchive, registerCancelCallback)
obj = Z_ZIP_P(self);
/* free if called twice */
_php_zip_cancel_callback_free(obj);
/* register */
ZVAL_COPY(&obj->cancel_callback, &fci.function_name);
if (zip_register_cancel_callback_with_state(intern, _php_zip_cancel_callback, _php_zip_cancel_callback_free, obj)) {
RETURN_FALSE;
}
ZVAL_COPY(&obj->cancel_callback, &fci.function_name);
RETURN_TRUE;
}

View file

@ -0,0 +1,22 @@
--TEST--
GH-18431 (Registering ZIP progress callback twice doesn't work)
--EXTENSIONS--
zip
--FILE--
<?php
$file = __DIR__ . '/gh18431.zip';
$callback = var_dump(...);
$zip = new ZipArchive;
$zip->open($file, ZIPARCHIVE::CREATE);
$zip->registerProgressCallback(0.5, $callback);
$zip->registerProgressCallback(0.5, $callback);
$zip->addFromString('foo', 'entry #1');
?>
--CLEAN--
<?php
$file = __DIR__ . '/gh18431.zip';
@unlink($file);
?>
--EXPECT--
float(0)
float(1)