diff --git a/UPGRADING b/UPGRADING index 7f0fcaf8943a8..140c27b3de18d 100644 --- a/UPGRADING +++ b/UPGRADING @@ -57,6 +57,9 @@ PHP 8.6 UPGRADE NOTES - Phar: . Phar::mungServer() now supports reference values. +- Sockets: + . socket_addrinfo_lookup() now returns an error code instead of FALSE on resolution failures. + - Zip: . ZipArchive::extractTo now raises a TypeError for the files argument if one or more of the entries is not @@ -85,6 +88,25 @@ PHP 8.6 UPGRADE NOTES 10. New Global Constants ======================================== +- Sockets: + . EAI_BADFLAGS. + . EAI_NONAME. + . EAI_AGAIN. + . EAI_FAIL. + . EAI_NODATA. + . EAI_FAMILY. + . EAI_SOCKTYPE. + . EAI_SERVICE. + . EAI_ADDRFAMILY. + . EAI_SYSTEM. + . EAI_OVERFLOW + . EAI_INPROGRESS. + . EAI_CANCELED. + . EAI_NOTCANCELED. + . EAI_ALLDONE. + . EAI_INTR. + . EAI_IDN_ENCODE. + ======================================== 11. Changes to INI File Handling ======================================== diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index 4a9332498c3cc..0567caad9408a 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -2730,16 +2730,18 @@ PHP_FUNCTION(socket_addrinfo_lookup) char *service = NULL; size_t service_len = 0; zend_string *hostname, *key; - zval *hint, *zhints = NULL; + zval *hint, *zhints = NULL, *error_code = NULL; + int ret = 0; struct addrinfo hints, *result, *rp; php_addrinfo *res; - ZEND_PARSE_PARAMETERS_START(1, 3) + ZEND_PARSE_PARAMETERS_START(1, 4) Z_PARAM_STR(hostname) Z_PARAM_OPTIONAL Z_PARAM_STRING_OR_NULL(service, service_len) Z_PARAM_ARRAY(zhints) + Z_PARAM_ZVAL_OR_NULL(error_code) ZEND_PARSE_PARAMETERS_END(); memset(&hints, 0, sizeof(hints)); @@ -2825,7 +2827,10 @@ PHP_FUNCTION(socket_addrinfo_lookup) } ZEND_HASH_FOREACH_END(); } - if (getaddrinfo(ZSTR_VAL(hostname), service, &hints, &result) != 0) { + if ((ret = getaddrinfo(ZSTR_VAL(hostname), service, &hints, &result)) != 0) { + if (error_code) { + ZEND_TRY_ASSIGN_REF_LONG(error_code, ret); + } RETURN_FALSE; } diff --git a/ext/sockets/sockets.stub.php b/ext/sockets/sockets.stub.php index 3df9b598a1e8f..bbc9cbb077ea8 100644 --- a/ext/sockets/sockets.stub.php +++ b/ext/sockets/sockets.stub.php @@ -2053,6 +2053,136 @@ const SHUT_RDWR = UNKNOWN; #endif + +#ifdef EAI_BADFLAGS +/** + * @var int + * @cvalue EAI_BADFLAGS + */ +const EAI_BADFLAGS = UNKNOWN; +#endif +#ifdef EAI_NONAME +/** + * @var int + * @cvalue EAI_NONAME + */ +const EAI_NONAME = UNKNOWN; +#endif +#ifdef EAI_AGAIN +/** + * @var int + * @cvalue EAI_AGAIN + */ +const EAI_AGAIN = UNKNOWN; +#endif +#ifdef EAI_FAIL +/** + * @var int + * @cvalue EAI_FAIL + */ +const EAI_FAIL = UNKNOWN; +#endif +#ifdef EAI_NODATA +/** + * @var int + * @cvalue EAI_NODATA + */ +const EAI_NODATA = UNKNOWN; +#endif +#ifdef EAI_FAMILY +/** + * @var int + * @cvalue EAI_FAMILY + */ +const EAI_FAMILY = UNKNOWN; +#endif +#ifdef EAI_SOCKTYPE +/** + * @var int + * @cvalue EAI_SOCKTYPE + */ +const EAI_SOCKTYPE = UNKNOWN; +#endif +#ifdef EAI_SERVICE +/** + * @var int + * @cvalue EAI_SERVICE + */ +const EAI_SERVICE = UNKNOWN; +#endif +#ifdef EAI_ADDRFAMILY +/** + * @var int + * @cvalue EAI_ADDRFAMILY + */ +const EAI_ADDRFAMILY = UNKNOWN; +#else +#ifdef EAI_FAMILY +/** + * @var int + * @cvalue EAI_FAMILY + */ +const EAI_ADDRFAMILY = UNKNOWN; +#else +#endif +#endif +#ifdef EAI_SYSTEM +/** + * @var int + * @cvalue EAI_SYSTEM + */ +const EAI_SYSTEM = UNKNOWN; +#endif +#ifdef EAI_OVERFLOW +/** + * @var int + * @cvalue EAI_OVERFLOW + */ +const EAI_OVERFLOW = UNKNOWN; +#endif +#ifdef EAI_INPROGRESS +/** + * @var int + * @cvalue EAI_INPROGRESS + */ +const EAI_INPROGRESS = UNKNOWN; +#endif +#ifdef EAI_CANCELED +/** + * @var int + * @cvalue EAI_CANCELED + */ +const EAI_CANCELED = UNKNOWN; +#endif +#ifdef EAI_NOTCANCELED +/** + * @var int + * @cvalue EAI_NOTCANCELED + */ +const EAI_NOTCANCELED = UNKNOWN; +#endif +#ifdef EAI_ALLDONE +/** + * @var int + * @cvalue EAI_ALLDONE + */ +const EAI_ALLDONE = UNKNOWN; +#endif +#ifdef EAI_INTR +/** + * @var int + * @cvalue EAI_INTR + */ +const EAI_INTR = UNKNOWN; +#endif +#ifdef EAI_IDN_ENCODE +/** + * @var int + * @cvalue EAI_IDN_ENCODE + */ +const EAI_IDN_ENCODE = UNKNOWN; +#endif + /** * @strict-properties * @not-serializable @@ -2173,9 +2303,10 @@ function socket_cmsg_space(int $level, int $type, int $num = 0): ?int {} /** * @return array|false + * @param int $error_code * @refcount 1 */ -function socket_addrinfo_lookup(string $host, ?string $service = null, array $hints = []): array|false {} +function socket_addrinfo_lookup(string $host, ?string $service = null, array $hints = [], &$error_code = null): array|false {} function socket_addrinfo_connect(AddressInfo $address): Socket|false {} diff --git a/ext/sockets/sockets_arginfo.h b/ext/sockets/sockets_arginfo.h index edfc344ff8cc0..94455beec6735 100644 --- a/ext/sockets/sockets_arginfo.h +++ b/ext/sockets/sockets_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: f754368e28f6e45bf3a63a403e49f5659c29d2c6 */ + * Stub hash: d1769513ef7c8ecbf7de53822e28869f8e3293f3 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_socket_select, 0, 4, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(1, read, IS_ARRAY, 1) @@ -184,6 +184,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_socket_addrinfo_lookup, 0, 1, MA ZEND_ARG_TYPE_INFO(0, host, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, service, IS_STRING, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, hints, IS_ARRAY, 0, "[]") + ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, error_code, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_socket_addrinfo_connect, 0, 1, Socket, MAY_BE_FALSE) @@ -1048,6 +1049,60 @@ static void register_sockets_symbols(int module_number) REGISTER_LONG_CONSTANT("SHUT_WR", SHUT_WR, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SHUT_RDWR", SHUT_RDWR, CONST_PERSISTENT); #endif +#if defined(EAI_BADFLAGS) + REGISTER_LONG_CONSTANT("EAI_BADFLAGS", EAI_BADFLAGS, CONST_PERSISTENT); +#endif +#if defined(EAI_NONAME) + REGISTER_LONG_CONSTANT("EAI_NONAME", EAI_NONAME, CONST_PERSISTENT); +#endif +#if defined(EAI_AGAIN) + REGISTER_LONG_CONSTANT("EAI_AGAIN", EAI_AGAIN, CONST_PERSISTENT); +#endif +#if defined(EAI_FAIL) + REGISTER_LONG_CONSTANT("EAI_FAIL", EAI_FAIL, CONST_PERSISTENT); +#endif +#if defined(EAI_NODATA) + REGISTER_LONG_CONSTANT("EAI_NODATA", EAI_NODATA, CONST_PERSISTENT); +#endif +#if defined(EAI_FAMILY) + REGISTER_LONG_CONSTANT("EAI_FAMILY", EAI_FAMILY, CONST_PERSISTENT); +#endif +#if defined(EAI_SOCKTYPE) + REGISTER_LONG_CONSTANT("EAI_SOCKTYPE", EAI_SOCKTYPE, CONST_PERSISTENT); +#endif +#if defined(EAI_SERVICE) + REGISTER_LONG_CONSTANT("EAI_SERVICE", EAI_SERVICE, CONST_PERSISTENT); +#endif +#if defined(EAI_ADDRFAMILY) + REGISTER_LONG_CONSTANT("EAI_ADDRFAMILY", EAI_ADDRFAMILY, CONST_PERSISTENT); +#endif +#if !(defined(EAI_ADDRFAMILY)) && defined(EAI_FAMILY) + REGISTER_LONG_CONSTANT("EAI_ADDRFAMILY", EAI_FAMILY, CONST_PERSISTENT); +#endif +#if defined(EAI_SYSTEM) + REGISTER_LONG_CONSTANT("EAI_SYSTEM", EAI_SYSTEM, CONST_PERSISTENT); +#endif +#if defined(EAI_OVERFLOW) + REGISTER_LONG_CONSTANT("EAI_OVERFLOW", EAI_OVERFLOW, CONST_PERSISTENT); +#endif +#if defined(EAI_INPROGRESS) + REGISTER_LONG_CONSTANT("EAI_INPROGRESS", EAI_INPROGRESS, CONST_PERSISTENT); +#endif +#if defined(EAI_CANCELED) + REGISTER_LONG_CONSTANT("EAI_CANCELED", EAI_CANCELED, CONST_PERSISTENT); +#endif +#if defined(EAI_NOTCANCELED) + REGISTER_LONG_CONSTANT("EAI_NOTCANCELED", EAI_NOTCANCELED, CONST_PERSISTENT); +#endif +#if defined(EAI_ALLDONE) + REGISTER_LONG_CONSTANT("EAI_ALLDONE", EAI_ALLDONE, CONST_PERSISTENT); +#endif +#if defined(EAI_INTR) + REGISTER_LONG_CONSTANT("EAI_INTR", EAI_INTR, CONST_PERSISTENT); +#endif +#if defined(EAI_IDN_ENCODE) + REGISTER_LONG_CONSTANT("EAI_IDN_ENCODE", EAI_IDN_ENCODE, CONST_PERSISTENT); +#endif } static zend_class_entry *register_class_Socket(void) diff --git a/ext/sockets/tests/gh20532.phpt b/ext/sockets/tests/gh20532.phpt new file mode 100644 index 0000000000000..f3368c830369a --- /dev/null +++ b/ext/sockets/tests/gh20532.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-20562 - socket_addrinfo_lookup() returns error codes on resolution failures. +--EXTENSIONS-- +sockets +--FILE-- + AF_INET], $error_code) === false && in_array($error_code, [EAI_FAMILY, EAI_ADDRFAMILY, EAI_NONAME, EAI_NODATA])); +var_dump(socket_addrinfo_lookup("example.com", "http", ['ai_socktype' => SOCK_RAW, 'ai_flags' => 2147483647], $error_code) === false && in_array($error_code, [EAI_SOCKTYPE, EAI_SERVICE, EAI_BADFLAGS, EAI_NONAME])); +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) +