diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index 1c2e430485884..316c22aab5f06 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -3073,10 +3073,12 @@ static int php_zip_cancel_callback(zip_t *arch, void *ptr) return -1; } bool failed = false; - zend_long retval = zval_try_get_long(&cb_retval, &failed); + zval *cb_retval_ptr = &cb_retval; + ZVAL_DEREF(cb_retval_ptr); + zend_long retval = zval_try_get_long(cb_retval_ptr, &failed); if (failed) { zend_type_error("Return value of callback provided to ZipArchive::registerCancelCallback()" - " must be of type int, %s returned", zend_zval_value_name(&cb_retval)); + " must be of type int, %s returned", zend_zval_value_name(cb_retval_ptr)); zval_ptr_dtor(&cb_retval); return -1; } diff --git a/ext/zip/tests/gh18439.phpt b/ext/zip/tests/gh18439.phpt new file mode 100644 index 0000000000000..5235bd99e47bd --- /dev/null +++ b/ext/zip/tests/gh18439.phpt @@ -0,0 +1,27 @@ +--TEST-- +GH-18439 (Reference handling in cancel callback) +--EXTENSIONS-- +zip +--FILE-- +open($file, ZIPARCHIVE::CREATE); +$zip->registerCancelCallback(cb(...)); +$zip->addFromString('test', 'test'); +echo "Done\n"; + +?> +--CLEAN-- + +--EXPECT-- +Done