Skip to content

Commit 64f819f

Browse files
committed
ext/socket: Throw TypeErrors when not passing a string for options requiering one
1 parent eb86bb4 commit 64f819f

6 files changed

+192
-18
lines changed

ext/sockets/sockets.c

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1921,13 +1921,12 @@ PHP_FUNCTION(socket_set_option)
19211921
switch (optname) {
19221922
#ifdef TCP_CONGESTION
19231923
case TCP_CONGESTION: {
1924-
if (Z_TYPE_P(arg4) == IS_STRING) {
1925-
opt_ptr = Z_STRVAL_P(arg4);
1926-
optlen = Z_STRLEN_P(arg4);
1927-
} else {
1928-
opt_ptr = "";
1929-
optlen = 0;
1924+
if (Z_TYPE_P(arg4) != IS_STRING) {
1925+
zend_argument_type_error(4, "must be of type string when argument #3 ($option) is TCP_CONGESTION, %s given", zend_zval_value_name(arg4));
1926+
RETURN_THROWS();
19301927
}
1928+
opt_ptr = Z_STRVAL_P(arg4);
1929+
optlen = Z_STRLEN_P(arg4);
19311930
if (setsockopt(php_sock->bsd_socket, level, optname, opt_ptr, optlen) != 0) {
19321931
PHP_SOCKET_ERROR(php_sock, "Unable to set socket option", errno);
19331932
RETURN_FALSE;
@@ -1940,8 +1939,8 @@ PHP_FUNCTION(socket_set_option)
19401939
#ifdef TCP_FUNCTION_BLK
19411940
case TCP_FUNCTION_BLK: {
19421941
if (Z_TYPE_P(arg4) != IS_STRING) {
1943-
php_error_docref(NULL, E_WARNING, "Invalid tcp stack name argument type");
1944-
RETURN_FALSE;
1942+
zend_argument_type_error(4, "must be of type string when argument #3 ($option) is TCP_FUNCTION_BLK, %s given", zend_zval_value_name(arg4));
1943+
RETURN_THROWS();
19451944
}
19461945
struct tcp_function_set tfs = {0};
19471946
strlcpy(tfs.function_set_name, Z_STRVAL_P(arg4), TCP_FUNCTION_NAME_LEN_MAX);
@@ -2054,22 +2053,21 @@ PHP_FUNCTION(socket_set_option)
20542053
}
20552054
#ifdef SO_BINDTODEVICE
20562055
case SO_BINDTODEVICE: {
2057-
if (Z_TYPE_P(arg4) == IS_STRING) {
2058-
opt_ptr = Z_STRVAL_P(arg4);
2059-
optlen = Z_STRLEN_P(arg4);
2060-
} else {
2061-
opt_ptr = "";
2062-
optlen = 0;
2056+
if (Z_TYPE_P(arg4) != IS_STRING) {
2057+
zend_argument_type_error(4, "must be of type string when argument #3 ($option) is SO_BINDTODEVICE, %s given", zend_zval_value_name(arg4));
2058+
RETURN_THROWS();
20632059
}
2060+
opt_ptr = Z_STRVAL_P(arg4);
2061+
optlen = Z_STRLEN_P(arg4);
20642062
break;
20652063
}
20662064
#endif
20672065

20682066
#ifdef SO_ACCEPTFILTER
20692067
case SO_ACCEPTFILTER: {
20702068
if (Z_TYPE_P(arg4) != IS_STRING) {
2071-
php_error_docref(NULL, E_WARNING, "Invalid filter argument type");
2072-
RETURN_FALSE;
2069+
zend_argument_type_error(4, "must be of type string when argument #3 ($option) is SO_ACCEPTFILTER, %s given", zend_zval_value_name(arg4));
2070+
RETURN_THROWS();
20732071
}
20742072
struct accept_filter_arg af = {0};
20752073
strlcpy(af.af_name, Z_STRVAL_P(arg4), sizeof(af.af_name));
@@ -2087,8 +2085,8 @@ PHP_FUNCTION(socket_set_option)
20872085
RETURN_FALSE;
20882086
}
20892087
if (Z_TYPE_P(arg4) != IS_STRING) {
2090-
php_error_docref(NULL, E_WARNING, "Invalid filter argument type");
2091-
RETURN_FALSE;
2088+
zend_argument_type_error(4, "must be of type string when argument #3 ($option) is FIL_ATTACH or FIL_DETACH, %s given", zend_zval_value_name(arg4));
2089+
RETURN_THROWS();
20922090
}
20932091
opt_ptr = Z_STRVAL_P(arg4);
20942092
optlen = Z_STRLEN_P(arg4);
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
socket_set_option($socket, IPPROTO_TCP, TCP_CONGESTION, INVALID_TYPE_FOR_OPTION)
3+
--EXTENSIONS--
4+
sockets
5+
--SKIPIF--
6+
<?php
7+
8+
if (!defined('IPPROTO_TCP')) {
9+
die('skip IPPROTO_TCP not available.');
10+
}
11+
if (!defined('TCP_CONGESTION')) {
12+
die('skip TCP_CONGESTION not available.');
13+
}
14+
15+
?>
16+
--FILE--
17+
<?php
18+
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
19+
if (!$socket) {
20+
die('Unable to create AF_INET socket [socket]');
21+
}
22+
23+
try {
24+
$ret = socket_set_option($socket, IPPROTO_TCP, TCP_CONGESTION, new stdClass());
25+
var_dump($ret);
26+
} catch (Throwable $e) {
27+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
28+
}
29+
30+
socket_close($socket);
31+
?>
32+
--EXPECT--
33+
TypeError: socket_set_option(): Argument #4 ($value) must be of type string when argument #3 ($option) is TCP_CONGESTION, stdClass given
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
socket_set_option($socket, IPPROTO_TCP, TCP_FUNCTION_BLK, INVALID_TYPE_FOR_OPTION)
3+
--EXTENSIONS--
4+
sockets
5+
--SKIPIF--
6+
<?php
7+
8+
if (!defined('IPPROTO_TCP')) {
9+
die('skip IPPROTO_TCP not available.');
10+
}
11+
if (!defined('TCP_FUNCTION_BLK')) {
12+
die('skip TCP_FUNCTION_BLK not available.');
13+
}
14+
15+
?>
16+
--FILE--
17+
<?php
18+
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
19+
if (!$socket) {
20+
die('Unable to create AF_INET socket [socket]');
21+
}
22+
23+
try {
24+
$ret = socket_set_option($socket, IPPROTO_TCP, TCP_FUNCTION_BLK, new stdClass());
25+
var_dump($ret);
26+
} catch (Throwable $e) {
27+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
28+
}
29+
30+
socket_close($socket);
31+
?>
32+
--EXPECT--
33+
TypeError: socket_set_option(): Argument #4 ($value) must be of type string when argument #3 ($option) is TCP_FUNCTION_BLK, stdClass given
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
--TEST--
2+
socket_set_option($socket, SOL_SOCKET, SO_BINDTODEVICE, INVALID_TYPE_FOR_OPTION)
3+
--EXTENSIONS--
4+
sockets
5+
--SKIPIF--
6+
<?php
7+
8+
if (!defined('SOL_FILTER')) {
9+
die('skip SOL_FILTER not available.');
10+
}
11+
if (!defined('FIL_ATTACH')) {
12+
die('skip FIL_ATTACH not available.');
13+
}
14+
if (!defined('FIL_DETACH')) {
15+
die('skip FIL_DETACH not available.');
16+
}
17+
18+
?>
19+
--FILE--
20+
<?php
21+
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
22+
if (!$socket) {
23+
die('Unable to create AF_INET socket [socket]');
24+
}
25+
26+
// TODO Warning when using FIL_ATTACH/FIL_DETACH option when level is not SOL_FILTER
27+
try {
28+
$ret = socket_set_option($socket, SOL_FILTER, FIL_ATTACH, new stdClass());
29+
var_dump($ret);
30+
} catch (Throwable $e) {
31+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
32+
}
33+
try {
34+
$ret = socket_set_option($socket, SOL_FILTER, FIL_DETACH, new stdClass());
35+
var_dump($ret);
36+
} catch (Throwable $e) {
37+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
38+
}
39+
40+
socket_close($socket);
41+
?>
42+
--EXPECT--
43+
TypeError: socket_set_option(): Argument #4 ($value) must be of type string when argument #3 ($option) is FIL_ATTACH or FIL_DETACH, stdClass given
44+
TypeError: socket_set_option(): Argument #4 ($value) must be of type string when argument #3 ($option) is FIL_ATTACH or FIL_DETACH, stdClass given
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
socket_set_option($socket, SOL_SOCKET, SO_ACCEPTFILTER, INVALID_TYPE_FOR_OPTION)
3+
--EXTENSIONS--
4+
sockets
5+
--SKIPIF--
6+
<?php
7+
8+
if (!defined('SOL_SOCKET')) {
9+
die('skip SOL_SOCKET not available.');
10+
}
11+
if (!defined('SO_ACCEPTFILTER')) {
12+
die('skip SO_ACCEPTFILTER not available.');
13+
}
14+
15+
?>
16+
--FILE--
17+
<?php
18+
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
19+
if (!$socket) {
20+
die('Unable to create AF_INET socket [socket]');
21+
}
22+
23+
try {
24+
$ret = socket_set_option($socket, SOL_SOCKET, SO_ACCEPTFILTER, new stdClass());
25+
var_dump($ret);
26+
} catch (Throwable $e) {
27+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
28+
}
29+
30+
socket_close($socket);
31+
?>
32+
--EXPECT--
33+
TypeError: socket_set_option(): Argument #4 ($value) must be of type string when argument #3 ($option) is SO_ACCEPTFILTER, stdClass given
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
socket_set_option($socket, SOL_SOCKET, SO_BINDTODEVICE, INVALID_TYPE_FOR_OPTION)
3+
--EXTENSIONS--
4+
sockets
5+
--SKIPIF--
6+
<?php
7+
8+
if (!defined('SOL_SOCKET')) {
9+
die('skip SOL_SOCKET not available.');
10+
}
11+
if (!defined('SO_BINDTODEVICE')) {
12+
die('skip SO_BINDTODEVICE not available.');
13+
}
14+
15+
?>
16+
--FILE--
17+
<?php
18+
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
19+
if (!$socket) {
20+
die('Unable to create AF_INET socket [socket]');
21+
}
22+
23+
try {
24+
$ret = socket_set_option($socket, SOL_SOCKET, SO_BINDTODEVICE, new stdClass());
25+
var_dump($ret);
26+
} catch (Throwable $e) {
27+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
28+
}
29+
30+
socket_close($socket);
31+
?>
32+
--EXPECT--
33+
TypeError: socket_set_option(): Argument #4 ($value) must be of type string when argument #3 ($option) is SO_BINDTODEVICE, stdClass given

0 commit comments

Comments
 (0)