@@ -2970,6 +2970,78 @@ static void zend_opcache_static_cache_publish_context(zend_opcache_static_cache_
29702970 zend_opcache_static_cache_restore_context (previous_context );
29712971}
29722972
2973+ static void zend_opcache_static_cache_capture_decoded_reachable_value_ex (
2974+ zval * value ,
2975+ HashTable * seen_arrays ,
2976+ HashTable * seen_objects
2977+ );
2978+
2979+ static void zend_opcache_static_cache_capture_decoded_hash_values (
2980+ HashTable * values ,
2981+ HashTable * seen_arrays ,
2982+ HashTable * seen_objects
2983+ )
2984+ {
2985+ zval * child , * source_value ;
2986+
2987+ if (values == NULL ) {
2988+ return ;
2989+ }
2990+
2991+ ZEND_HASH_FOREACH_VAL (values , child ) {
2992+ source_value = Z_TYPE_P (child ) == IS_INDIRECT ? Z_INDIRECT_P (child ) : child ;
2993+ if (Z_TYPE_P (source_value ) != IS_UNDEF ) {
2994+ zend_opcache_static_cache_capture_decoded_reachable_value_ex (source_value , seen_arrays , seen_objects );
2995+ }
2996+ } ZEND_HASH_FOREACH_END ();
2997+ }
2998+
2999+ static bool zend_opcache_static_cache_capture_decoded_safe_direct_object (
3000+ zval * value ,
3001+ HashTable * seen_arrays ,
3002+ HashTable * seen_objects
3003+ )
3004+ {
3005+ zend_class_entry * ce , * base_ce = NULL ;
3006+ zend_opcache_static_cache_safe_direct_state_serialize_func_t serialize_func ;
3007+ zval state ;
3008+ HashTable * properties ;
3009+
3010+ ce = Z_OBJCE_P (value );
3011+ base_ce = zend_opcache_serializer_find_safe_direct_cache_base (ce );
3012+ if (base_ce == NULL ||
3013+ zend_opcache_serializer_has_safe_direct_cache_overrides (ce , base_ce )
3014+ ) {
3015+ return false;
3016+ }
3017+
3018+ serialize_func = zend_opcache_static_cache_safe_direct_state_serialize_func (ce );
3019+ if (serialize_func == NULL ) {
3020+ return false;
3021+ }
3022+
3023+ /* Internal safe-direct objects may reject ZEND_PROP_PURPOSE_SERIALIZE
3024+ * because their cache state is exposed through explicit handlers. */
3025+ ZVAL_UNDEF (& state );
3026+ if (serialize_func (value , & state ) && Z_TYPE (state ) == IS_ARRAY ) {
3027+ zend_opcache_static_cache_capture_decoded_hash_values (Z_ARRVAL (state ), seen_arrays , seen_objects );
3028+ }
3029+ if (!Z_ISUNDEF (state )) {
3030+ zval_ptr_dtor (& state );
3031+ }
3032+
3033+ if (EG (exception )) {
3034+ return true;
3035+ }
3036+
3037+ if (!zend_opcache_static_cache_safe_direct_state_includes_properties (ce )) {
3038+ properties = zend_std_get_properties (Z_OBJ_P (value ));
3039+ zend_opcache_static_cache_capture_decoded_hash_values (properties , seen_arrays , seen_objects );
3040+ }
3041+
3042+ return true;
3043+ }
3044+
29733045static void zend_opcache_static_cache_capture_decoded_reachable_value_ex (
29743046 zval * value ,
29753047 HashTable * seen_arrays ,
@@ -3026,6 +3098,10 @@ static void zend_opcache_static_cache_capture_decoded_reachable_value_ex(
30263098 return ;
30273099 }
30283100
3101+ if (zend_opcache_static_cache_capture_decoded_safe_direct_object (value , seen_arrays , seen_objects )) {
3102+ return ;
3103+ }
3104+
30293105 properties = zend_get_properties_for (value , ZEND_PROP_PURPOSE_SERIALIZE );
30303106 if (properties == NULL ) {
30313107 return ;
0 commit comments