From 7e17f8591a06e2bf0fb7955b6654bd7f86b8f9e9 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 12 Sep 2006 11:01:16 +0000 Subject: [PATCH] Fixed bug #38772 (inconsistent overriding of methods in different visibility contexts) --- NEWS | 2 ++ Zend/tests/bug38772.phpt | 42 +++++++++++++++++++++++++++++++++++++ Zend/zend_compile.c | 4 +++- Zend/zend_object_handlers.c | 33 +++++++++++++++-------------- 4 files changed, 64 insertions(+), 17 deletions(-) create mode 100755 Zend/tests/bug38772.phpt diff --git a/NEWS b/NEWS index 555d3d9e8c..0a4cb5c958 100644 --- a/NEWS +++ b/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) 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 7f9bf757b0..bb04271e2e 100644 --- a/Zend/zend_compile.c +++ b/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))) { diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 9785cc0b69..32521f68d2 100644 --- a/Zend/zend_object_handlers.c +++ b/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 : ""); + } } } -- 2.40.0