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