@@ -43,6 +43,8 @@ static void zend_check_generic_link_bounds(
4343static void zend_substitute_trait_method_arg_info (
4444 zend_function * new_fn , const zend_function * orig_fn ,
4545 const zend_type * bind_args , uint32_t bind_arity );
46+ static zend_arg_info * zend_clone_arg_info_block (
47+ const zend_arg_info * orig_block , uint32_t total );
4648
4749/* Unresolved means that class declarations that are currently not available are needed to
4850 * determine whether the inheritance is valid or not. At runtime UNRESOLVED should be treated
@@ -2008,20 +2010,8 @@ static void do_inherit_property(zend_property_info *parent_info, zend_string *ke
20082010 uint32_t num_args = orig -> op_array .num_args ;
20092011 if (orig -> op_array .fn_flags & ZEND_ACC_VARIADIC ) num_args ++ ;
20102012 uint32_t total = num_args + 1 ;
2011- size_t arg_info_block = sizeof (zend_arg_info ) * total ;
20122013
2013- zend_arg_info * new_arg_info = zend_arena_alloc (& CG (arena ), arg_info_block );
2014- memcpy (new_arg_info , orig -> op_array .arg_info - 1 , arg_info_block );
2015-
2016- for (uint32_t i = 0 ; i < total ; i ++ ) {
2017- if (new_arg_info [i ].name ) {
2018- zend_string_addref (new_arg_info [i ].name );
2019- }
2020-
2021- if (new_arg_info [i ].doc_comment ) {
2022- zend_string_addref (new_arg_info [i ].doc_comment );
2023- }
2024- }
2014+ zend_arg_info * new_arg_info = zend_clone_arg_info_block (orig -> op_array .arg_info - 1 , total );
20252015
20262016 uint32_t slot = (hi == ZEND_PROPERTY_HOOK_GET ) ? 0 : 1 ;
20272017 new_arg_info [slot ].type = sub ;
@@ -2864,6 +2854,23 @@ static const zend_type_named_with_args *zend_find_trait_use_binding_by_name(
28642854 return NULL ;
28652855}
28662856
2857+ static zend_arg_info * zend_clone_arg_info_block (const zend_arg_info * orig_block , uint32_t total )
2858+ {
2859+ zend_arg_info * new_block = zend_arena_alloc (& CG (arena ), sizeof (zend_arg_info ) * total );
2860+ memcpy (new_block , orig_block , sizeof (zend_arg_info ) * total );
2861+ for (uint32_t i = 0 ; i < total ; i ++ ) {
2862+ if (new_block [i ].name ) {
2863+ zend_string_addref (new_block [i ].name );
2864+ }
2865+
2866+ if (new_block [i ].doc_comment ) {
2867+ zend_string_addref (new_block [i ].doc_comment );
2868+ }
2869+ }
2870+
2871+ return new_block ;
2872+ }
2873+
28672874static void zend_substitute_trait_method_arg_info (
28682875 zend_function * new_fn , const zend_function * orig_fn ,
28692876 const zend_type * bind_args , uint32_t bind_arity )
@@ -2887,19 +2894,7 @@ static void zend_substitute_trait_method_arg_info(
28872894 }
28882895
28892896 const zend_arg_info * orig_block = has_return ? orig_op -> arg_info - 1 : orig_op -> arg_info ;
2890- zend_arg_info * new_block = zend_arena_alloc (& CG (arena ), sizeof (zend_arg_info ) * total );
2891- memcpy (new_block , orig_block , sizeof (zend_arg_info ) * total );
2892-
2893- /* The clone shares name/doc_comment string pointers with the parent's arg_info; bump refcount
2894- * so opcache's interning pass on the parent doesn't release strings the clone still references. */
2895- for (uint32_t i = 0 ; i < total ; i ++ ) {
2896- if (new_block [i ].name ) {
2897- zend_string_addref (new_block [i ].name );
2898- }
2899- if (new_block [i ].doc_comment ) {
2900- zend_string_addref (new_block [i ].doc_comment );
2901- }
2902- }
2897+ zend_arg_info * new_block = zend_clone_arg_info_block (orig_block , total );
29032898
29042899 uint32_t return_slot_offset = has_return ? 1 : 0 ;
29052900
0 commit comments