diff --git a/NEWS b/NEWS index 1a16d1d6741..d5fc3492105 100644 --- a/NEWS +++ b/NEWS @@ -88,6 +88,8 @@ PHP NEWS (David Carlier) . socket_sendto() throws an exception on invalid port value. (David Carlier) + . socket_addrinfo_lookup throws an exception on invalid hints value types. + (David Carlier) - Standard: . Fixed crypt() tests on musl when using --with-external-libcrypt diff --git a/UPGRADING b/UPGRADING index 1e9472a2a5f..7f14ef7108b 100644 --- a/UPGRADING +++ b/UPGRADING @@ -127,6 +127,8 @@ PHP 8.5 UPGRADE NOTES - Sockets: . socket_create_listen, socket_bind and socket_sendto throw a ValueError if the port is lower than 0 or greater than 65535. + . socket_addrinfo_lookup throw a TypeError if any of the hints + values cannot be cast to a int. - Zlib: . The "use_include_path" argument for the diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index ebb2f7c6bd9..a17650bbc32 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -2586,14 +2586,35 @@ PHP_FUNCTION(socket_addrinfo_lookup) if (zhints && !HT_IS_PACKED(Z_ARRVAL_P(zhints))) { ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(zhints), key, hint) { if (key) { + bool failed = false; if (zend_string_equals_literal(key, "ai_flags")) { - hints.ai_flags = zval_get_long(hint); + zend_long val = zval_try_get_long(hint, &failed); + if (failed) { + zend_argument_type_error(3, "\"ai_flags\" key must be of type int, %s given", zend_zval_type_name(hint)); + RETURN_THROWS(); + } + hints.ai_flags = (int)val; } else if (zend_string_equals_literal(key, "ai_socktype")) { - hints.ai_socktype = zval_get_long(hint); + zend_long val = zval_try_get_long(hint, &failed); + if (failed) { + zend_argument_type_error(3, "\"ai_socktype\" key must be of type int, %s given", zend_zval_type_name(hint)); + RETURN_THROWS(); + } + hints.ai_socktype = (int)val; } else if (zend_string_equals_literal(key, "ai_protocol")) { - hints.ai_protocol = zval_get_long(hint); + zend_long val = zval_try_get_long(hint, &failed); + if (failed) { + zend_argument_type_error(3, "\"ai_protocol\" key must be of type int, %s given", zend_zval_type_name(hint)); + RETURN_THROWS(); + } + hints.ai_protocol = (int)val; } else if (zend_string_equals_literal(key, "ai_family")) { - hints.ai_family = zval_get_long(hint); + zend_long val = zval_try_get_long(hint, &failed); + if (failed) { + zend_argument_type_error(3, "\"ai_family\" key must be of type int, %s given", zend_zval_type_name(hint)); + RETURN_THROWS(); + } + hints.ai_family = (int)val; } else { zend_argument_value_error(3, "must only contain array keys \"ai_flags\", \"ai_socktype\", " "\"ai_protocol\", or \"ai_family\""); diff --git a/ext/sockets/tests/socket_getaddrinfo_error.phpt b/ext/sockets/tests/socket_getaddrinfo_error.phpt new file mode 100644 index 00000000000..8891c2b84a0 --- /dev/null +++ b/ext/sockets/tests/socket_getaddrinfo_error.phpt @@ -0,0 +1,52 @@ +--TEST-- +socket_addrinfo_lookup with invalid hints +--EXTENSIONS-- +sockets +--FILE-- + new stdClass(), + 'ai_socktype' => SOCK_DGRAM, + 'ai_flags' => 0, + 'ai_protocol' => 0, + )); +} catch (\TypeError $e) { + echo $e->getMessage() . PHP_EOL; +} +try { + socket_addrinfo_lookup('127.0.0.1', 2000, array( + 'ai_family' => AF_INET, + 'ai_socktype' => new stdClass(), + 'ai_flags' => 0, + 'ai_protocol' => 0, + )); +} catch (\TypeError $e) { + echo $e->getMessage() . PHP_EOL; +} +try { + socket_addrinfo_lookup('127.0.0.1', 2000, array( + 'ai_family' => AF_INET, + 'ai_socktype' => SOCK_DGRAM, + 'ai_flags' => new stdClass(), + 'ai_protocol' => 0, + )); +} catch (\TypeError $e) { + echo $e->getMessage() . PHP_EOL; +} +try { + socket_addrinfo_lookup('127.0.0.1', 2000, array( + 'ai_family' => AF_INET, + 'ai_socktype' => SOCK_DGRAM, + 'ai_flags' => 0, + 'ai_protocol' => new stdClass(), + )); +} catch (\TypeError $e) { + echo $e->getMessage() . PHP_EOL; +} +?> +--EXPECT-- +socket_addrinfo_lookup(): Argument #3 ($hints) "ai_family" key must be of type int, stdClass given +socket_addrinfo_lookup(): Argument #3 ($hints) "ai_socktype" key must be of type int, stdClass given +socket_addrinfo_lookup(): Argument #3 ($hints) "ai_flags" key must be of type int, stdClass given +socket_addrinfo_lookup(): Argument #3 ($hints) "ai_protocol" key must be of type int, stdClass given