@@ -5737,6 +5737,7 @@ void zend_compile_func_decl(znode *result, zend_ast *ast, zend_bool toplevel) /*
5737
5737
zend_ast * return_type_ast = decl -> child [3 ];
5738
5738
zend_bool is_method = decl -> kind == ZEND_AST_METHOD ;
5739
5739
5740
+ zend_class_entry * orig_class_entry = CG (active_class_entry );
5740
5741
zend_op_array * orig_op_array = CG (active_op_array );
5741
5742
zend_op_array * op_array = zend_arena_alloc (& CG (arena ), sizeof (zend_op_array ));
5742
5743
zend_oparray_context orig_oparray_context ;
@@ -5769,6 +5770,13 @@ void zend_compile_func_decl(znode *result, zend_ast *ast, zend_bool toplevel) /*
5769
5770
5770
5771
CG (active_op_array ) = op_array ;
5771
5772
5773
+ /* Do not leak the class scope into free standing functions, even if they are dynamically
5774
+ * defined inside a class method. This is necessary for correct handling of magic constants.
5775
+ * For example __CLASS__ should always be "" inside a free standing function. */
5776
+ if (decl -> kind == ZEND_AST_FUNC_DECL ) {
5777
+ CG (active_class_entry ) = NULL ;
5778
+ }
5779
+
5772
5780
if (toplevel ) {
5773
5781
op_array -> fn_flags |= ZEND_ACC_TOP_LEVEL ;
5774
5782
}
@@ -5816,6 +5824,7 @@ void zend_compile_func_decl(znode *result, zend_ast *ast, zend_bool toplevel) /*
5816
5824
zend_stack_del_top (& CG (loop_var_stack ));
5817
5825
5818
5826
CG (active_op_array ) = orig_op_array ;
5827
+ CG (active_class_entry ) = orig_class_entry ;
5819
5828
}
5820
5829
/* }}} */
5821
5830
@@ -6672,17 +6681,20 @@ static zend_bool zend_try_ct_eval_magic_const(zval *zv, zend_ast *ast) /* {{{ */
6672
6681
}
6673
6682
break ;
6674
6683
case T_METHOD_C :
6675
- if ((op_array && !op_array -> scope && op_array -> function_name ) || (op_array -> fn_flags & ZEND_ACC_CLOSURE )) {
6676
- ZVAL_STR_COPY (zv , op_array -> function_name );
6677
- } else if (ce ) {
6678
- if (op_array && op_array -> function_name ) {
6679
- ZVAL_NEW_STR (zv , zend_concat3 (ZSTR_VAL (ce -> name ), ZSTR_LEN (ce -> name ), "::" , 2 ,
6684
+ /* Detect whether we are directly inside a class (e.g. a class constant) and treat
6685
+ * this as not being inside a function. */
6686
+ if (op_array && ce && !op_array -> scope && !(op_array -> fn_flags & ZEND_ACC_CLOSURE )) {
6687
+ op_array = NULL ;
6688
+ }
6689
+ if (op_array && op_array -> function_name ) {
6690
+ if (op_array -> scope ) {
6691
+ ZVAL_NEW_STR (zv , zend_concat3 (
6692
+ ZSTR_VAL (op_array -> scope -> name ), ZSTR_LEN (op_array -> scope -> name ),
6693
+ "::" , 2 ,
6680
6694
ZSTR_VAL (op_array -> function_name ), ZSTR_LEN (op_array -> function_name )));
6681
6695
} else {
6682
- ZVAL_STR_COPY (zv , ce -> name );
6696
+ ZVAL_STR_COPY (zv , op_array -> function_name );
6683
6697
}
6684
- } else if (op_array && op_array -> function_name ) {
6685
- ZVAL_STR_COPY (zv , op_array -> function_name );
6686
6698
} else {
6687
6699
ZVAL_EMPTY_STRING (zv );
6688
6700
}
0 commit comments