Skip to content

Commit 8afa2c6

Browse files
committed
Merge branch 'PHP-7.4'
2 parents e683c18 + 9364153 commit 8afa2c6

File tree

3 files changed

+43
-9
lines changed

3 files changed

+43
-9
lines changed

Zend/tests/bug76430.phpt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
Bug #76430: __METHOD__ inconsistent outside of method
3+
--FILE--
4+
<?php
5+
6+
class Foo {
7+
const X = __METHOD__;
8+
}
9+
function foo() {
10+
class Bar {
11+
const X = __METHOD__;
12+
}
13+
}
14+
15+
foo();
16+
var_dump(Foo::X);
17+
var_dump(Bar::X);
18+
19+
?>
20+
--EXPECT--
21+
string(0) ""
22+
string(0) ""

Zend/tests/nested_method_and_function.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ $c();
3030
--EXPECT--
3131
string(7) "Baz\foo"
3232
string(7) "Baz\foo"
33-
string(7) "Baz\Foo"
33+
string(0) ""
3434
string(3) "bar"
3535
string(12) "Baz\Foo::bar"
3636
string(7) "Baz\Foo"

Zend/zend_compile.c

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5737,6 +5737,7 @@ void zend_compile_func_decl(znode *result, zend_ast *ast, zend_bool toplevel) /*
57375737
zend_ast *return_type_ast = decl->child[3];
57385738
zend_bool is_method = decl->kind == ZEND_AST_METHOD;
57395739

5740+
zend_class_entry *orig_class_entry = CG(active_class_entry);
57405741
zend_op_array *orig_op_array = CG(active_op_array);
57415742
zend_op_array *op_array = zend_arena_alloc(&CG(arena), sizeof(zend_op_array));
57425743
zend_oparray_context orig_oparray_context;
@@ -5769,6 +5770,13 @@ void zend_compile_func_decl(znode *result, zend_ast *ast, zend_bool toplevel) /*
57695770

57705771
CG(active_op_array) = op_array;
57715772

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+
57725780
if (toplevel) {
57735781
op_array->fn_flags |= ZEND_ACC_TOP_LEVEL;
57745782
}
@@ -5816,6 +5824,7 @@ void zend_compile_func_decl(znode *result, zend_ast *ast, zend_bool toplevel) /*
58165824
zend_stack_del_top(&CG(loop_var_stack));
58175825

58185826
CG(active_op_array) = orig_op_array;
5827+
CG(active_class_entry) = orig_class_entry;
58195828
}
58205829
/* }}} */
58215830

@@ -6672,17 +6681,20 @@ static zend_bool zend_try_ct_eval_magic_const(zval *zv, zend_ast *ast) /* {{{ */
66726681
}
66736682
break;
66746683
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,
66806694
ZSTR_VAL(op_array->function_name), ZSTR_LEN(op_array->function_name)));
66816695
} else {
6682-
ZVAL_STR_COPY(zv, ce->name);
6696+
ZVAL_STR_COPY(zv, op_array->function_name);
66836697
}
6684-
} else if (op_array && op_array->function_name) {
6685-
ZVAL_STR_COPY(zv, op_array->function_name);
66866698
} else {
66876699
ZVAL_EMPTY_STRING(zv);
66886700
}

0 commit comments

Comments
 (0)