Commit 1b6ccd5b587 for php

commit 1b6ccd5b587a01b71444ec4ca5b56d1af46d12c8
Merge: a4c4173d9a1 ed60b9edebd
Author: Ilia Alshanetsky <ilia@ilia.ws>
Date:   Sun Sep 27 12:33:50 2026 -0400

    Merge branch 'PHP-8.4' into PHP-8.5

    * PHP-8.4:
      ext/ffi: Hold a reference to the callable of an FFI callback

diff --cc NEWS
index c872634f968,bde051dee66..63ca854c759
--- a/NEWS
+++ b/NEWS
@@@ -27,9 -27,15 +27,13 @@@ PH
    . Fixed Dom\HTMLDocument giving attributes the namespace of their element
      when a fragment is parsed with an xlink, xml or xmlns context element.
      (Ilia Alshanetsky)
 -  . Fixed bug GH-23729 (DOMXPath::__construct() use-after-free during an
 -    evaluation). (David Carlier)
 -  . Fixed bug GH-23897 (php:function() assertion failure after a failed
 -    registerPHPFunctions()). (David Carlier)
 +  . Fixed bug GH-23887 (Dom\HTMLCollection::namedItem() assertion failure,
 +    hang, or missed first element). (Lazizbek Ergashev)

+ - FFI:
+   . Fixed crashes with FFI callbacks created from __call() trampolines
+     and array callables whose object is released. (Ilia Alshanetsky)
+
  - FTP:
    . Fixed bug GH-23619 (cryptic error on servers that don't support TLS
      session resumption on data connection). (ndossche)
diff --cc ext/ffi/ffi.c
index e98b155ebe2,79783441c1d..5ff2c9a1227
--- a/ext/ffi/ffi.c
+++ b/ext/ffi/ffi.c
@@@ -920,10 -923,8 +920,8 @@@ static void zend_ffi_callback_hash_dtor
  	zend_ffi_callback_data *callback_data = Z_PTR_P(zv);

  	ffi_closure_free(callback_data->callback);
- 	if (callback_data->fcc.function_handler->common.fn_flags & ZEND_ACC_CLOSURE) {
- 		OBJ_RELEASE(ZEND_CLOSURE_OBJECT(callback_data->fcc.function_handler));
- 	}
+ 	zend_fcc_dtor(&callback_data->fcc);
 -	for (int i = 0; i < callback_data->arg_count; ++i) {
 +	for (uint32_t i = 0; i < callback_data->arg_count; ++i) {
  		if (callback_data->arg_types[i]->type == FFI_TYPE_STRUCT) {
  			efree(callback_data->arg_types[i]);
  		}
@@@ -962,17 -957,16 +954,14 @@@ static void zend_ffi_callback_trampolin
  		} ZEND_HASH_FOREACH_END();
  	}

- 	ZVAL_UNDEF(&retval);
- 	if (zend_call_function(&fci, &callback_data->fcc) != SUCCESS) {
- 		zend_throw_error(zend_ffi_exception_ce, "Cannot call callback");
- 	}
+ 	zend_call_known_fcc(&callback_data->fcc, &retval, callback_data->arg_count, params, NULL);

  	if (callback_data->arg_count) {
 -		int n = 0;
 -
 -		for (n = 0; n < callback_data->arg_count; n++) {
 +		for (uint32_t n = 0; n < callback_data->arg_count; n++) {
- 			zval_ptr_dtor(&fci.params[n]);
+ 			zval_ptr_dtor(&params[n]);
  		}
  	}
- 	free_alloca(fci.params, use_heap);
+ 	free_alloca(params, use_heap);

  	if (EG(exception)) {
  		zend_error_noreturn(E_ERROR, "Throwing from FFI callbacks is not allowed");