Commit 56bd75634f9 for php

commit 56bd75634f931745f35bbbde52aa92e319557ca1
Author: lacatoire <la.catoire@gmail.com>
Date:   Sun Aug 16 19:29:18 2026 +0200

    ext/ldap: fix crash in ldap_exop_sync() when $response_data is omitted

    ldap_exop_sync() always takes the synchronous branch of php_ldap_exop(),
    which assigns $response_data unconditionally. When the argument is not
    passed, retdata is NULL and ZEND_TRY_ASSIGN_REF_STRINGL()/
    ZEND_TRY_ASSIGN_REF_EMPTY_STRING() dereference it, so any successful
    ldap_exop_sync($ldap, $oid) call segfaults. Guard the assignment the way
    the $response_oid one already is.

    Closes GH-23339.

diff --git a/NEWS b/NEWS
index 798f849854c..433aa7d0297 100644
--- a/NEWS
+++ b/NEWS
@@ -111,6 +111,9 @@ PHP                                                                        NEWS
     properties after running out of memory while escaping a property name.
     (adapik)

+- LDAP:
+  . Fix crash in ldap_exop_sync() when $response_data is omitted. (lacatoire)
+
 - MBString:
   . Fixed bug GH-23958 (truncated encoding names resolving to full names). (Kamil Tekiela)
   . Fixed out-of-bounds read in php_mb_rfc1867_getword() on a multibyte lead
diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c
index 2b3cb0e8a70..4c9466749ea 100644
--- a/ext/ldap/ldap.c
+++ b/ext/ldap/ldap.c
@@ -4129,10 +4129,12 @@ static void php_ldap_exop(INTERNAL_FUNCTION_PARAMETERS, bool force_sync) {
 		}

 		if (lretdata) {
-			ZEND_TRY_ASSIGN_REF_STRINGL(retdata, lretdata->bv_val, lretdata->bv_len);
+			if (retdata) {
+				ZEND_TRY_ASSIGN_REF_STRINGL(retdata, lretdata->bv_val, lretdata->bv_len);
+			}
 			ldap_memfree(lretdata->bv_val);
 			ldap_memfree(lretdata);
-		} else {
+		} else if (retdata) {
 			ZEND_TRY_ASSIGN_REF_EMPTY_STRING(retdata);
 		}

diff --git a/ext/ldap/tests/ldap_exop_sync_without_response_data.phpt b/ext/ldap/tests/ldap_exop_sync_without_response_data.phpt
new file mode 100644
index 00000000000..111900c6a05
--- /dev/null
+++ b/ext/ldap/tests/ldap_exop_sync_without_response_data.phpt
@@ -0,0 +1,22 @@
+--TEST--
+ldap_exop_sync() - without the response_data argument
+--EXTENSIONS--
+ldap
+--SKIPIF--
+<?php require_once('skipifbindfailure.inc'); ?>
+--FILE--
+<?php
+require "connect.inc";
+
+$link = ldap_connect_and_bind($uri, $user, $passwd, $protocol_version);
+
+var_dump(
+    ldap_exop_sync($link, LDAP_EXOP_WHO_AM_I),
+    ldap_exop_sync($link, LDAP_EXOP_WHO_AM_I, null, null, $retdata),
+    $retdata
+);
+?>
+--EXPECTF--
+bool(true)
+bool(true)
+string(%d) "dn:%s"