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)
--- /dev/null
+--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
}
}
- 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))) {
}
/* 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...
*/
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 : "");
+ }
}
}