From: Dmitry Stogov Date: Wed, 14 Jan 2009 11:56:24 +0000 (+0000) Subject: Fixed __call() to be invoked on private/protected method access through callback X-Git-Tag: php-5.4.0alpha1~191^2~4522 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2cfd6cd1957ecde0e9d2e1634de2b6a7fc5dc686;p=php Fixed __call() to be invoked on private/protected method access through callback s --- diff --git a/Zend/tests/access_modifiers_012.phpt b/Zend/tests/access_modifiers_012.phpt new file mode 100644 index 0000000000..ac4d72ce1d --- /dev/null +++ b/Zend/tests/access_modifiers_012.phpt @@ -0,0 +1,21 @@ +--TEST-- +Trigger __call() in lieu of non visible methods when called via a callback. +--FILE-- + +--EXPECTF-- +In __call() for method none() +In __call() for method prot() +In __call() for method priv() diff --git a/Zend/zend_API.c b/Zend/zend_API.c index febd091564..b8555f0ff6 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -2892,31 +2892,56 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca 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) {