Skip to content

streams: Re-add support for arbitrary metadata for stream notifier functions #19158

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
5 changes: 5 additions & 0 deletions UPGRADING.INTERNALS
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
20 changes: 9 additions & 11 deletions ext/standard/streamsfuncs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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))) {
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion main/streams/php_stream_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
};
Expand Down