@@ -507,6 +507,12 @@ static inline void zai_hook_resolved_install_inherited_internal_function_recursi
507507}
508508
509509static zend_long zai_hook_resolved_install (zai_hook_t * hook , zend_function * resolved , zend_class_entry * ce ) {
510+ // Handle the edge case of inherited internal constructors: They are not fetched from the ce->function_table, but from ce->construct
511+ // Hence we need to explicitly instrument the parents constructor (this will also implicitly instrument the inherited constructor for explicit calls).
512+ if ((resolved -> common .fn_flags & ZEND_ACC_CTOR ) && !ZEND_USER_CODE (resolved -> type ) && resolved -> common .scope -> constructor ) {
513+ resolved = resolved -> common .scope -> constructor ;
514+ }
515+
510516 zai_hooks_entry * hooks = zai_hook_resolved_ensure_hooks_entry (resolved , ce );
511517 zend_long index = zai_hook_add_entry (hooks , hook );
512518
@@ -724,6 +730,12 @@ static inline void zai_hook_resolve(HashTable *base_ht, zend_class_entry *ce, ze
724730 return ;
725731 }
726732
733+ // Handle the edge case of inherited internal constructors: They are not fetched from the ce->function_table, but from ce->construct
734+ // Hence we need to explicitly instrument the parents constructor (this will also implicitly instrument the inherited constructor for explicit calls).
735+ if ((function -> common .fn_flags & ZEND_ACC_CTOR ) && !ZEND_USER_CODE (function -> type ) && function -> common .scope -> constructor ) {
736+ function = function -> common .scope -> constructor ;
737+ }
738+
727739 zai_install_address addr = zai_hook_install_address (function );
728740 if (!zend_hash_index_add_ptr (& zai_hook_resolved , addr , hooks )) {
729741 // it's already there (e.g. thanks to aliases, traits, ...), merge it
@@ -737,6 +749,12 @@ static inline void zai_hook_resolve(HashTable *base_ht, zend_class_entry *ce, ze
737749 existingHooks -> dynamic += hook -> dynamic ;
738750 zend_hash_index_add_new (& existingHooks -> hooks , index , hook_zv );
739751 zai_hook_sort_newest (existingHooks );
752+
753+ if (hook -> is_abstract ) {
754+ zai_hook_resolved_install_abstract_recursive (hook , (zend_ulong )index , function -> common .scope );
755+ } else if (!ZEND_USER_CODE (function -> type ) && function -> common .scope ) {
756+ zai_hook_resolved_install_inherited_internal_function_recursive (hook , (zend_ulong )index , function -> common .scope , function -> internal_function .handler );
757+ }
740758 } ZEND_HASH_FOREACH_END ();
741759
742760 // we remove the whole zai_hooks_entry, excluding the individual zai_hook_t which we moved
@@ -755,9 +773,16 @@ static inline void zai_hook_resolve(HashTable *base_ht, zend_class_entry *ce, ze
755773 base_ht -> pDestructor = zai_hook_hash_destroy ;
756774 zai_hook_resolve_hooks_entry (hooks , function );
757775 zai_hook_t * hook ;
758- ZEND_HASH_FOREACH_PTR (& hooks -> hooks , hook ) {
776+ zend_ulong index ;
777+ ZEND_HASH_FOREACH_NUM_KEY_PTR (& hooks -> hooks , index , hook ) {
759778 hook -> resolved_scope = ce ;
760779 hook -> is_abstract = is_abstract ;
780+
781+ if (hook -> is_abstract ) {
782+ zai_hook_resolved_install_abstract_recursive (hook , (zend_ulong )index , function -> common .scope );
783+ } else if (!ZEND_USER_CODE (function -> type ) && function -> common .scope ) {
784+ zai_hook_resolved_install_inherited_internal_function_recursive (hook , (zend_ulong )index , function -> common .scope , function -> internal_function .handler );
785+ }
761786 } ZEND_HASH_FOREACH_END ();
762787 }
763788 }
0 commit comments