]> granicus.if.org Git - php/commitdiff
Fixed bug #62814
authorNikita Popov <nikic@php.net>
Tue, 29 Mar 2016 17:07:14 +0000 (19:07 +0200)
committerNikita Popov <nikic@php.net>
Tue, 29 Mar 2016 17:08:17 +0000 (19:08 +0200)
NEWS
Zend/tests/bug62814.phpt [new file with mode: 0644]
Zend/zend_inheritance.c

diff --git a/NEWS b/NEWS
index 604cf485dd7a3ad71bc01e3b845d7d25e7ccc12c..f677f0a0d3710ad9d04c5318a479765166e665cc 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -4,8 +4,10 @@ PHP                                                                        NEWS
 
 - Core:
   . Fixed bug #62210 (Exceptions can leak temporary variables). (Dmitry, Bob)
+  . Fixed bug #62814 (It is possible to stiffen child class members visibility).
+    (Nikita)
   . Fixed bug #69989 (Generators don't participate in cycle GC). (Nikita)
-  . Fixed buf #71572 (String offset assignment from an empty string inserts
+  . Fixed bug #71572 (String offset assignment from an empty string inserts
     null byte). (Francois)
   . Implemented the RFC `Support Class Constant Visibility`. (Sean DuBois,
     Reeze Xia, Dmitry)
diff --git a/Zend/tests/bug62814.phpt b/Zend/tests/bug62814.phpt
new file mode 100644 (file)
index 0000000..6646aa2
--- /dev/null
@@ -0,0 +1,20 @@
+--TEST--
+Bug #62814: It is possible to stiffen child class members visibility
+--FILE--
+<?php
+
+class A {
+    private function test() { }
+}
+
+class B extends A {
+    protected function test() { }
+}
+
+class C extends B {
+    private function test() { }
+}
+
+?>
+--EXPECTF--
+Fatal error: Access level to C::test() must be protected (as in class B) or weaker in %s on line %d
index 1f74000a4783a45e94947e7233583054b84c063b..1243552d59c0b264a9bc3da04b112f51ea93e445 100644 (file)
@@ -546,17 +546,17 @@ static void do_inheritance_check_on_method(zend_function *child, zend_function *
                zend_error_noreturn(E_COMPILE_ERROR, "Cannot make non abstract method %s::%s() abstract in class %s", ZEND_FN_SCOPE_NAME(parent), ZSTR_VAL(child->common.function_name), ZEND_FN_SCOPE_NAME(child));
        }
 
+       /* Prevent derived classes from restricting access that was available in parent classes */
+       if (UNEXPECTED((child_flags & ZEND_ACC_PPP_MASK) > (parent_flags & ZEND_ACC_PPP_MASK))) {
+               zend_error_noreturn(E_COMPILE_ERROR, "Access level to %s::%s() must be %s (as in class %s)%s", ZEND_FN_SCOPE_NAME(child), ZSTR_VAL(child->common.function_name), zend_visibility_string(parent_flags), ZEND_FN_SCOPE_NAME(parent), (parent_flags&ZEND_ACC_PUBLIC) ? "" : " or weaker");
+       }
+
+       if (((child_flags & ZEND_ACC_PPP_MASK) < (parent_flags & ZEND_ACC_PPP_MASK))
+               && ((parent_flags & ZEND_ACC_PPP_MASK) & ZEND_ACC_PRIVATE)) {
+               child->common.fn_flags |= ZEND_ACC_CHANGED;
+       }
        if (parent_flags & ZEND_ACC_CHANGED) {
                child->common.fn_flags |= ZEND_ACC_CHANGED;
-       } else {
-               /* Prevent derived classes from restricting access that was available in parent classes
-                */
-               if (UNEXPECTED((child_flags & ZEND_ACC_PPP_MASK) > (parent_flags & ZEND_ACC_PPP_MASK))) {
-                       zend_error_noreturn(E_COMPILE_ERROR, "Access level to %s::%s() must be %s (as in class %s)%s", ZEND_FN_SCOPE_NAME(child), ZSTR_VAL(child->common.function_name), zend_visibility_string(parent_flags), ZEND_FN_SCOPE_NAME(parent), (parent_flags&ZEND_ACC_PUBLIC) ? "" : " or weaker");
-               } else if (((child_flags & ZEND_ACC_PPP_MASK) < (parent_flags & ZEND_ACC_PPP_MASK))
-                       && ((parent_flags & ZEND_ACC_PPP_MASK) & ZEND_ACC_PRIVATE)) {
-                       child->common.fn_flags |= ZEND_ACC_CHANGED;
-               }
        }
 
        if (parent_flags & ZEND_ACC_PRIVATE) {