Skip to content

Commit 57b16fc

Browse files
committed
Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4: ext/sockets: socket_select() silent set truncation on Windows.
2 parents d84d188 + 2bca736 commit 57b16fc

2 files changed

Lines changed: 66 additions & 7 deletions

File tree

‎ext/sockets/sockets.c‎

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ static int php_sock_array_to_fd_set(uint32_t arg_num, zval *sock_array, fd_set *
579579
num++;
580580
} ZEND_HASH_FOREACH_END();
581581

582-
return num ? 1 : 0;
582+
return num;
583583
}
584584
/* }}} */
585585

@@ -630,7 +630,7 @@ PHP_FUNCTION(socket_select)
630630
struct timeval *tv_p = NULL;
631631
fd_set rfds, wfds, efds;
632632
PHP_SOCKET max_fd = 0;
633-
int retval, sets = 0;
633+
int retval, max_set_count = 0;
634634
zend_long sec, usec = 0;
635635
bool sec_is_null = 0;
636636

@@ -648,30 +648,39 @@ PHP_FUNCTION(socket_select)
648648
FD_ZERO(&efds);
649649

650650
if (r_array != NULL) {
651-
sets += retval = php_sock_array_to_fd_set(1, r_array, &rfds, &max_fd);
651+
retval = php_sock_array_to_fd_set(1, r_array, &rfds, &max_fd);
652652
if (retval == -1) {
653653
RETURN_THROWS();
654654
}
655+
if (retval > max_set_count) {
656+
max_set_count = retval;
657+
}
655658
}
656659
if (w_array != NULL) {
657-
sets += retval = php_sock_array_to_fd_set(2, w_array, &wfds, &max_fd);
660+
retval = php_sock_array_to_fd_set(2, w_array, &wfds, &max_fd);
658661
if (retval == -1) {
659662
RETURN_THROWS();
660663
}
664+
if (retval > max_set_count) {
665+
max_set_count = retval;
666+
}
661667
}
662668
if (e_array != NULL) {
663-
sets += retval = php_sock_array_to_fd_set(3, e_array, &efds, &max_fd);
669+
retval = php_sock_array_to_fd_set(3, e_array, &efds, &max_fd);
664670
if (retval == -1) {
665671
RETURN_THROWS();
666672
}
673+
if (retval > max_set_count) {
674+
max_set_count = retval;
675+
}
667676
}
668677

669-
if (!sets) {
678+
if (!max_set_count) {
670679
zend_value_error("socket_select(): At least one array argument must be passed");
671680
RETURN_THROWS();
672681
}
673682

674-
if (!PHP_SAFE_MAX_FD(max_fd, 0)) {
683+
if (!PHP_SAFE_MAX_FD(max_fd, max_set_count)) {
675684
RETURN_FALSE;
676685
}
677686

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
--TEST--
2+
socket_select() reports an overflowing set instead of silently truncating it
3+
--EXTENSIONS--
4+
sockets
5+
--SKIPIF--
6+
<?php
7+
if (PHP_OS_FAMILY !== 'Windows') {
8+
die('skip Windows only, elsewhere the overflow is caught through max_fd');
9+
}
10+
?>
11+
--FILE--
12+
<?php
13+
$sockets = [];
14+
for ($i = 0; $i < 300; $i++) {
15+
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
16+
if ($socket === false) {
17+
break;
18+
}
19+
$sockets[] = $socket;
20+
}
21+
22+
var_dump(count($sockets) > 256);
23+
24+
$read = $sockets;
25+
$write = $except = null;
26+
var_dump(socket_select($read, $write, $except, 0));
27+
28+
$write = $sockets;
29+
$read = $except = null;
30+
var_dump(socket_select($read, $write, $except, 0));
31+
32+
$except = $sockets;
33+
$read = $write = null;
34+
var_dump(socket_select($read, $write, $except, 0));
35+
36+
foreach ($sockets as $socket) {
37+
socket_close($socket);
38+
}
39+
?>
40+
--EXPECTF--
41+
bool(true)
42+
43+
Warning: socket_select(): PHP needs to be recompiled with a larger value of FD_SETSIZE.%A
44+
bool(false)
45+
46+
Warning: socket_select(): PHP needs to be recompiled with a larger value of FD_SETSIZE.%A
47+
bool(false)
48+
49+
Warning: socket_select(): PHP needs to be recompiled with a larger value of FD_SETSIZE.%A
50+
bool(false)

0 commit comments

Comments
 (0)