Skip to content

Commit 6b3f302

Browse files
authored
streams: Re-add support for arbitrary metadata for stream notifier functions (#19158)
Support for attaching arbitrary metadata for consumption by stream notifier functions got broken in #19024 when the previous `zval ptr` got changed to `zend_fcall_info_cache *fcc`, making the data specific to the `user_space_stream_notifier`. Fix this by changing the field to `void *ptr`, avoiding the indirection through a `zval`, but preserving the ability to store arbitrary data. If necessary to support different types than `IS_PTR`, extensions can heap-allocate a `zval` to store within `->ptr` as a minimal change to keep compatibility with PHP 8.4 or lower.
1 parent 78d96e9 commit 6b3f302

File tree

4 files changed

+16
-12
lines changed

4 files changed

+16
-12
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ PHP NEWS
44

55
- Core:
66
. Add clone-with support to the clone() function. (timwolla, edorian)
7+
. Fix support for non-userland stream notifiers. (timwolla)
78

89
- Curl:
910
. Add support for CURLINFO_CONN_ID in curl_getinfo() (thecaliskan)

UPGRADING.INTERNALS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ PHP 8.5 INTERNALS UPGRADE NOTES
2323
the user side when requiring libphp.so, by using dlmopen with LM_ID_NEWLM
2424
instead of dlopen.
2525
RTLD_DEEPBIND is still enabled when the Apache SAPI is in use.
26+
. The ptr field of the php_stream_notifier struct is now a void* instead
27+
of a zval. If the zval was used to store IS_PTR values only, the
28+
extra layer of indirection can be removed. In other cases a zval can
29+
be heap-allocated and stored in the pointer as a minimal change to keep
30+
compatibility.
2631

2732
- Zend
2833
. Added zend_safe_assign_to_variable_noref() function to safely assign

ext/standard/streamsfuncs.c

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -869,19 +869,17 @@ static void user_space_stream_notifier(php_stream_context *context, int notifyco
869869
ZVAL_LONG(&zvs[4], bytes_sofar);
870870
ZVAL_LONG(&zvs[5], bytes_max);
871871

872-
zend_call_known_fcc(context->notifier->fcc, NULL, 6, zvs, NULL);
872+
zend_call_known_fcc(context->notifier->ptr, NULL, 6, zvs, NULL);
873873
/* Free refcounted string parameter */
874874
zval_ptr_dtor_str(&zvs[2]);
875875
}
876876

877877
static void user_space_stream_notifier_dtor(php_stream_notifier *notifier)
878878
{
879-
ZEND_ASSERT(notifier);
880-
ZEND_ASSERT(notifier->fcc);
881-
ZEND_ASSERT(notifier->fcc->function_handler);
882-
zend_fcc_dtor(notifier->fcc);
883-
efree(notifier->fcc);
884-
notifier->fcc = NULL;
879+
zend_fcall_info_cache *fcc = notifier->ptr;
880+
zend_fcc_dtor(fcc);
881+
efree(notifier->ptr);
882+
notifier->ptr = NULL;
885883
}
886884

887885
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 *
931929

932930
context->notifier = php_stream_notification_alloc();
933931
context->notifier->func = user_space_stream_notifier;
934-
context->notifier->fcc = fcc;
932+
context->notifier->ptr = fcc;
935933
context->notifier->dtor = user_space_stream_notifier_dtor;
936934
}
937935
if (NULL != (tmp = zend_hash_str_find(params, "options", sizeof("options")-1))) {
@@ -1128,10 +1126,10 @@ PHP_FUNCTION(stream_context_get_params)
11281126
}
11291127

11301128
array_init(return_value);
1131-
if (context->notifier && context->notifier->fcc) {
1132-
ZEND_ASSERT(context->notifier->func == user_space_stream_notifier);
1129+
if (context->notifier && context->notifier->func == user_space_stream_notifier) {
1130+
zend_fcall_info_cache *fcc = context->notifier->ptr;
11331131
zval fn;
1134-
zend_get_callable_zval_from_fcc(context->notifier->fcc, &fn);
1132+
zend_get_callable_zval_from_fcc(fcc, &fn);
11351133
add_assoc_zval_ex(return_value, ZEND_STRL("notification"), &fn);
11361134
}
11371135
Z_TRY_ADDREF(context->options);

main/streams/php_stream_context.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ typedef struct _php_stream_notifier php_stream_notifier;
4444
struct _php_stream_notifier {
4545
php_stream_notification_func func;
4646
void (*dtor)(php_stream_notifier *notifier);
47-
zend_fcall_info_cache *fcc;
47+
void *ptr;
4848
int mask;
4949
size_t progress, progress_max; /* position for progress notification */
5050
};

0 commit comments

Comments
 (0)