--- /dev/null
+--TEST--
+Trigger __call() in lieu of non visible methods when called via a callback.
+--FILE--
+<?php
+class C {
+ protected function prot() { }
+ private function priv() { }
+ public function __call($name, $args) {
+ echo "In __call() for method $name()\n";
+ }
+}
+
+$c = new C;
+call_user_func(array($c, 'none'));
+call_user_func(array($c, 'prot'));
+call_user_func(array($c, 'priv'));
+?>
+--EXPECTF--
+In __call() for method none()
+In __call() for method prot()
+In __call() for method priv()
fcc->function_handler = priv_fbc;
}
}
- } else if (fcc->object_ptr) {
- if (Z_OBJ_HT_P(fcc->object_ptr)->get_method) {
- zstr method = mname;
- int method_len = mlen;
-
- if (UG(unicode) && Z_TYPE_P(callable) == IS_STRING) {
- zend_string_to_unicode(ZEND_U_CONVERTER(UG(runtime_encoding_conv)), &method.u, &method_len, mname.s, mlen TSRMLS_CC);
- } else if (!UG(unicode) && Z_TYPE_P(callable) == IS_UNICODE) {
- zend_unicode_to_string(ZEND_U_CONVERTER(UG(runtime_encoding_conv)), &method.s, &method_len, mname.u, mlen TSRMLS_CC);
- }
- fcc->function_handler = Z_OBJ_HT_P(fcc->object_ptr)->get_method(&fcc->object_ptr, method, method_len TSRMLS_CC);
- if (method.v != mname.v) {
- efree(method.v);
+ if ((check_flags & IS_CALLABLE_CHECK_NO_ACCESS) == 0 &&
+ (fcc->calling_scope &&
+ (fcc->calling_scope->__call ||
+ fcc->calling_scope->__callstatic))) {
+ if (fcc->function_handler->op_array.fn_flags & ZEND_ACC_PRIVATE) {
+ if (!zend_check_private(fcc->function_handler, fcc->object_ptr ? Z_OBJCE_P(fcc->object_ptr) : EG(scope), lmname, lmlen TSRMLS_CC)) {
+ retval = 0;
+ fcc->function_handler = NULL;
+ goto get_function_via_handler;
+ }
+ } else if ((fcc->function_handler->common.fn_flags & ZEND_ACC_PROTECTED)) {
+ if (!zend_check_protected(fcc->function_handler->common.scope, EG(scope))) {
+ retval = 0;
+ fcc->function_handler = NULL;
+ goto get_function_via_handler;
+ }
}
- retval = fcc->function_handler ? 1 : 0;
- call_via_handler = 1;
}
- } else if (fcc->calling_scope) {
- if (fcc->calling_scope->get_static_method) {
- fcc->function_handler = fcc->calling_scope->get_static_method(fcc->calling_scope, Z_TYPE_P(callable), mname, mlen TSRMLS_CC);
- } else {
- fcc->function_handler = zend_std_get_static_method(fcc->calling_scope, Z_TYPE_P(callable), mname, mlen TSRMLS_CC);
+ } else {
+get_function_via_handler:
+ if (fcc->object_ptr) {
+ if (Z_OBJ_HT_P(fcc->object_ptr)->get_method) {
+ zstr method = mname;
+ int method_len = mlen;
+
+ if (UG(unicode) && Z_TYPE_P(callable) == IS_STRING) {
+ zend_string_to_unicode(ZEND_U_CONVERTER(UG(runtime_encoding_conv)), &method.u, &method_len, mname.s, mlen TSRMLS_CC);
+ } else if (!UG(unicode) && Z_TYPE_P(callable) == IS_UNICODE) {
+ zend_unicode_to_string(ZEND_U_CONVERTER(UG(runtime_encoding_conv)), &method.s, &method_len, mname.u, mlen TSRMLS_CC);
+ }
+ fcc->function_handler = Z_OBJ_HT_P(fcc->object_ptr)->get_method(&fcc->object_ptr, method, method_len TSRMLS_CC);
+ if (method.v != mname.v) {
+ efree(method.v);
+ }
+ if (fcc->function_handler) {
+ retval = 1;
+ call_via_handler = (fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0;
+ }
+ }
+ } else if (fcc->calling_scope) {
+ if (fcc->calling_scope->get_static_method) {
+ fcc->function_handler = fcc->calling_scope->get_static_method(fcc->calling_scope, Z_TYPE_P(callable), mname, mlen TSRMLS_CC);
+ } else {
+ fcc->function_handler = zend_std_get_static_method(fcc->calling_scope, Z_TYPE_P(callable), mname, mlen TSRMLS_CC);
+ }
+ if (fcc->function_handler) {
+ retval = 1;
+ call_via_handler = (fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0;
+ }
}
- retval = fcc->function_handler ? 1 : 0;
- call_via_handler = 1;
}
if (retval) {