2626#include "zend_closures.h"
2727#include "zend_weakrefs.h"
2828#include "main/SAPI.h"
29+ #include "zend_observer.h"
2930
3031#include <ffi.h>
3132
@@ -5373,6 +5374,25 @@ static zend_result zend_ffi_preload(char *preload) /* {{{ */
53735374}
53745375/* }}} */
53755376
5377+ /* The startup code for observers adds a temporary to each function for internal use.
5378+ * The "new", "cast", and "type" functions in FFI are both static and non-static.
5379+ * Only the static versions are in the function table and the non-static versions are not.
5380+ * This means the non-static versions will be skipped by the observers startup code.
5381+ * This function fixes that by incrementing the temporary count for the non-static versions.
5382+ */
5383+ static zend_result (* prev_zend_post_startup_cb )(void );
5384+ static zend_result ffi_fixup_temporaries (void ) {
5385+ if (ZEND_OBSERVER_ENABLED ) {
5386+ ++ zend_ffi_new_fn .T ;
5387+ ++ zend_ffi_cast_fn .T ;
5388+ ++ zend_ffi_type_fn .T ;
5389+ }
5390+ if (prev_zend_post_startup_cb ) {
5391+ return prev_zend_post_startup_cb ();
5392+ }
5393+ return SUCCESS ;
5394+ }
5395+
53765396/* {{{ ZEND_MINIT_FUNCTION */
53775397ZEND_MINIT_FUNCTION (ffi )
53785398{
@@ -5395,6 +5415,9 @@ ZEND_MINIT_FUNCTION(ffi)
53955415 memcpy (& zend_ffi_type_fn , zend_hash_str_find_ptr (& zend_ffi_ce -> function_table , "type" , sizeof ("type" )- 1 ), sizeof (zend_internal_function ));
53965416 zend_ffi_type_fn .fn_flags &= ~ZEND_ACC_STATIC ;
53975417
5418+ prev_zend_post_startup_cb = zend_post_startup_cb ;
5419+ zend_post_startup_cb = ffi_fixup_temporaries ;
5420+
53985421 memcpy (& zend_ffi_handlers , zend_get_std_object_handlers (), sizeof (zend_object_handlers ));
53995422 zend_ffi_handlers .get_constructor = zend_fake_get_constructor ;
54005423 zend_ffi_handlers .free_obj = zend_ffi_free_obj ;
0 commit comments