From f9752256dae3496707afdaed4d568d00e2def4d5 Mon Sep 17 00:00:00 2001 From: Jakub Zelenka Date: Thu, 20 Nov 2025 17:18:35 +0100 Subject: [PATCH] Allow filtered streams to be casted as fd for select This removes the artificial limitation that is not necessary. The fact that some streams can have some data buffered is not a problem because the similar situation is already present for OpenSSL streams where OpenSSL can internally buffer data for the unprocessed part of the record. --- .../stream_select_filtered_base64_basic.phpt | 32 ++++++++++ ...tream_select_filtered_base64_buffered.phpt | 59 +++++++++++++++++++ main/streams/cast.c | 2 +- 3 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 ext/standard/tests/streams/stream_select_filtered_base64_basic.phpt create mode 100644 ext/standard/tests/streams/stream_select_filtered_base64_buffered.phpt diff --git a/ext/standard/tests/streams/stream_select_filtered_base64_basic.phpt b/ext/standard/tests/streams/stream_select_filtered_base64_basic.phpt new file mode 100644 index 0000000000000..f7ec2b6a4b542 --- /dev/null +++ b/ext/standard/tests/streams/stream_select_filtered_base64_basic.phpt @@ -0,0 +1,32 @@ +--TEST-- +stream_select() base64-decode filter basic usage +--FILE-- + 0) { + echo fread($file, 1024) . "\n"; + } +} else { + echo "stream_select failed\n"; +} + +fclose($file); +?> +--EXPECT-- +stream_select succeeded +Hello World diff --git a/ext/standard/tests/streams/stream_select_filtered_base64_buffered.phpt b/ext/standard/tests/streams/stream_select_filtered_base64_buffered.phpt new file mode 100644 index 0000000000000..4d11bf718a1bd --- /dev/null +++ b/ext/standard/tests/streams/stream_select_filtered_base64_buffered.phpt @@ -0,0 +1,59 @@ +--TEST-- +stream_select() base64-decode filter buffered data usage +--FILE-- + 0) { + $content = fread($read_pipe, 1024); + echo "Decoded content: " . $content . "\n"; +} + +fclose($read_pipe); +fclose($write_pipe); +?> +--EXPECT-- +Decoded content (before select): Hel +After incomplete data - select result: 0 +After incomplete data - readable streams: 0 +After complete data - select result: 1 +After complete data - readable streams: 1 +Decoded content: lo diff --git a/main/streams/cast.c b/main/streams/cast.c index 4b7183024571b..4dc8ddb5f6a30 100644 --- a/main/streams/cast.c +++ b/main/streams/cast.c @@ -297,7 +297,7 @@ PHPAPI zend_result _php_stream_cast(php_stream *stream, int castas, void **ret, } } - if (php_stream_is_filtered(stream)) { + if (php_stream_is_filtered(stream) && castas != PHP_STREAM_AS_FD_FOR_SELECT) { if (show_err) { php_error_docref(NULL, E_WARNING, "Cannot cast a filtered stream on this system"); }