mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Merge branch 'PHP-8.2'
* PHP-8.2: [ci skip] NEWS [ci skip] NEWS [ci skip] NEWS Return immediately when FD_SETSIZE is exceeded (#9602)
This commit is contained in:
commit
5b6f9df51a
8 changed files with 185 additions and 6 deletions
71
ext/mysqli/tests/gh9590.phpt
Normal file
71
ext/mysqli/tests/gh9590.phpt
Normal file
|
@ -0,0 +1,71 @@
|
|||
--TEST--
|
||||
Bug GH-9602 (stream_select does not abort upon exception or empty valid fd set)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once('skipif.inc');
|
||||
require_once('connect.inc');
|
||||
require_once('skipifconnectfailure.inc');
|
||||
|
||||
if (!$IS_MYSQLND)
|
||||
die("skip mysqlnd only feature, compile PHP using --with-mysqli=mysqlnd");
|
||||
|
||||
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
|
||||
die("skip cannot connect");
|
||||
|
||||
if (mysqli_get_server_version($link) < 50012)
|
||||
die("skip Test needs SQL function SLEEP() available as of MySQL 5.0.12");
|
||||
|
||||
if (!function_exists('posix_setrlimit') || !posix_setrlimit(POSIX_RLIMIT_NOFILE, 2048, -1))
|
||||
die('skip Failed to set POSIX_RLIMIT_NOFILE');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
posix_setrlimit(POSIX_RLIMIT_NOFILE, 2048, -1);
|
||||
|
||||
$fds = [];
|
||||
for ($i = 0; $i < 1023; $i++) {
|
||||
$fds[] = @fopen(__DIR__ . "/GH-9590-tmpfile.$i", 'w');
|
||||
}
|
||||
|
||||
require_once('connect.inc');
|
||||
|
||||
function get_connection() {
|
||||
global $host, $user, $passwd, $db, $port, $socket;
|
||||
|
||||
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
|
||||
printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
|
||||
return $link;
|
||||
}
|
||||
|
||||
|
||||
$mysqli1 = get_connection();
|
||||
$mysqli2 = get_connection();
|
||||
|
||||
var_dump(mysqli_query($mysqli1, "SELECT SLEEP(0.10)", MYSQLI_ASYNC | MYSQLI_USE_RESULT));
|
||||
var_dump(mysqli_query($mysqli2, "SELECT SLEEP(0.20)", MYSQLI_ASYNC | MYSQLI_USE_RESULT));
|
||||
|
||||
$links = $errors = $reject = array($mysqli1, $mysqli2);
|
||||
var_dump(mysqli_poll($links, $errors, $reject, 0, 50000));
|
||||
|
||||
mysqli_close($mysqli1);
|
||||
mysqli_close($mysqli2);
|
||||
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
bool(true)
|
||||
bool(true)
|
||||
|
||||
Warning: mysqli_poll(): You MUST recompile PHP with a larger value of FD_SETSIZE.
|
||||
It is set to 1024, but you have descriptors numbered at least as high as %d.
|
||||
--enable-fd-setsize=%d is recommended, but you may want to set it
|
||||
to equal the maximum number of open files supported by your system,
|
||||
in order to avoid seeing this error again at a later date. in %s on line %d
|
||||
bool(false)
|
||||
done!
|
||||
--CLEAN--
|
||||
<?php
|
||||
for ($i = 0; $i < 1023; $i++) {
|
||||
@unlink(__DIR__ . "/GH-9590-tmpfile.$i");
|
||||
}
|
||||
?>
|
|
@ -2256,7 +2256,9 @@ mysqlnd_poll(MYSQLND **r_array, MYSQLND **e_array, MYSQLND ***dont_poll, long se
|
|||
DBG_RETURN(FAIL);
|
||||
}
|
||||
|
||||
PHP_SAFE_MAX_FD(max_fd, max_set_count);
|
||||
if (!PHP_SAFE_MAX_FD(max_fd, max_set_count)) {
|
||||
DBG_RETURN(FAIL);
|
||||
}
|
||||
|
||||
/* Solaris + BSD do not like microsecond values which are >= 1 sec */
|
||||
if (usec > 999999) {
|
||||
|
|
|
@ -613,7 +613,9 @@ PHP_FUNCTION(socket_select)
|
|||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
PHP_SAFE_MAX_FD(max_fd, 0); /* someone needs to make this look more like stream_socket_select */
|
||||
if (!PHP_SAFE_MAX_FD(max_fd, 0)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
/* If seconds is not set to null, build the timeval, else we wait indefinitely */
|
||||
if (!sec_is_null) {
|
||||
|
|
|
@ -799,7 +799,9 @@ PHP_FUNCTION(stream_select)
|
|||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
PHP_SAFE_MAX_FD(max_fd, max_set_count);
|
||||
if (!PHP_SAFE_MAX_FD(max_fd, max_set_count)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (secnull && !usecnull) {
|
||||
if (usec != 0) {
|
||||
|
|
38
ext/standard/tests/streams/gh9590-001.phpt
Normal file
38
ext/standard/tests/streams/gh9590-001.phpt
Normal file
|
@ -0,0 +1,38 @@
|
|||
--TEST--
|
||||
Bug GH-9590 001 (stream_select does not abort upon exception or empty valid fd set)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!function_exists('posix_setrlimit') || !posix_setrlimit(POSIX_RLIMIT_NOFILE, 2048, -1)) {
|
||||
die('skip Failed to set POSIX_RLIMIT_NOFILE');
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
posix_setrlimit(POSIX_RLIMIT_NOFILE, 2048, -1);
|
||||
|
||||
$fds = [];
|
||||
for ($i = 0; $i < 1023; $i++) {
|
||||
$fds[] = @fopen(__DIR__ . "/GH-9590-001-tmpfile.$i", 'w');
|
||||
}
|
||||
|
||||
list($a, $b) = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
|
||||
|
||||
$r = [$a];
|
||||
$w = $e = [];
|
||||
var_dump(stream_select($r, $w, $e, PHP_INT_MAX));
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: stream_select(): You MUST recompile PHP with a larger value of FD_SETSIZE.
|
||||
It is set to 1024, but you have descriptors numbered at least as high as %d.
|
||||
--enable-fd-setsize=%d is recommended, but you may want to set it
|
||||
to equal the maximum number of open files supported by your system,
|
||||
in order to avoid seeing this error again at a later date. in %s on line %d
|
||||
bool(false)
|
||||
--CLEAN--
|
||||
<?php
|
||||
for ($i = 0; $i < 1023; $i++) {
|
||||
@unlink(__DIR__ . "/GH-9590-001-tmpfile.$i");
|
||||
}
|
||||
?>
|
40
ext/standard/tests/streams/gh9590-002.phpt
Normal file
40
ext/standard/tests/streams/gh9590-002.phpt
Normal file
|
@ -0,0 +1,40 @@
|
|||
--TEST--
|
||||
Bug GH-9590 002 (stream_select does not abort upon exception or empty valid fd set)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!function_exists('posix_setrlimit') || !posix_setrlimit(POSIX_RLIMIT_NOFILE, 2048, -1)) {
|
||||
die('skip Failed to set POSIX_RLIMIT_NOFILE');
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
posix_setrlimit(POSIX_RLIMIT_NOFILE, 2048, -1);
|
||||
|
||||
$fds = [];
|
||||
for ($i = 0; $i < 1023; $i++) {
|
||||
$fds[] = @fopen(__DIR__ . "/GH-9590-002-tmpfile.$i", 'w');
|
||||
}
|
||||
|
||||
list($a, $b) = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
|
||||
|
||||
set_error_handler(function($errno, $errstr) { throw new \Exception($errstr); });
|
||||
|
||||
$r = [$a];
|
||||
$w = $e = [];
|
||||
var_dump(stream_select($r, $w, $e, PHP_INT_MAX));
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught Exception: stream_select(): You MUST recompile PHP with a larger value of FD_SETSIZE.
|
||||
It is set to 1024, but you have descriptors numbered at least as high as %d.
|
||||
--enable-fd-setsize=%d is recommended, but you may want to set it
|
||||
to equal the maximum number of open files supported by your system,
|
||||
in order to avoid seeing this error again at a later date. in %s:%d
|
||||
Stack trace:%a
|
||||
--CLEAN--
|
||||
<?php
|
||||
for ($i = 0; $i < 1023; $i++) {
|
||||
@unlink(__DIR__ . "/GH-9590-002-tmpfile.$i");
|
||||
}
|
||||
?>
|
|
@ -1200,7 +1200,14 @@ PHPAPI int php_poll2(php_pollfd *ufds, unsigned int nfds, int timeout)
|
|||
}
|
||||
#endif
|
||||
|
||||
PHP_SAFE_MAX_FD(max_fd, nfds + 1);
|
||||
if (!PHP_SAFE_MAX_FD(max_fd, nfds + 1)) {
|
||||
#ifdef PHP_WIN32
|
||||
WSASetLastError(WSAEINVAL);
|
||||
#else
|
||||
errno = ERANGE;
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
FD_ZERO(&rset);
|
||||
FD_ZERO(&wset);
|
||||
|
|
|
@ -211,18 +211,35 @@ static inline int php_pollfd_for_ms(php_socket_t fd, int events, int timeout)
|
|||
/* emit warning and suggestion for unsafe select(2) usage */
|
||||
PHPAPI void _php_emit_fd_setsize_warning(int max_fd);
|
||||
|
||||
static inline bool _php_check_fd_setsize(php_socket_t *max_fd, int setsize)
|
||||
{
|
||||
#ifdef PHP_WIN32
|
||||
if (setsize + 1 >= FD_SETSIZE) {
|
||||
_php_emit_fd_setsize_warning(setsize);
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
if (*max_fd >= FD_SETSIZE) {
|
||||
_php_emit_fd_setsize_warning(*max_fd);
|
||||
*max_fd = FD_SETSIZE - 1;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
/* it is safe to FD_SET too many fd's under win32; the macro will simply ignore
|
||||
* descriptors that go beyond the default FD_SETSIZE */
|
||||
# define PHP_SAFE_FD_SET(fd, set) FD_SET(fd, set)
|
||||
# define PHP_SAFE_FD_CLR(fd, set) FD_CLR(fd, set)
|
||||
# define PHP_SAFE_FD_ISSET(fd, set) FD_ISSET(fd, set)
|
||||
# define PHP_SAFE_MAX_FD(m, n) do { if (n + 1 >= FD_SETSIZE) { _php_emit_fd_setsize_warning(n); }} while(0)
|
||||
# define PHP_SAFE_MAX_FD(m, n) _php_check_fd_setsize(&m, n)
|
||||
#else
|
||||
# define PHP_SAFE_FD_SET(fd, set) do { if (fd < FD_SETSIZE) FD_SET(fd, set); } while(0)
|
||||
# define PHP_SAFE_FD_CLR(fd, set) do { if (fd < FD_SETSIZE) FD_CLR(fd, set); } while(0)
|
||||
# define PHP_SAFE_FD_ISSET(fd, set) ((fd < FD_SETSIZE) && FD_ISSET(fd, set))
|
||||
# define PHP_SAFE_MAX_FD(m, n) do { if (m >= FD_SETSIZE) { _php_emit_fd_setsize_warning(m); m = FD_SETSIZE - 1; }} while(0)
|
||||
# define PHP_SAFE_MAX_FD(m, n) _php_check_fd_setsize(&m, n)
|
||||
#endif
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue