ext/zip: Convert progress_callback to FCC

This commit is contained in:
Gina Peter Banyard 2025-01-10 12:56:36 +00:00
parent 08784ed58a
commit 76a5804560
2 changed files with 20 additions and 20 deletions

View file

@ -1019,13 +1019,12 @@ static HashTable *php_zip_get_properties(zend_object *object)/* {{{ */
/* }}} */ /* }}} */
#ifdef HAVE_PROGRESS_CALLBACK #ifdef HAVE_PROGRESS_CALLBACK
static void _php_zip_progress_callback_free(void *ptr) static void php_zip_progress_callback_free(void *ptr)
{ {
ze_zip_object *obj = ptr; ze_zip_object *obj = ptr;
if (!Z_ISUNDEF(obj->progress_callback)) { if (ZEND_FCC_INITIALIZED(obj->progress_callback)) {
zval_ptr_dtor(&obj->progress_callback); zend_fcc_dtor(&obj->progress_callback);
ZVAL_UNDEF(&obj->progress_callback);
} }
} }
#endif #endif
@ -1066,7 +1065,7 @@ static void php_zip_object_free_storage(zend_object *object) /* {{{ */
#ifdef HAVE_PROGRESS_CALLBACK #ifdef HAVE_PROGRESS_CALLBACK
/* if not properly called by libzip */ /* if not properly called by libzip */
_php_zip_progress_callback_free(intern); php_zip_progress_callback_free(intern);
#endif #endif
#ifdef HAVE_CANCEL_CALLBACK #ifdef HAVE_CANCEL_CALLBACK
@ -3019,42 +3018,43 @@ PHP_METHOD(ZipArchive, getStream)
} }
#ifdef HAVE_PROGRESS_CALLBACK #ifdef HAVE_PROGRESS_CALLBACK
static void _php_zip_progress_callback(zip_t *arch, double state, void *ptr) static void php_zip_progress_callback(zip_t *arch, double state, void *ptr)
{ {
zval cb_args[1]; zval cb_args[1];
zval cb_retval;
ze_zip_object *obj = ptr; ze_zip_object *obj = ptr;
ZVAL_DOUBLE(&cb_args[0], state); ZVAL_DOUBLE(&cb_args[0], state);
if (call_user_function(EG(function_table), NULL, &obj->progress_callback, &cb_retval, 1, cb_args) == SUCCESS && !Z_ISUNDEF(cb_retval)) { zend_call_known_fcc(&obj->progress_callback, NULL, 1, cb_args, NULL);
zval_ptr_dtor(&cb_retval);
}
} }
/* {{{ register a progression callback: void callback(double state); */ /* {{{ register a progression callback: void callback(double state); */
PHP_METHOD(ZipArchive, registerProgressCallback) PHP_METHOD(ZipArchive, registerProgressCallback)
{ {
struct zip *intern; struct zip *intern;
zval *self = ZEND_THIS;
double rate; double rate;
zend_fcall_info fci; zend_fcall_info dummy_fci;
zend_fcall_info_cache fcc; zend_fcall_info_cache fcc;
ze_zip_object *obj; ze_zip_object *obj;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "df", &rate, &fci, &fcc) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "dF", &rate, &dummy_fci, &fcc) == FAILURE) {
RETURN_THROWS(); RETURN_THROWS();
} }
ZIP_FROM_OBJECT(intern, self); /* Inline ZIP_FROM_OBJECT(intern, self); */
obj = Z_ZIP_P(ZEND_THIS);
obj = Z_ZIP_P(self); intern = obj->za;
if (!intern) { \
zend_value_error("Invalid or uninitialized Zip object");
zend_release_fcall_info_cache(&fcc);
RETURN_THROWS();
}
/* free if called twice */ /* free if called twice */
_php_zip_progress_callback_free(obj); php_zip_progress_callback_free(obj);
/* register */ /* register */
ZVAL_COPY(&obj->progress_callback, &fci.function_name); zend_fcc_dup(&obj->progress_callback, &fcc);
if (zip_register_progress_callback_with_state(intern, rate, _php_zip_progress_callback, _php_zip_progress_callback_free, obj)) { if (zip_register_progress_callback_with_state(intern, rate, php_zip_progress_callback, php_zip_progress_callback_free, obj)) {
RETURN_FALSE; RETURN_FALSE;
} }

View file

@ -77,7 +77,7 @@ typedef struct _ze_zip_object {
int err_zip; int err_zip;
int err_sys; int err_sys;
#ifdef HAVE_PROGRESS_CALLBACK #ifdef HAVE_PROGRESS_CALLBACK
zval progress_callback; zend_fcall_info_cache progress_callback;
#endif #endif
#ifdef HAVE_CANCEL_CALLBACK #ifdef HAVE_CANCEL_CALLBACK
zval cancel_callback; zval cancel_callback;