@@ -5784,6 +5784,7 @@ void zend_compile_func_decl(znode *result, zend_ast *ast, zend_bool toplevel) /*
5784
5784
zend_ast * return_type_ast = decl -> child [3 ];
5785
5785
zend_bool is_method = decl -> kind == ZEND_AST_METHOD ;
5786
5786
5787
+ zend_class_entry * orig_class_entry = CG (active_class_entry );
5787
5788
zend_op_array * orig_op_array = CG (active_op_array );
5788
5789
zend_op_array * op_array = zend_arena_alloc (& CG (arena ), sizeof (zend_op_array ));
5789
5790
zend_oparray_context orig_oparray_context ;
@@ -5816,6 +5817,13 @@ void zend_compile_func_decl(znode *result, zend_ast *ast, zend_bool toplevel) /*
5816
5817
5817
5818
CG (active_op_array ) = op_array ;
5818
5819
5820
+ /* Do not leak the class scope into free standing functions, even if they are dynamically
5821
+ * defined inside a class method. This is necessary for correct handling of magic constants.
5822
+ * For example __CLASS__ should always be "" inside a free standing function. */
5823
+ if (decl -> kind == ZEND_AST_FUNC_DECL ) {
5824
+ CG (active_class_entry ) = NULL ;
5825
+ }
5826
+
5819
5827
if (toplevel ) {
5820
5828
op_array -> fn_flags |= ZEND_ACC_TOP_LEVEL ;
5821
5829
}
@@ -5863,6 +5871,7 @@ void zend_compile_func_decl(znode *result, zend_ast *ast, zend_bool toplevel) /*
5863
5871
zend_stack_del_top (& CG (loop_var_stack ));
5864
5872
5865
5873
CG (active_op_array ) = orig_op_array ;
5874
+ CG (active_class_entry ) = orig_class_entry ;
5866
5875
}
5867
5876
/* }}} */
5868
5877
@@ -6724,17 +6733,20 @@ static zend_bool zend_try_ct_eval_magic_const(zval *zv, zend_ast *ast) /* {{{ */
6724
6733
}
6725
6734
break ;
6726
6735
case T_METHOD_C :
6727
- if ((op_array && !op_array -> scope && op_array -> function_name ) || (op_array -> fn_flags & ZEND_ACC_CLOSURE )) {
6728
- ZVAL_STR_COPY (zv , op_array -> function_name );
6729
- } else if (ce ) {
6730
- if (op_array && op_array -> function_name ) {
6731
- ZVAL_NEW_STR (zv , zend_concat3 (ZSTR_VAL (ce -> name ), ZSTR_LEN (ce -> name ), "::" , 2 ,
6736
+ /* Detect whether we are directly inside a class (e.g. a class constant) and treat
6737
+ * this as not being inside a function. */
6738
+ if (op_array && ce && !op_array -> scope && !(op_array -> fn_flags & ZEND_ACC_CLOSURE )) {
6739
+ op_array = NULL ;
6740
+ }
6741
+ if (op_array && op_array -> function_name ) {
6742
+ if (op_array -> scope ) {
6743
+ ZVAL_NEW_STR (zv , zend_concat3 (
6744
+ ZSTR_VAL (op_array -> scope -> name ), ZSTR_LEN (op_array -> scope -> name ),
6745
+ "::" , 2 ,
6732
6746
ZSTR_VAL (op_array -> function_name ), ZSTR_LEN (op_array -> function_name )));
6733
6747
} else {
6734
- ZVAL_STR_COPY (zv , ce -> name );
6748
+ ZVAL_STR_COPY (zv , op_array -> function_name );
6735
6749
}
6736
- } else if (op_array && op_array -> function_name ) {
6737
- ZVAL_STR_COPY (zv , op_array -> function_name );
6738
6750
} else {
6739
6751
ZVAL_EMPTY_STRING (zv );
6740
6752
}
0 commit comments