]> granicus.if.org Git - php/commitdiff
Fixed bug #76869 (Incorrect bypassing protected method accessibilty check).
authorDmitry Stogov <dmitry@zend.com>
Wed, 12 Sep 2018 09:16:50 +0000 (12:16 +0300)
committerDmitry Stogov <dmitry@zend.com>
Wed, 12 Sep 2018 09:16:50 +0000 (12:16 +0300)
NEWS
Zend/tests/bug76869.phpt [new file with mode: 0644]
Zend/zend_object_handlers.c

diff --git a/NEWS b/NEWS
index 555cadd217e32fc45282547004dc2bd7a5f9ab2d..c99e0fd17a4cd7195513a9815be13f630a0deb47 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,9 @@
 PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? ??? ????, PHP 7.3.0RC2
+- Core:
+  . Fixed bug #76869 (Incorrect bypassing protected method accessibilty check).
+    (Dmitry)
 
 13 Sep 2018, PHP 7.3.0RC1
 
diff --git a/Zend/tests/bug76869.phpt b/Zend/tests/bug76869.phpt
new file mode 100644 (file)
index 0000000..ba963d4
--- /dev/null
@@ -0,0 +1,23 @@
+--TEST--
+Bug #76869 (Incorrect bypassing protected method accessibilty check)
+--FILE--
+<?php
+class A {
+       private function f() {
+               return "A";
+       }
+}
+class B extends A {
+       protected function f() {
+               return "B";
+       }
+}
+$b = new B();
+try {
+       var_dump($b->f());
+} catch (Throwable $e) {
+       echo "Exception: ", $e->getMessage(), "\n";
+}
+?>
+--EXPECT--
+Exception: Call to protected method B::f() from context ''
index aa2f5be8465c5cbdbbf565f1d5c31f0589d11f6d..b10e5afb0a048479ef30fbd9c1c94a7b8e9f6847 100644 (file)
@@ -1243,12 +1243,17 @@ ZEND_API zend_function *zend_std_get_method(zend_object **obj_ptr, zend_string *
                 */
 
                scope = zend_get_executed_scope();
-               if (fbc->op_array.fn_flags & ZEND_ACC_CHANGED) {
-                       zend_function *priv_fbc = zend_get_parent_private(scope, fbc->common.scope, lc_method_name);
-                       if (priv_fbc) {
-                               fbc = priv_fbc;
+               do {
+                       if (fbc->op_array.fn_flags & ZEND_ACC_CHANGED) {
+                               zend_function *priv_fbc = zend_get_parent_private(scope, fbc->common.scope, lc_method_name);
+                               if (priv_fbc) {
+                                       fbc = priv_fbc;
+                                       break;
+                               } else if (!(fbc->op_array.fn_flags & ZEND_ACC_PROTECTED)) {
+                                       break;
+                               }
                        }
-               } else {
+
                        /* Ensure that if we're calling a protected function, we're allowed to do so.
                         * If we're not and __call() handler exists, invoke it, otherwise error out.
                         */
@@ -1260,7 +1265,7 @@ ZEND_API zend_function *zend_std_get_method(zend_object **obj_ptr, zend_string *
                                        fbc = NULL;
                                }
                        }
-               }
+               } while (0);
        }
 
        if (UNEXPECTED(!key)) {