From 93a68d4003257d8819875541599b587c338c1c45 Mon Sep 17 00:00:00 2001 From: Jack Worman Date: Mon, 2 Nov 2026 07:56:24 -0600 Subject: [PATCH] Fix GH-25148: Blocking socket fread() reports timed_out on Windows after returning buffered data Since the fix for bug #51056, a blocking read that already has data buffered only checks for more without waiting. Windows has no MSG_DONTWAIT, so it checks with a zero-timeout poll, and when that poll found nothing, timeout_event was set and stream_get_meta_data() reported timed_out. --- ext/standard/tests/streams/gh25148.phpt | 23 +++++++++++++++++++++++ main/streams/xp_socket.c | 8 ++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 ext/standard/tests/streams/gh25148.phpt diff --git a/ext/standard/tests/streams/gh25148.phpt b/ext/standard/tests/streams/gh25148.phpt new file mode 100644 index 000000000000..810fead961e9 --- /dev/null +++ b/ext/standard/tests/streams/gh25148.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-25148 (Blocking socket fread() reports timed_out on Windows after returning buffered data) +--FILE-- + +--EXPECT-- +int(1024) +bool(false) +int(476) +bool(false) diff --git a/main/streams/xp_socket.c b/main/streams/xp_socket.c index 8d577de6e76d..2294dff39e9c 100644 --- a/main/streams/xp_socket.c +++ b/main/streams/xp_socket.c @@ -182,8 +182,12 @@ static ssize_t php_sockop_read(php_stream *stream, char *buf, size_t count) if (!dont_wait || MSG_DONTWAIT == 0) { php_sock_stream_wait_for_data(stream, sock, has_buffered_data); if (sock->timeout_event) { - /* It is ok to timeout if there is any data buffered so return 0, otherwise -1. */ - return has_buffered_data ? 0 : -1; + if (has_buffered_data) { + /* The poll did not wait as there is data buffered, so this is not a timeout. */ + sock->timeout_event = 0; + return 0; + } + return -1; } } }