Commit 9b719cd4a35 for php.net
commit 9b719cd4a3501ed76e2eaf88f4506c7fe73ee546
Author: David CARLIER <devnexen@gmail.com>
Date: Thu Jan 15 19:24:56 2026 +0000
ext/sockets: socket_addrinfo_lookup() allows AF_UNSPEC for ai_family. (#20658)
while still filtering out IPC like addresses and so on.
close GH-20658
diff --git a/NEWS b/NEWS
index 9c1fc8c14b0..062265576af 100644
--- a/NEWS
+++ b/NEWS
@@ -80,7 +80,9 @@ PHP NEWS
- Sockets:
. Added the TCP_USER_TIMEOUT constant for Linux to set the maximum time in milliseconds
- transmitted data can remain unacknowledged. (James Lucas)
+ transmitted data can remain unacknowledged. (James Lucas)
+ . Added AF_UNSPEC support for sock_addrinfo_lookup() as a sole umbrella for
+ AF_INET* family only. (David Carlier)
- SPL:
. DirectoryIterator key can now work better with filesystem supporting larger
diff --git a/UPGRADING b/UPGRADING
index a160f0c901a..0b651e5895c 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -111,6 +111,7 @@ PHP 8.6 UPGRADE NOTES
- Sockets:
. TCP_USER_TIMEOUT (Linux only).
+ . AF_UNSPEC.
========================================
11. Changes to INI File Handling
diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c
index b76818830fc..54f862d5536 100644
--- a/ext/sockets/sockets.c
+++ b/ext/sockets/sockets.c
@@ -2749,8 +2749,7 @@ PHP_FUNCTION(socket_export_stream)
/* {{{ Gets array with contents of getaddrinfo about the given hostname. */
PHP_FUNCTION(socket_addrinfo_lookup)
{
- char *service = NULL;
- size_t service_len = 0;
+ zend_string *service = NULL;
zend_string *hostname, *key;
zval *hint, *zhints = NULL;
@@ -2760,7 +2759,7 @@ PHP_FUNCTION(socket_addrinfo_lookup)
ZEND_PARSE_PARAMETERS_START(1, 3)
Z_PARAM_STR(hostname)
Z_PARAM_OPTIONAL
- Z_PARAM_STRING_OR_NULL(service, service_len)
+ Z_PARAM_STR_OR_NULL(service)
Z_PARAM_ARRAY(zhints)
ZEND_PARSE_PARAMETERS_END();
@@ -2824,14 +2823,16 @@ PHP_FUNCTION(socket_addrinfo_lookup)
// Some platforms support also PF_LOCAL/AF_UNIX (e.g. FreeBSD) but the security concerns implied
// make it not worth handling it (e.g. unwarranted write permissions on the socket).
// Note existing socket_addrinfo* api already forbid such case.
+ if (val != AF_UNSPEC) {
#ifdef HAVE_IPV6
- if (val != AF_INET && val != AF_INET6) {
- zend_argument_value_error(3, "\"ai_family\" key must be AF_INET or AF_INET6");
+ if (val != AF_INET && val != AF_INET6) {
+ zend_argument_value_error(3, "\"ai_family\" key must be AF_INET or AF_INET6");
#else
- if (val != AF_INET) {
- zend_argument_value_error(3, "\"ai_family\" key must be AF_INET");
+ if (val != AF_INET) {
+ zend_argument_value_error(3, "\"ai_family\" key must be AF_INET");
#endif
- RETURN_THROWS();
+ RETURN_THROWS();
+ }
}
hints.ai_family = (int)val;
} else {
@@ -2847,7 +2848,7 @@ PHP_FUNCTION(socket_addrinfo_lookup)
} ZEND_HASH_FOREACH_END();
}
- if (getaddrinfo(ZSTR_VAL(hostname), service, &hints, &result) != 0) {
+ if (getaddrinfo(ZSTR_VAL(hostname), service ? ZSTR_VAL(service) : NULL, &hints, &result) != 0) {
RETURN_FALSE;
}
@@ -2855,7 +2856,11 @@ PHP_FUNCTION(socket_addrinfo_lookup)
zend_hash_real_init_packed(Z_ARRVAL_P(return_value));
for (rp = result; rp != NULL; rp = rp->ai_next) {
- if (rp->ai_family != AF_UNSPEC) {
+ if (rp->ai_family == AF_INET
+#ifdef HAVE_IPV6
+ || rp->ai_family == AF_INET6
+#endif
+ ) {
zval zaddr;
object_init_ex(&zaddr, address_info_ce);
diff --git a/ext/sockets/sockets.stub.php b/ext/sockets/sockets.stub.php
index 04fb702807e..0f645da25ce 100644
--- a/ext/sockets/sockets.stub.php
+++ b/ext/sockets/sockets.stub.php
@@ -19,6 +19,13 @@
*/
const AF_INET6 = UNKNOWN;
#endif
+#ifdef AF_UNSPEC
+/**
+ * @var int
+ * @cvalue AF_UNSPEC
+ */
+const AF_UNSPEC = UNKNOWN;
+#endif
#ifdef AF_DIVERT
/**
* @var int
diff --git a/ext/sockets/sockets_arginfo.h b/ext/sockets/sockets_arginfo.h
index 0145d012528..50a81c5ee3a 100644
Binary files a/ext/sockets/sockets_arginfo.h and b/ext/sockets/sockets_arginfo.h differ