Skip to content
Open
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
23 changes: 23 additions & 0 deletions ext/standard/tests/streams/gh25148.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
--TEST--
GH-25148 (Blocking socket fread() reports timed_out on Windows after returning buffered data)
--FILE--
<?php
$domain = PHP_OS_FAMILY === 'Windows' ? STREAM_PF_INET : STREAM_PF_UNIX;
[$client, $server] = stream_socket_pair($domain, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);

fwrite($server, str_repeat('x', 1500));
usleep(100000);

// takes all 1500 bytes into the read buffer and returns the first 1024
var_dump(strlen(fread($client, 1024)));
var_dump(stream_get_meta_data($client)['timed_out']);

// returns the other 476 from the read buffer without waiting for more
var_dump(strlen(fread($client, 1024)));
var_dump(stream_get_meta_data($client)['timed_out']);
?>
--EXPECT--
int(1024)
bool(false)
int(476)
bool(false)
8 changes: 6 additions & 2 deletions main/streams/xp_socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
}
Expand Down
Loading