@@ -2764,101 +2764,113 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
2764
2764
#endif
2765
2765
2766
2766
bool orig_record_errors = EG (record_errors );
2767
- if (ce -> ce_flags & ZEND_ACC_IMMUTABLE ) {
2768
- if (is_cacheable ) {
2769
- if (zend_inheritance_cache_get && zend_inheritance_cache_add ) {
2770
- zend_class_entry * ret = zend_inheritance_cache_get (ce , parent , traits_and_interfaces );
2771
- if (ret ) {
2772
- if (traits_and_interfaces ) {
2773
- free_alloca (traits_and_interfaces , use_heap );
2774
- }
2775
- zv = zend_hash_find_known_hash (CG (class_table ), key );
2776
- Z_CE_P (zv ) = ret ;
2777
- return ret ;
2778
- }
2779
2767
2780
- /* Make sure warnings (such as deprecations) thrown during inheritance
2781
- * will be recoreded in the inheritance cache. */
2782
- zend_begin_record_errors ();
2783
- } else {
2784
- is_cacheable = 0 ;
2768
+ if (ce -> ce_flags & ZEND_ACC_IMMUTABLE && is_cacheable ) {
2769
+ if (zend_inheritance_cache_get && zend_inheritance_cache_add ) {
2770
+ zend_class_entry * ret = zend_inheritance_cache_get (ce , parent , traits_and_interfaces );
2771
+ if (ret ) {
2772
+ if (traits_and_interfaces ) {
2773
+ free_alloca (traits_and_interfaces , use_heap );
2774
+ }
2775
+ zv = zend_hash_find_known_hash (CG (class_table ), key );
2776
+ Z_CE_P (zv ) = ret ;
2777
+ return ret ;
2785
2778
}
2786
- proto = ce ;
2779
+
2780
+ /* Make sure warnings (such as deprecations) thrown during inheritance
2781
+ * will be recorded in the inheritance cache. */
2782
+ zend_begin_record_errors ();
2783
+ } else {
2784
+ is_cacheable = 0 ;
2787
2785
}
2788
- /* Lazy class loading */
2789
- ce = zend_lazy_class_load (ce );
2790
- zv = zend_hash_find_known_hash (CG (class_table ), key );
2791
- Z_CE_P (zv ) = ce ;
2792
- } else if (ce -> ce_flags & ZEND_ACC_FILE_CACHED ) {
2793
- /* Lazy class loading */
2794
- ce = zend_lazy_class_load (ce );
2795
- ce -> ce_flags &= ~ZEND_ACC_FILE_CACHED ;
2796
- zv = zend_hash_find_known_hash (CG (class_table ), key );
2797
- Z_CE_P (zv ) = ce ;
2786
+ proto = ce ;
2798
2787
}
2799
2788
2800
- if (CG (unlinked_uses )) {
2801
- zend_hash_index_del (CG (unlinked_uses ), (zend_long )(zend_uintptr_t ) ce );
2802
- }
2789
+ zend_try {
2790
+ if (ce -> ce_flags & ZEND_ACC_IMMUTABLE ) {
2791
+ /* Lazy class loading */
2792
+ ce = zend_lazy_class_load (ce );
2793
+ zv = zend_hash_find_known_hash (CG (class_table ), key );
2794
+ Z_CE_P (zv ) = ce ;
2795
+ } else if (ce -> ce_flags & ZEND_ACC_FILE_CACHED ) {
2796
+ /* Lazy class loading */
2797
+ ce = zend_lazy_class_load (ce );
2798
+ ce -> ce_flags &= ~ZEND_ACC_FILE_CACHED ;
2799
+ zv = zend_hash_find_known_hash (CG (class_table ), key );
2800
+ Z_CE_P (zv ) = ce ;
2801
+ }
2803
2802
2804
- orig_linking_class = CG (current_linking_class );
2805
- CG (current_linking_class ) = is_cacheable ? ce : NULL ;
2803
+ if (CG (unlinked_uses )) {
2804
+ zend_hash_index_del (CG (unlinked_uses ), (zend_long )(zend_uintptr_t ) ce );
2805
+ }
2806
2806
2807
- if (ce -> ce_flags & ZEND_ACC_ENUM ) {
2808
- /* Only register builtin enum methods during inheritance to avoid persisting them in
2809
- * opcache. */
2810
- zend_enum_register_funcs (ce );
2811
- }
2807
+ orig_linking_class = CG (current_linking_class );
2808
+ CG (current_linking_class ) = is_cacheable ? ce : NULL ;
2812
2809
2813
- if (parent ) {
2814
- if (!(parent -> ce_flags & ZEND_ACC_LINKED )) {
2815
- add_dependency_obligation (ce , parent );
2810
+ if (ce -> ce_flags & ZEND_ACC_ENUM ) {
2811
+ /* Only register builtin enum methods during inheritance to avoid persisting them in
2812
+ * opcache. */
2813
+ zend_enum_register_funcs (ce );
2816
2814
}
2817
- zend_do_inheritance (ce , parent );
2818
- }
2819
- if (ce -> num_traits ) {
2820
- zend_do_bind_traits (ce , traits_and_interfaces );
2821
- }
2822
- if (ce -> num_interfaces ) {
2823
- /* Also copy the parent interfaces here, so we don't need to reallocate later. */
2824
- uint32_t num_parent_interfaces = parent ? parent -> num_interfaces : 0 ;
2825
- zend_class_entry * * interfaces = emalloc (
2826
- sizeof (zend_class_entry * ) * (ce -> num_interfaces + num_parent_interfaces ));
2827
2815
2828
- if (num_parent_interfaces ) {
2829
- memcpy (interfaces , parent -> interfaces ,
2830
- sizeof (zend_class_entry * ) * num_parent_interfaces );
2816
+ if (parent ) {
2817
+ if (!(parent -> ce_flags & ZEND_ACC_LINKED )) {
2818
+ add_dependency_obligation (ce , parent );
2819
+ }
2820
+ zend_do_inheritance (ce , parent );
2821
+ }
2822
+ if (ce -> num_traits ) {
2823
+ zend_do_bind_traits (ce , traits_and_interfaces );
2831
2824
}
2832
- memcpy (interfaces + num_parent_interfaces , traits_and_interfaces + ce -> num_traits ,
2833
- sizeof (zend_class_entry * ) * ce -> num_interfaces );
2825
+ if (ce -> num_interfaces ) {
2826
+ /* Also copy the parent interfaces here, so we don't need to reallocate later. */
2827
+ uint32_t num_parent_interfaces = parent ? parent -> num_interfaces : 0 ;
2828
+ zend_class_entry * * interfaces = emalloc (
2829
+ sizeof (zend_class_entry * ) * (ce -> num_interfaces + num_parent_interfaces ));
2834
2830
2835
- zend_do_implement_interfaces (ce , interfaces );
2836
- } else if (parent && parent -> num_interfaces ) {
2837
- zend_do_inherit_interfaces (ce , parent );
2838
- }
2839
- if (!(ce -> ce_flags & (ZEND_ACC_INTERFACE |ZEND_ACC_TRAIT ))
2840
- && (ce -> ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS |ZEND_ACC_EXPLICIT_ABSTRACT_CLASS ))
2841
- ) {
2842
- zend_verify_abstract_class (ce );
2843
- }
2844
- if (ce -> ce_flags & ZEND_ACC_ENUM ) {
2845
- zend_verify_enum (ce );
2846
- }
2831
+ if (num_parent_interfaces ) {
2832
+ memcpy (interfaces , parent -> interfaces ,
2833
+ sizeof (zend_class_entry * ) * num_parent_interfaces );
2834
+ }
2835
+ memcpy (interfaces + num_parent_interfaces , traits_and_interfaces + ce -> num_traits ,
2836
+ sizeof (zend_class_entry * ) * ce -> num_interfaces );
2847
2837
2848
- /* Normally Stringable is added during compilation. However, if it is imported from a trait,
2849
- * we need to explicilty add the interface here. */
2850
- if (ce -> __tostring && !(ce -> ce_flags & ZEND_ACC_TRAIT )
2838
+ zend_do_implement_interfaces (ce , interfaces );
2839
+ } else if (parent && parent -> num_interfaces ) {
2840
+ zend_do_inherit_interfaces (ce , parent );
2841
+ }
2842
+ if (!(ce -> ce_flags & (ZEND_ACC_INTERFACE |ZEND_ACC_TRAIT ))
2843
+ && (ce -> ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS |ZEND_ACC_EXPLICIT_ABSTRACT_CLASS ))
2844
+ ) {
2845
+ zend_verify_abstract_class (ce );
2846
+ }
2847
+ if (ce -> ce_flags & ZEND_ACC_ENUM ) {
2848
+ zend_verify_enum (ce );
2849
+ }
2850
+
2851
+ /* Normally Stringable is added during compilation. However, if it is imported from a trait,
2852
+ * we need to explicilty add the interface here. */
2853
+ if (ce -> __tostring && !(ce -> ce_flags & ZEND_ACC_TRAIT )
2851
2854
&& !zend_class_implements_interface (ce , zend_ce_stringable )) {
2852
- ZEND_ASSERT (ce -> __tostring -> common .fn_flags & ZEND_ACC_TRAIT_CLONE );
2853
- ce -> ce_flags |= ZEND_ACC_RESOLVED_INTERFACES ;
2854
- ce -> num_interfaces ++ ;
2855
- ce -> interfaces = perealloc (ce -> interfaces ,
2856
- sizeof (zend_class_entry * ) * ce -> num_interfaces , ce -> type == ZEND_INTERNAL_CLASS );
2857
- ce -> interfaces [ce -> num_interfaces - 1 ] = zend_ce_stringable ;
2858
- do_interface_implementation (ce , zend_ce_stringable );
2859
- }
2855
+ ZEND_ASSERT (ce -> __tostring -> common .fn_flags & ZEND_ACC_TRAIT_CLONE );
2856
+ ce -> ce_flags |= ZEND_ACC_RESOLVED_INTERFACES ;
2857
+ ce -> num_interfaces ++ ;
2858
+ ce -> interfaces = perealloc (ce -> interfaces ,
2859
+ sizeof (zend_class_entry * ) * ce -> num_interfaces , ce -> type == ZEND_INTERNAL_CLASS );
2860
+ ce -> interfaces [ce -> num_interfaces - 1 ] = zend_ce_stringable ;
2861
+ do_interface_implementation (ce , zend_ce_stringable );
2862
+ }
2863
+
2864
+ zend_build_properties_info_table (ce );
2865
+ } zend_catch {
2866
+ /* Do not leak recorded errors to the next linked class. */
2867
+ if (!orig_record_errors ) {
2868
+ EG (record_errors ) = false;
2869
+ zend_free_recorded_errors ();
2870
+ }
2871
+ zend_bailout ();
2872
+ } zend_end_try ();
2860
2873
2861
- zend_build_properties_info_table (ce );
2862
2874
EG (record_errors ) = orig_record_errors ;
2863
2875
2864
2876
if (!(ce -> ce_flags & ZEND_ACC_UNRESOLVED_VARIANCE )) {
@@ -3027,22 +3039,29 @@ ZEND_API zend_class_entry *zend_try_early_bind(zend_class_entry *ce, zend_class_
3027
3039
orig_linking_class = CG (current_linking_class );
3028
3040
CG (current_linking_class ) = is_cacheable ? ce : NULL ;
3029
3041
3030
- if (is_cacheable ) {
3031
- zend_begin_record_errors ();
3032
- }
3042
+ zend_try {
3043
+ if (is_cacheable ) {
3044
+ zend_begin_record_errors ();
3045
+ }
3033
3046
3034
- zend_do_inheritance_ex (ce , parent_ce , status == INHERITANCE_SUCCESS );
3035
- if (parent_ce && parent_ce -> num_interfaces ) {
3036
- zend_do_inherit_interfaces (ce , parent_ce );
3037
- }
3038
- zend_build_properties_info_table (ce );
3039
- if ((ce -> ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS |ZEND_ACC_INTERFACE |ZEND_ACC_TRAIT |ZEND_ACC_EXPLICIT_ABSTRACT_CLASS )) == ZEND_ACC_IMPLICIT_ABSTRACT_CLASS ) {
3040
- zend_verify_abstract_class (ce );
3041
- }
3042
- ZEND_ASSERT (!(ce -> ce_flags & ZEND_ACC_UNRESOLVED_VARIANCE ));
3043
- ce -> ce_flags |= ZEND_ACC_LINKED ;
3047
+ zend_do_inheritance_ex (ce , parent_ce , status == INHERITANCE_SUCCESS );
3048
+ if (parent_ce && parent_ce -> num_interfaces ) {
3049
+ zend_do_inherit_interfaces (ce , parent_ce );
3050
+ }
3051
+ zend_build_properties_info_table (ce );
3052
+ if ((ce -> ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS |ZEND_ACC_INTERFACE |ZEND_ACC_TRAIT |ZEND_ACC_EXPLICIT_ABSTRACT_CLASS )) == ZEND_ACC_IMPLICIT_ABSTRACT_CLASS ) {
3053
+ zend_verify_abstract_class (ce );
3054
+ }
3055
+ ZEND_ASSERT (!(ce -> ce_flags & ZEND_ACC_UNRESOLVED_VARIANCE ));
3056
+ ce -> ce_flags |= ZEND_ACC_LINKED ;
3057
+
3058
+ CG (current_linking_class ) = orig_linking_class ;
3059
+ } zend_catch {
3060
+ EG (record_errors ) = false;
3061
+ zend_free_recorded_errors ();
3062
+ zend_bailout ();
3063
+ } zend_end_try ();
3044
3064
3045
- CG (current_linking_class ) = orig_linking_class ;
3046
3065
EG (record_errors ) = false;
3047
3066
3048
3067
if (is_cacheable ) {
0 commit comments