Skip to content

Commit dfd05da

Browse files
committed
Fix bug #66719
While parent:: should inherit the called scope, it should only do so if it is compatible. If there is no called scope, or it is not a subtype of the scope, we should fall back to the scope.
1 parent 760ff84 commit dfd05da

File tree

3 files changed

+51
-0
lines changed

3 files changed

+51
-0
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ PHP NEWS
44

55
- Core:
66
. Fixed bug #72595 (php_output_handler_append illegal write access). (cmb)
7+
. Fixed bug #66719 (Weird behaviour when using get_called_class() with
8+
call_user_func()). (Nikita)
79

810
- BCMath:
911
. Fixed bug #78238 (BCMath returns "-0"). (cmb)

Zend/tests/bug66719.phpt

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
--TEST--
2+
Bug #66719: Weird behaviour when using get_called_class() with call_user_func()
3+
--FILE--
4+
<?php
5+
6+
class A
7+
{
8+
public static function who()
9+
{
10+
var_dump(get_called_class());
11+
}
12+
}
13+
class B extends A
14+
{
15+
public static function who()
16+
{
17+
parent::who();
18+
}
19+
}
20+
21+
class C
22+
{
23+
public static function test() {
24+
B::who();
25+
call_user_func(array(A::class, 'who'));
26+
call_user_func(array(B::class, 'parent::who'));
27+
}
28+
}
29+
30+
B::who();
31+
call_user_func(array(A::class, 'who'));
32+
call_user_func(array(B::class, 'parent::who'));
33+
34+
C::test();
35+
36+
?>
37+
--EXPECT--
38+
string(1) "B"
39+
string(1) "A"
40+
string(1) "A"
41+
string(1) "B"
42+
string(1) "A"
43+
string(1) "A"

Zend/zend_API.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2922,6 +2922,9 @@ static int zend_is_callable_check_class(zend_string *name, zend_class_entry *sco
29222922
if (error) *error = estrdup("cannot access self:: when no class scope is active");
29232923
} else {
29242924
fcc->called_scope = zend_get_called_scope(EG(current_execute_data));
2925+
if (!fcc->called_scope || !instanceof_function(fcc->called_scope, scope)) {
2926+
fcc->called_scope = scope;
2927+
}
29252928
fcc->calling_scope = scope;
29262929
if (!fcc->object) {
29272930
fcc->object = zend_get_this_object(EG(current_execute_data));
@@ -2935,6 +2938,9 @@ static int zend_is_callable_check_class(zend_string *name, zend_class_entry *sco
29352938
if (error) *error = estrdup("cannot access parent:: when current class scope has no parent");
29362939
} else {
29372940
fcc->called_scope = zend_get_called_scope(EG(current_execute_data));
2941+
if (!fcc->called_scope || !instanceof_function(fcc->called_scope, scope->parent)) {
2942+
fcc->called_scope = scope->parent;
2943+
}
29382944
fcc->calling_scope = scope->parent;
29392945
if (!fcc->object) {
29402946
fcc->object = zend_get_this_object(EG(current_execute_data));

0 commit comments

Comments
 (0)