From: Dmitry Stogov Date: Tue, 12 Sep 2006 11:01:31 +0000 (+0000) Subject: Fixed bug #38772 (inconsistent overriding of methods in different visibility contexts) X-Git-Tag: RELEASE_1_0_0RC1~1694 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5574651edb8069452edbda545edee273398167e0;p=php Fixed bug #38772 (inconsistent overriding of methods in different visibility contexts) --- diff --git a/Zend/tests/bug38772.phpt b/Zend/tests/bug38772.phpt new file mode 100755 index 0000000000..0e97c291c3 --- /dev/null +++ b/Zend/tests/bug38772.phpt @@ -0,0 +1,42 @@ +--TEST-- +Bug #38772 (inconsistent overriding of methods in different visibility contexts) +--FILE-- + 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 diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index f581de537c..35f4ddcc68 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -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))) { diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 6a0abb77b4..9314a5a01b 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -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,21 +821,12 @@ 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)) { - /* 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); + 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); + } } }