mirror of
https://github.com/php/php-src.git
synced 2024-09-23 10:57:26 +00:00
Fixed bug #38772 (inconsistent overriding of methods in different visibility contexts)
This commit is contained in:
parent
a98f411f80
commit
5574651edb
42
Zend/tests/bug38772.phpt
Executable file
42
Zend/tests/bug38772.phpt
Executable file
@ -0,0 +1,42 @@
|
||||
--TEST--
|
||||
Bug #38772 (inconsistent overriding of methods in different visibility contexts)
|
||||
--FILE--
|
||||
<?php
|
||||
class A {
|
||||
|
||||
public function __construct() {
|
||||
$this -> foo();
|
||||
}
|
||||
|
||||
private function foo() {
|
||||
echo __METHOD__ . "\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
public function foo() {
|
||||
echo __METHOD__ . "\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
class C extends A {
|
||||
protected function foo() {
|
||||
echo __METHOD__ . "\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
class D extends A {
|
||||
private function foo() {
|
||||
echo __METHOD__ . "\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
$a = new A();
|
||||
$b = new B();
|
||||
$c = new C();
|
||||
$d = new D();
|
||||
--EXPECT--
|
||||
A::foo
|
||||
A::foo
|
||||
A::foo
|
||||
A::foo
|
@ -2160,7 +2160,9 @@ static zend_bool do_inherit_method_check(HashTable *child_function_table, zend_f
|
||||
}
|
||||
}
|
||||
|
||||
if (parent_flags & ZEND_ACC_ABSTRACT) {
|
||||
if (parent_flags & ZEND_ACC_PRIVATE) {
|
||||
child->common.prototype = NULL;
|
||||
} else if (parent_flags & ZEND_ACC_ABSTRACT) {
|
||||
child->common.fn_flags |= ZEND_ACC_IMPLEMENTED_ABSTRACT;
|
||||
child->common.prototype = parent;
|
||||
} else if (!(parent->common.fn_flags & ZEND_ACC_CTOR) || (parent->common.prototype && (parent->common.prototype->common.scope->ce_flags & ZEND_ACC_INTERFACE))) {
|
||||
|
@ -798,7 +798,17 @@ static union _zend_function *zend_std_get_method(zval **object_ptr, zstr method_
|
||||
}
|
||||
|
||||
/* Check access level */
|
||||
if (fbc->op_array.fn_flags & ZEND_ACC_PUBLIC) {
|
||||
if (fbc->op_array.fn_flags & ZEND_ACC_PRIVATE) {
|
||||
zend_function *updated_fbc;
|
||||
|
||||
/* Ensure that if we're calling a private function, we're allowed to do so.
|
||||
*/
|
||||
updated_fbc = zend_check_private_int(fbc, Z_OBJ_HANDLER_P(object, get_class_entry)(object TSRMLS_CC), lc_method_name, method_len TSRMLS_CC);
|
||||
if (!updated_fbc) {
|
||||
zend_error(E_ERROR, "Call to %s method %v::%v() from context '%v'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), method_name, EG(scope) ? EG(scope)->name : EMPTY_ZSTR);
|
||||
}
|
||||
fbc = updated_fbc;
|
||||
} else {
|
||||
/* Ensure that we haven't overridden a private function and end up calling
|
||||
* the overriding public function...
|
||||
*/
|
||||
@ -811,23 +821,14 @@ static union _zend_function *zend_std_get_method(zval **object_ptr, zstr method_
|
||||
fbc = priv_fbc;
|
||||
}
|
||||
}
|
||||
} else if (fbc->op_array.fn_flags & ZEND_ACC_PRIVATE) {
|
||||
zend_function *updated_fbc;
|
||||
|
||||
/* Ensure that if we're calling a private function, we're allowed to do so.
|
||||
*/
|
||||
updated_fbc = zend_check_private_int(fbc, Z_OBJ_HANDLER_P(object, get_class_entry)(object TSRMLS_CC), lc_method_name, method_len TSRMLS_CC);
|
||||
if (!updated_fbc) {
|
||||
zend_error(E_ERROR, "Call to %s method %v::%v() from context '%v'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), method_name, EG(scope) ? EG(scope)->name : EMPTY_ZSTR);
|
||||
}
|
||||
fbc = updated_fbc;
|
||||
} else if ((fbc->common.fn_flags & ZEND_ACC_PROTECTED)) {
|
||||
if ((fbc->common.fn_flags & ZEND_ACC_PROTECTED)) {
|
||||
/* Ensure that if we're calling a protected function, we're allowed to do so.
|
||||
*/
|
||||
if (!zend_check_protected(zend_get_function_root_class(fbc), EG(scope))) {
|
||||
zend_error(E_ERROR, "Call to %s method %v::%v() from context '%v'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), method_name, EG(scope) ? EG(scope)->name : EMPTY_ZSTR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
efree(lc_method_name.v);
|
||||
return fbc;
|
||||
|
Loading…
Reference in New Issue
Block a user