]> granicus.if.org Git - php/commitdiff
Fixed bug #38772 (inconsistent overriding of methods in different visibility contexts)
authorDmitry Stogov <dmitry@php.net>
Tue, 12 Sep 2006 11:01:16 +0000 (11:01 +0000)
committerDmitry Stogov <dmitry@php.net>
Tue, 12 Sep 2006 11:01:16 +0000 (11:01 +0000)
NEWS
Zend/tests/bug38772.phpt [new file with mode: 0755]
Zend/zend_compile.c
Zend/zend_object_handlers.c

diff --git a/NEWS b/NEWS
index 555d3d9e8c6a3b66ab90a180e60f06ccbb901a88..0a4cb5c958bba5800d1ccc5798c49c46ff869581 100644 (file)
--- 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 (executable)
index 0000000..0e97c29
--- /dev/null
@@ -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
index 7f9bf757b0b00058107abe0a7c26476dd6c20cc4..bb04271e2e48b284c1757f47eeec436abe7455aa 100644 (file)
@@ -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))) {
index 9785cc0b69d7a9bb57562238e1d633d078523e32..32521f68d2199bbfa5163deaafd5463beabc9082 100644 (file)
@@ -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 : "");
+                       }
                }
        }