Skip to content

Commit ecc9588

Browse files
committed
Properly handle non resources passed to socket_select()
As of PHP 8.0.0, failing `zend_fetch_resource_ex()` throws a TypeError, so we cannot simply skip non resources in the `$read`, `$write` and `$except` arrays. Instead we bail out. Since these arrays are already checked in `php_sock_array_to_fd_set()`, we remove the additional check in `php_sock_array_from_fd_set()`.
1 parent 04d5086 commit ecc9588

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
lines changed

ext/sockets/sockets.c

+20-5
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,7 @@ static int php_sock_array_to_fd_set(zval *sock_array, fd_set *fds, PHP_SOCKET *m
694694
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(sock_array), element) {
695695
ZVAL_DEREF(element);
696696
php_sock = (php_socket*) zend_fetch_resource_ex(element, le_socket_name, le_socket);
697-
if (!php_sock) continue; /* If element is not a resource, skip it */
697+
if (!php_sock) return -1; /* If element is not a resource, bail out */
698698

699699
PHP_SAFE_FD_SET(php_sock->bsd_socket, fds);
700700
if (php_sock->bsd_socket > *max_fd) {
@@ -723,7 +723,7 @@ static int php_sock_array_from_fd_set(zval *sock_array, fd_set *fds) /* {{{ */
723723
ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(sock_array), num_key, key, element) {
724724
ZVAL_DEREF(element);
725725
php_sock = (php_socket*) zend_fetch_resource_ex(element, le_socket_name, le_socket);
726-
if (!php_sock) continue; /* If element is not a resource, skip it */
726+
ZEND_ASSERT(php_sock); /* element is supposed to be resource */
727727

728728
if (PHP_SAFE_FD_ISSET(php_sock->bsd_socket, fds)) {
729729
/* Add fd to new array */
@@ -769,9 +769,24 @@ PHP_FUNCTION(socket_select)
769769
FD_ZERO(&wfds);
770770
FD_ZERO(&efds);
771771

772-
if (r_array != NULL) sets += php_sock_array_to_fd_set(r_array, &rfds, &max_fd);
773-
if (w_array != NULL) sets += php_sock_array_to_fd_set(w_array, &wfds, &max_fd);
774-
if (e_array != NULL) sets += php_sock_array_to_fd_set(e_array, &efds, &max_fd);
772+
if (r_array != NULL) {
773+
sets += retval = php_sock_array_to_fd_set(r_array, &rfds, &max_fd);
774+
if (retval == -1) {
775+
return;
776+
}
777+
}
778+
if (w_array != NULL) {
779+
sets += retval = php_sock_array_to_fd_set(w_array, &wfds, &max_fd);
780+
if (retval == -1) {
781+
return;
782+
}
783+
}
784+
if (e_array != NULL) {
785+
sets += retval = php_sock_array_to_fd_set(e_array, &efds, &max_fd);
786+
if (retval == -1) {
787+
return;
788+
}
789+
}
775790

776791
if (!sets) {
777792
php_error_docref(NULL, E_WARNING, "no resource arrays were passed to select");
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
socket_select() error conditions
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('sockets')) die('skip socket extension not available');
6+
?>
7+
--FILE--
8+
<?php
9+
$r = $w = $e = ['no resource'];
10+
try {
11+
socket_select($r, $w, $e, 1);
12+
} catch (TypeError $ex) {
13+
echo $ex->getMessage(), PHP_EOL;
14+
}
15+
?>
16+
--EXPECT--
17+
socket_select(): supplied argument is not a valid Socket resource

0 commit comments

Comments
 (0)