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.
This commit is contained in:
Nikita Popov 2021-07-23 11:17:29 +02:00
parent 760ff841a1
commit dfd05da97f
3 changed files with 51 additions and 0 deletions

2
NEWS
View file

@ -4,6 +4,8 @@ PHP NEWS
- Core:
. Fixed bug #72595 (php_output_handler_append illegal write access). (cmb)
. Fixed bug #66719 (Weird behaviour when using get_called_class() with
call_user_func()). (Nikita)
- BCMath:
. Fixed bug #78238 (BCMath returns "-0"). (cmb)

43
Zend/tests/bug66719.phpt Normal file
View file

@ -0,0 +1,43 @@
--TEST--
Bug #66719: Weird behaviour when using get_called_class() with call_user_func()
--FILE--
<?php
class A
{
public static function who()
{
var_dump(get_called_class());
}
}
class B extends A
{
public static function who()
{
parent::who();
}
}
class C
{
public static function test() {
B::who();
call_user_func(array(A::class, 'who'));
call_user_func(array(B::class, 'parent::who'));
}
}
B::who();
call_user_func(array(A::class, 'who'));
call_user_func(array(B::class, 'parent::who'));
C::test();
?>
--EXPECT--
string(1) "B"
string(1) "A"
string(1) "A"
string(1) "B"
string(1) "A"
string(1) "A"

View file

@ -2922,6 +2922,9 @@ static int zend_is_callable_check_class(zend_string *name, zend_class_entry *sco
if (error) *error = estrdup("cannot access self:: when no class scope is active");
} else {
fcc->called_scope = zend_get_called_scope(EG(current_execute_data));
if (!fcc->called_scope || !instanceof_function(fcc->called_scope, scope)) {
fcc->called_scope = scope;
}
fcc->calling_scope = scope;
if (!fcc->object) {
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
if (error) *error = estrdup("cannot access parent:: when current class scope has no parent");
} else {
fcc->called_scope = zend_get_called_scope(EG(current_execute_data));
if (!fcc->called_scope || !instanceof_function(fcc->called_scope, scope->parent)) {
fcc->called_scope = scope->parent;
}
fcc->calling_scope = scope->parent;
if (!fcc->object) {
fcc->object = zend_get_this_object(EG(current_execute_data));