From 41a03c35bfbace3d977c4ac409b90c5c553a07ad Mon Sep 17 00:00:00 2001 From: David Carlier Date: Mon, 30 Dec 2024 08:56:39 +0000 Subject: [PATCH] ext/socket: socket_addrinfo_lookup check hints array. --- ext/sockets/sockets.c | 29 +++++++++-- .../tests/socket_getaddrinfo_error.phpt | 52 +++++++++++++++++++ 2 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 ext/sockets/tests/socket_getaddrinfo_error.phpt diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index ebb2f7c6bd90..a17650bbc32a 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 000000000000..8891c2b84a02 --- /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