php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #70099 stream_select() reverts to previous behavior of not preserving keys after read
Submitted: 2015-07-19 08:18 UTC Modified: -
Votes:5
Avg. Score:4.6 ± 0.8
Reproduced:5 of 5 (100.0%)
Same Version:1 (20.0%)
Same OS:2 (40.0%)
From: chris dot ball at mailinator dot com Assigned:
Status: Open Package: Streams related
PHP Version: 5.6.11 OS: Windows
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2015-07-19 08:18 UTC] chris dot ball at mailinator dot com
Description:
------------
stream_select() should always preserve keys of input arrays.  It does so in the example for the first stream_select() call but then fails to do so in subsequent calls AFTER data has been read in.

Test script:
---------------
<?php
	$fp = fopen(__FILE__, "rb");
	stream_set_blocking($fp, 0);

	$readfp = array("__fp" => $fp);
	$writefp = NULL;
	$exceptfp = NULL;
	$timeout = NULL;
var_dump($readfp);
	$result = stream_select($readfp, $writefp, $exceptfp, $timeout);
var_dump($readfp);

	$data = fread($fp, 1024);

	$readfp = array("__fp" => $fp);
	$writefp = NULL;
	$exceptfp = NULL;
	$timeout = NULL;
var_dump($readfp);
	$result = stream_select($readfp, $writefp, $exceptfp, $timeout);
var_dump($readfp);
?>

Expected result:
----------------
array(1) {
  ["__fp"]=>
  resource(5) of type (stream)
}
array(1) {
  ["__fp"]=>
  resource(5) of type (stream)
}
array(1) {
  ["__fp"]=>
  resource(5) of type (stream)
}
array(1) {
  ["__fp"]=>
  resource(5) of type (stream)
}

Actual result:
--------------
array(1) {
  ["__fp"]=>
  resource(5) of type (stream)
}
array(1) {
  ["__fp"]=>
  resource(5) of type (stream)
}
array(1) {
  ["__fp"]=>
  resource(5) of type (stream)
}
array(1) {
  [0]=>
  resource(5) of type (stream)
}

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-03-20 10:46 UTC] paul dot smith at deepseaplc dot com
I'm seeing this same problem except it works fine for up to 2 weeks before reverting. As you can imagine I've spent months trying to get to the bottom of it.

Right now I'm passing in an array of 4 resources to read, an empty array to write, null to except and 60 to tv_sec.

The stream resources are:-
STDIN
STDERR
A listener created with stream_socket_server()
A socket accepted by stream_socket_accept() (from the listener)

stream_select() returns 1 and modifies the read array to contain a single stream (the last one that was passed to it). The array comes back zero based so my code doesn't perform a read on it and gets stuck in an endless loop.

If I open another connection from external software into the script, it hangs at "connecting" for a few minutes before erroring. It looks like the software can see the script is listening but the connection is never accepted. I'd expect stream_select() to leave 2 elements in the array (the stream I've still not read from and now the listener stream). Strangely though I still only get the 1 stream that was there before and stream_select() still returns 1.

I think something is happening that zeros the array keys meaning only one element can be returned. Even if I were to modify my code so it doesn't rely on indexes being preserved I still don't think it would work properly due to this.

I'm running PHP 7.2.1 on CentOS 7.1.1503. The problem has only been noticed on production servers. So far neither of the dev servers have got into this state. Both accept SSL connections but they tend not to be used on dev. Production also has a lot more connections. Restarting the PHP script fixes the problem immediately for a few weeks.

Please let me know if you need any more information or would like me to test any code.
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Sun Nov 17 12:01:34 2019 UTC