Browse Source

Fixed bug #38772 (inconsistent overriding of methods in different visibility contexts)

PECL_OPENSSL
Dmitry Stogov 20 years ago
parent
commit
7e17f8591a
  1. 2
      NEWS
  2. 42
      Zend/tests/bug38772.phpt
  3. 4
      Zend/zend_compile.c
  4. 33
      Zend/zend_object_handlers.c

2
NEWS

@ -7,6 +7,8 @@
readded it for other SAPIs (restore to pre 5.1.x behavior). (Edin)
- Fixed bug #38779 (engine crashes when require()'ing file with syntax error
through userspace stream wrapper). (Tony, Dmitry)
- Fixed bug #38772 (inconsistent overriding of methods in different visibility
contexts). (Dmitry)
- Fixed bug #38759 (PDO sqlite2 empty query causes segfault). (Tony)
- Fixed bug #38721 (Invalid memory read in date_parse()). (Tony, Derick)
- Fixed bug #38700 (SoapClient::__getTypes never returns). (Dmitry)

42
Zend/tests/bug38772.phpt

@ -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

4
Zend/zend_compile.c

@ -2025,7 +2025,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))) {

33
Zend/zend_object_handlers.c

@ -783,7 +783,17 @@ static union _zend_function *zend_std_get_method(zval **object_ptr, char *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 %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), method_name, EG(scope) ? EG(scope)->name : "");
}
fbc = updated_fbc;
} else {
/* Ensure that we haven't overridden a private function and end up calling
* the overriding public function...
*/
@ -796,21 +806,12 @@ static union _zend_function *zend_std_get_method(zval **object_ptr, char *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 %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), method_name, EG(scope) ? EG(scope)->name : "");
}
fbc = updated_fbc;
} else 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 %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), method_name, EG(scope) ? EG(scope)->name : "");
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 %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), method_name, EG(scope) ? EG(scope)->name : "");
}
}
}

Loading…
Cancel
Save