Hello,

Do we keep the support added in http://bugs.php.net/bug.php?id=37632
(that isn't supported in C++, for instance) or fix the
zend_is_callable_check_func() ?


Thanks.

2008/2/5, Robin Fernandes <[EMAIL PROTECTED]>:
> Hi all,
>
>  The fix to bug 37212 (http://bugs.php.net/bug.php?id=37632) introduced
>  an unusual method accessibility rule. A class can access a protected
>  method declared outside of its own direct class hierarchy if that
>  method has a prototype in a common superclass.
>
>  <?php
>  class A {
>         static protected function f() {return 'A::f()';}
>  }
>  class B1 extends A {
>         static protected function f() {return 'B1::f()';}
>  }
>  class B2 extends A {
>         static public function test() {echo B1::f();}
>  }
>  B2::test(); // prints B1::f()
>  ?>
>
>  This is achieved using by zend_get_function_root_class() when invoking
>  zend_check_protected(), e.g.:
>    zend_check_protected(zend_get_function_root_class(fbc), EG(scope))
>
>  Looking at other uses of zend_check_protected() reveals at least 5
>  cases where this rule is not enforced. They are illustrated below. So
>  is the rule itself incorrect? or should the inconsistent cases be
>  fixed?
>
>
>  The examples below were tested on 5.2.5 and the latest 5.3 and 6.0 snaps.
>
>  1. The visibility rule does not apply to properties (static or not):
>  <?php
>  class A {
>         protected $p = 'A::$p';
>         static protected $sp = 'A::$sp';
>  }
>  class B1 extends A {
>         protected $p = 'B1::$p';
>         static protected $sp = 'B1::$sp';
>  }
>  class B2 extends A {
>         static public function test() {
>                 $b1 = new B1;
>                 echo $b1->p;  //Fatal error: Cannot access protected property 
> B1::$p
>                 echo B1::$sp; //Fatal error: Cannot access protected property 
> B1::$sp
>         }
>  }
>  B2::test();
>  ?>
>
>
>  2. It doesn't apply to callbacks either:
>  <?php
>  class A {
>         static protected function f() {return 'A::f()';}
>  }
>  class B1 extends A {
>         static protected function f() {return 'B1::f()';}
>  }
>  class B2 extends A {
>         static public function test() {
>                 echo call_user_func('B1::f');
>         }
>  }
>  B2::test(); // Warning: call_user_func() expects parameter 1 to be a
>  valid callback, cannot access protected method B1::f()
>  ?>
>
>
>  3. is_callable() doesn't know about this visibility rule:
>  <?php
>  class A {
>         static protected function f() {return 'A::f()';}
>  }
>  class B1 extends A {
>         static protected function f() {return 'B1::f()';}
>  }
>  class B2 extends A {
>         static public function test() {
>                 var_dump(is_callable('B1::f')); // returns false
>                 B1::f(); // works
>         }
>  }
>  B2::test();
>  ?>
>
>
>  4. The rule does not apply to the clone magic method:
>  <?php
>  class A {
>         protected function f() {return 'A::f()';}
>         protected function __clone() {}
>  }
>  class B1 extends A {
>         protected function f() {return 'B1::f()';}
>         protected function __clone() {}
>  }
>  class B2 extends A {
>         static public function test($obj) {
>                 echo $obj->f();         // works
>                 clone $obj; // Fatal error: Call to protected B1::__clone() 
> from context 'B2'
>         }
>  }
>  B2::test(new B1);
>  ?>
>
>
>  5. The rule does not apply to destructors:
>  <?php
>  class A {
>         protected function __destruct() {}
>  }
>  class B1 extends A {
>         protected function __destruct() {}
>  }
>  class B2 extends A {
>         static public function test() {
>                 $obj = new B1;
>         }  // Fatal error: Call to protected B1::__destruct() from context 
> 'B2'
>  }
>  B2::test();
>  ?>
>
>  Many thanks,
>  Robin
>
>
>  --
>  PHP Internals - PHP Runtime Development Mailing List
>  To unsubscribe, visit: http://www.php.net/unsub.php
>
>

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to