diff --git a/NEWS b/NEWS index e317e0c234a3e..0ff1a5bbe0a75 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,7 @@ PHP NEWS - Core: . Add clone-with support to the clone() function. (timwolla, edorian) + . Fix support for non-userland stream notifiers. (timwolla) - Curl: . Add support for CURLINFO_CONN_ID in curl_getinfo() (thecaliskan) diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 7a14a4907ea62..0e0a0e94c9477 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -23,6 +23,11 @@ PHP 8.5 INTERNALS UPGRADE NOTES the user side when requiring libphp.so, by using dlmopen with LM_ID_NEWLM instead of dlopen. RTLD_DEEPBIND is still enabled when the Apache SAPI is in use. + . The ptr field of the php_stream_notifier struct is now a void* instead + of a zval. If the zval was used to store IS_PTR values only, the + extra layer of indirection can be removed. In other cases a zval can + be heap-allocated and stored in the pointer as a minimal change to keep + compatibility. - Zend . Added zend_safe_assign_to_variable_noref() function to safely assign diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c index 2e38965232c74..bf7cbc9fa4623 100644 --- a/ext/standard/streamsfuncs.c +++ b/ext/standard/streamsfuncs.c @@ -869,19 +869,17 @@ static void user_space_stream_notifier(php_stream_context *context, int notifyco ZVAL_LONG(&zvs[4], bytes_sofar); ZVAL_LONG(&zvs[5], bytes_max); - zend_call_known_fcc(context->notifier->fcc, NULL, 6, zvs, NULL); + zend_call_known_fcc(context->notifier->ptr, NULL, 6, zvs, NULL); /* Free refcounted string parameter */ zval_ptr_dtor_str(&zvs[2]); } static void user_space_stream_notifier_dtor(php_stream_notifier *notifier) { - ZEND_ASSERT(notifier); - ZEND_ASSERT(notifier->fcc); - ZEND_ASSERT(notifier->fcc->function_handler); - zend_fcc_dtor(notifier->fcc); - efree(notifier->fcc); - notifier->fcc = NULL; + zend_fcall_info_cache *fcc = notifier->ptr; + zend_fcc_dtor(fcc); + efree(notifier->ptr); + notifier->ptr = NULL; } static zend_result parse_context_options(php_stream_context *context, HashTable *options) @@ -931,7 +929,7 @@ static zend_result parse_context_params(php_stream_context *context, HashTable * context->notifier = php_stream_notification_alloc(); context->notifier->func = user_space_stream_notifier; - context->notifier->fcc = fcc; + context->notifier->ptr = fcc; context->notifier->dtor = user_space_stream_notifier_dtor; } if (NULL != (tmp = zend_hash_str_find(params, "options", sizeof("options")-1))) { @@ -1128,10 +1126,10 @@ PHP_FUNCTION(stream_context_get_params) } array_init(return_value); - if (context->notifier && context->notifier->fcc) { - ZEND_ASSERT(context->notifier->func == user_space_stream_notifier); + if (context->notifier && context->notifier->func == user_space_stream_notifier) { + zend_fcall_info_cache *fcc = context->notifier->ptr; zval fn; - zend_get_callable_zval_from_fcc(context->notifier->fcc, &fn); + zend_get_callable_zval_from_fcc(fcc, &fn); add_assoc_zval_ex(return_value, ZEND_STRL("notification"), &fn); } Z_TRY_ADDREF(context->options); diff --git a/main/streams/php_stream_context.h b/main/streams/php_stream_context.h index f61604c929d78..b983bbb10efe2 100644 --- a/main/streams/php_stream_context.h +++ b/main/streams/php_stream_context.h @@ -44,7 +44,7 @@ typedef struct _php_stream_notifier php_stream_notifier; struct _php_stream_notifier { php_stream_notification_func func; void (*dtor)(php_stream_notifier *notifier); - zend_fcall_info_cache *fcc; + void *ptr; int mask; size_t progress, progress_max; /* position for progress notification */ };