cvs: php-src /ext/standard basic_functions.c ZendEngine2 zend_API.c zend_API.h zend_object_handlers.c zend_object_handlers.h ZendEngine2/tests
bug29210.phpt
| From: | Dmitry Stogov | Date: | Wed, 27 Apr 2005 15:45:36 +0000 |
| Subject: | cvs: php-src /ext/standard basic_functions.c ZendEngine2 zend_API.c zend_API.h zend_object_handlers.c zend_object_handlers.h ZendEngine2/tests bug29210.phpt |
||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-31625@lists.php.net to get a copy of this message | ||
dmitry Wed Apr 27 11:45:36 2005 EDT
Modified files:
/ZendEngine2 zend_API.c zend_API.h zend_object_handlers.c
zend_object_handlers.h
/ZendEngine2/tests bug29210.phpt
/php-src/ext/standard basic_functions.c
Log:
Fixed bug #29210 (Function: is_callable - no support for private and protected classes)
http://cvs.php.net/diff.php/ZendEngine2/zend_API.c?r1=1.283&r2=1.284&ty=u Index: ZendEngine2/zend_API.c diff -u ZendEngine2/zend_API.c:1.283 ZendEngine2/zend_API.c:1.284 --- ZendEngine2/zend_API.c:1.283 Tue Apr 26 05:27:27 2005 +++ ZendEngine2/zend_API.c Wed Apr 27 11:45:35 2005 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_API.c,v 1.283 2005/04/26 09:27:27 dmitry Exp $ */ +/* $Id: zend_API.c,v 1.284 2005/04/27 15:45:35 dmitry Exp $ */ #include "zend.h" #include "zend_execute.h" @@ -1741,7 +1741,7 @@ return 1; } -ZEND_API zend_bool zend_is_callable(zval *callable, zend_bool syntax_only, char **callable_name) +ZEND_API zend_bool zend_is_callable(zval *callable, uint check_flags, char **callable_name) { char *lcname; zend_bool retval = 0; @@ -1752,7 +1752,7 @@ if (callable_name) { *callable_name = estrndup(Z_STRVAL_P(callable), Z_STRLEN_P(callable)); } - if (syntax_only) { + if (check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY) { return 1; } @@ -1789,7 +1789,7 @@ memcpy(ptr, Z_STRVAL_PP(method), Z_STRLEN_PP(method) + 1); } - if (syntax_only) + if (check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY) return 1; lcname = zend_str_tolower_dup(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj)); @@ -1818,14 +1818,27 @@ memcpy(ptr, Z_STRVAL_PP(method), Z_STRLEN_PP(method) + 1); } - if (syntax_only) + if (check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY) return 1; } if (ce) { + zend_function *fbc; + lcname = zend_str_tolower_dup(Z_STRVAL_PP(method), Z_STRLEN_PP(method)); - if (zend_hash_exists(&ce->function_table, lcname, Z_STRLEN_PP(method)+1)) { - retval = 1; + if (zend_hash_find(&ce->function_table, lcname, Z_STRLEN_PP(method)+1, (void **)&fbc) == SUCCESS) { + retval = 1; + if ((check_flags & IS_CALLABLE_CHECK_NO_ACCESS) == 0) { + if (fbc->op_array.fn_flags & ZEND_ACC_PRIVATE) { + if (!zend_check_private(fbc, (Z_TYPE_PP(obj) == IS_STRING)?EG(scope):(*obj)->value.obj.handlers->get_class_entry(*obj TSRMLS_CC), lcname, Z_STRLEN_PP(method) TSRMLS_CC)) { + retval = 0; + } + } else if ((fbc->common.fn_flags & ZEND_ACC_PROTECTED)) { + if (!zend_check_protected(fbc->common.scope, EG(scope))) { + retval = 0; + } + } + } } /* check for __call too */ if (retval == 0 && ce->__call != 0) { http://cvs.php.net/diff.php/ZendEngine2/zend_API.h?r1=1.196&r2=1.197&ty=u Index: ZendEngine2/zend_API.h diff -u ZendEngine2/zend_API.h:1.196 ZendEngine2/zend_API.h:1.197 --- ZendEngine2/zend_API.h:1.196 Tue Apr 19 18:04:57 2005 +++ ZendEngine2/zend_API.h Wed Apr 27 11:45:35 2005 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_API.h,v 1.196 2005/04/19 22:04:57 helly Exp $ */ +/* $Id: zend_API.h,v 1.197 2005/04/27 15:45:35 dmitry Exp $ */ #ifndef ZEND_API_H #define ZEND_API_H @@ -184,7 +184,11 @@ ZEND_API int zend_disable_class(char *class_name, uint class_name_length TSRMLS_DC); ZEND_API void zend_wrong_param_count(TSRMLS_D); -ZEND_API zend_bool zend_is_callable(zval *callable, zend_bool syntax_only, char **callable_name); + +#define IS_CALLABLE_CHECK_SYNTAX_ONLY (1<<0) +#define IS_CALLABLE_CHECK_NO_ACCESS (1<<1) + +ZEND_API zend_bool zend_is_callable(zval *callable, uint check_flags, char **callable_name); ZEND_API zend_bool zend_make_callable(zval *callable, char **callable_name TSRMLS_DC); ZEND_API char *zend_get_module_version(char *module_name); ZEND_API int zend_get_module_started(char *module_name); http://cvs.php.net/diff.php/ZendEngine2/zend_object_handlers.c?r1=1.118&r2=1.119&ty=u Index: ZendEngine2/zend_object_handlers.c diff -u ZendEngine2/zend_object_handlers.c:1.118 ZendEngine2/zend_object_handlers.c:1.119 --- ZendEngine2/zend_object_handlers.c:1.118 Mon Apr 25 16:41:26 2005 +++ ZendEngine2/zend_object_handlers.c Wed Apr 27 11:45:35 2005 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_object_handlers.c,v 1.118 2005/04/25 20:41:26 andrei Exp $ */ +/* $Id: zend_object_handlers.c,v 1.119 2005/04/27 15:45:35 dmitry Exp $ */ #include "zend.h" #include "zend_globals.h" @@ -531,7 +531,7 @@ * Returns the function address that should be called, or NULL * if no such function exists. */ -static inline zend_function *zend_check_private(zend_function *fbc, zend_class_entry *ce, int fn_flags, char *function_name_strval, int function_name_strlen TSRMLS_DC) +static inline zend_function *zend_check_private_int(zend_function *fbc, zend_class_entry *ce, char *function_name_strval, int function_name_strlen TSRMLS_DC) { if (!ce) { return 0; @@ -566,6 +566,12 @@ } +ZEND_API int zend_check_private(zend_function *fbc, zend_class_entry *ce, char *function_name_strval, int function_name_strlen TSRMLS_DC) +{ + return zend_check_private_int(fbc, ce, function_name_strval, function_name_strlen TSRMLS_CC) != NULL; +} + + /* Ensures that we're allowed to call a protected method. */ ZEND_API int zend_check_protected(zend_class_entry *ce, zend_class_entry *scope) @@ -643,7 +649,7 @@ /* Ensure that if we're calling a private function, we're allowed to do so. */ - updated_fbc = zend_check_private(fbc, object->value.obj.handlers->get_class_entry(object TSRMLS_CC), fbc->common.fn_flags, lc_method_name, method_len TSRMLS_CC); + updated_fbc = zend_check_private_int(fbc, object->value.obj.handlers->get_class_entry(object TSRMLS_CC), lc_method_name, method_len TSRMLS_CC); if (!updated_fbc) { zend_error(E_ERROR, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), method_name, EG(scope) ? EG(scope)->name : ""); } @@ -681,7 +687,7 @@ /* Ensure that if we're calling a private function, we're allowed to do so. */ - updated_fbc = zend_check_private(fbc, EG(scope), fbc->common.fn_flags, function_name_strval, function_name_strlen TSRMLS_CC); + updated_fbc = zend_check_private_int(fbc, EG(scope), function_name_strval, function_name_strlen TSRMLS_CC); if (!updated_fbc) { zend_error(E_ERROR, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), function_name_strval, EG(scope) ? EG(scope)->name : ""); } http://cvs.php.net/diff.php/ZendEngine2/zend_object_handlers.h?r1=1.43&r2=1.44&ty=u Index: ZendEngine2/zend_object_handlers.h diff -u ZendEngine2/zend_object_handlers.h:1.43 ZendEngine2/zend_object_handlers.h:1.44 --- ZendEngine2/zend_object_handlers.h:1.43 Fri Apr 8 07:35:11 2005 +++ ZendEngine2/zend_object_handlers.h Wed Apr 27 11:45:35 2005 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_object_handlers.h,v 1.43 2005/04/08 11:35:11 helly Exp $ */ +/* $Id: zend_object_handlers.h,v 1.44 2005/04/27 15:45:35 dmitry Exp $ */ #ifndef ZEND_OBJECT_HANDLERS_H #define ZEND_OBJECT_HANDLERS_H @@ -139,6 +139,8 @@ #define IS_ZEND_STD_OBJECT(z) ((z).type == IS_OBJECT && (Z_OBJ_HT((z))->get_class_entry != NULL)) #define HAS_CLASS_ENTRY(z) (Z_OBJ_HT(z)->get_class_entry != NULL) +ZEND_API int zend_check_private(union _zend_function *fbc, zend_class_entry *ce, char *function_name_strval, int function_name_strlen TSRMLS_DC); + ZEND_API int zend_check_protected(zend_class_entry *ce, zend_class_entry *scope); ZEND_API int zend_check_property_access(zend_object *zobj, char *prop_info_name TSRMLS_DC); http://cvs.php.net/diff.php/ZendEngine2/tests/bug29210.phpt?r1=1.1&r2=1.2&ty=u Index: ZendEngine2/tests/bug29210.phpt diff -u /dev/null ZendEngine2/tests/bug29210.phpt:1.2 --- /dev/null Wed Apr 27 11:45:36 2005 +++ ZendEngine2/tests/bug29210.phpt Wed Apr 27 11:45:36 2005 @@ -0,0 +1,104 @@ +--TEST-- +Bug #29210 Function: is_callable - no support for private and protected classes +--FILE-- +<?php +class test_class { + private function test_func1() { + echo "test_func1\n"; + } + protected function test_func2() { + echo "test_func2\n"; + } + static private function test_func3() { + echo "test_func3\n"; + } + static protected function test_func4() { + echo "test_func4\n"; + } + function test() { + if (is_callable(array($this,'test_func1'))) { + $this->test_func1(); + } else { + echo "test_func1 isn't callable from inside\n"; + } + if (is_callable(array($this,'test_func2'))) { + $this->test_func2(); + } else { + echo "test_func2 isn't callable from inside\n"; + } + if (is_callable(array('test_class','test_func3'))) { + test_class::test_func3(); + } else { + echo "test_func3 isn't callable from inside\n"; + } + if (is_callable(array('test_class','test_func4'))) { + test_class::test_func4(); + } else { + echo "test_func4 isn't callable from inside\n"; + } + } +} + +class foo extends test_class { + function test() { + if (is_callable(array($this,'test_func1'))) { + $this->test_func1(); + } else { + echo "test_func1 isn't callable from child\n"; + } + if (is_callable(array($this,'test_func2'))) { + $this->test_func2(); + } else { + echo "test_func2 isn't callable from child\n"; + } + if (is_callable(array('test_class','test_func3'))) { + test_class::test_func3(); + } else { + echo "test_func3 isn't callable from child\n"; + } + if (is_callable(array('test_class','test_func4'))) { + test_class::test_func4(); + } else { + echo "test_func4 isn't callable from child\n"; + } + } +} + +$object = new test_class; +$object->test(); +if (is_callable(array($object,'test_func1'))) { + $object->test_func1(); +} else { + echo "test_func1 isn't callable from outside\n"; +} +if (is_callable(array($object,'test_func2'))) { + $object->test_func2(); +} else { + echo "test_func2 isn't callable from outside\n"; +} +if (is_callable(array('test_class','test_func3'))) { + test_class::test_func3(); +} else { + echo "test_func3 isn't callable from outside\n"; +} +if (is_callable(array('test_class','test_func4'))) { + test_class::test_func4(); +} else { + echo "test_func4 isn't callable from outside\n"; +} +$object = new foo(); +$object->test(); +?> +--EXPECT-- +test_func1 +test_func2 +test_func3 +test_func4 +test_func1 isn't callable from outside +test_func2 isn't callable from outside +test_func3 isn't callable from outside +test_func4 isn't callable from outside +test_func1 isn't callable from child +test_func2 +test_func3 isn't callable from child +test_func4 http://cvs.php.net/diff.php/php-src/ext/standard/basic_functions.c?r1=1.710&r2=1.711&ty=u Index: php-src/ext/standard/basic_functions.c diff -u php-src/ext/standard/basic_functions.c:1.710 php-src/ext/standard/basic_functions.c:1.711 --- php-src/ext/standard/basic_functions.c:1.710 Thu Apr 21 10:44:29 2005 +++ php-src/ext/standard/basic_functions.c Wed Apr 27 11:45:36 2005 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: basic_functions.c,v 1.710 2005/04/21 14:44:29 sniper Exp $ */ +/* $Id: basic_functions.c,v 1.711 2005/04/27 15:45:36 dmitry Exp $ */ #include "php.h" #include "php_streams.h" @@ -2051,7 +2051,7 @@ convert_to_string_ex(params[0]); } - if (!zend_is_callable(*params[0], 0, &name)) { + if (!zend_is_callable(*params[0], IS_CALLABLE_CHECK_NO_ACCESS, &name)) { php_error_docref1(NULL TSRMLS_CC, name, E_WARNING, "First argument is expected to be a valid callback"); efree(name); efree(params); @@ -2106,7 +2106,7 @@ convert_to_string_ex(func); } - if (!zend_is_callable(*func, 0, &name)) { + if (!zend_is_callable(*func, IS_CALLABLE_CHECK_NO_ACCESS, &name)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "First argument is expected to be a valid callback, '%s' was given", name); efree(name); RETURN_NULL();
http://cvs.php.net/diff.php/ZendEngine2/zend_API.c?r1=1.283&r2=1.284&ty=u Index: ZendEngine2/zend_API.c diff -u ZendEngine2/zend_API.c:1.283 ZendEngine2/zend_API.c:1.284 --- ZendEngine2/zend_API.c:1.283 Tue Apr 26 05:27:27 2005 +++ ZendEngine2/zend_API.c Wed Apr 27 11:45:35 2005 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_API.c,v 1.283 2005/04/26 09:27:27 dmitry Exp $ */ +/* $Id: zend_API.c,v 1.284 2005/04/27 15:45:35 dmitry Exp $ */ #include "zend.h" #include "zend_execute.h" @@ -1741,7 +1741,7 @@ return 1; } -ZEND_API zend_bool zend_is_callable(zval *callable, zend_bool syntax_only, char **callable_name) +ZEND_API zend_bool zend_is_callable(zval *callable, uint check_flags, char **callable_name) { char *lcname; zend_bool retval = 0; @@ -1752,7 +1752,7 @@ if (callable_name) { *callable_name = estrndup(Z_STRVAL_P(callable), Z_STRLEN_P(callable)); } - if (syntax_only) { + if (check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY) { return 1; } @@ -1789,7 +1789,7 @@ memcpy(ptr, Z_STRVAL_PP(method), Z_STRLEN_PP(method) + 1); } - if (syntax_only) + if (check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY) return 1; lcname = zend_str_tolower_dup(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj)); @@ -1818,14 +1818,27 @@ memcpy(ptr, Z_STRVAL_PP(method), Z_STRLEN_PP(method) + 1); } - if (syntax_only) + if (check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY) return 1; } if (ce) { + zend_function *fbc; + lcname = zend_str_tolower_dup(Z_STRVAL_PP(method), Z_STRLEN_PP(method)); - if (zend_hash_exists(&ce->function_table, lcname, Z_STRLEN_PP(method)+1)) { - retval = 1; + if (zend_hash_find(&ce->function_table, lcname, Z_STRLEN_PP(method)+1, (void **)&fbc) == SUCCESS) { + retval = 1; + if ((check_flags & IS_CALLABLE_CHECK_NO_ACCESS) == 0) { + if (fbc->op_array.fn_flags & ZEND_ACC_PRIVATE) { + if (!zend_check_private(fbc, (Z_TYPE_PP(obj) == IS_STRING)?EG(scope):(*obj)->value.obj.handlers->get_class_entry(*obj TSRMLS_CC), lcname, Z_STRLEN_PP(method) TSRMLS_CC)) { + retval = 0; + } + } else if ((fbc->common.fn_flags & ZEND_ACC_PROTECTED)) { + if (!zend_check_protected(fbc->common.scope, EG(scope))) { + retval = 0; + } + } + } } /* check for __call too */ if (retval == 0 && ce->__call != 0) { http://cvs.php.net/diff.php/ZendEngine2/zend_API.h?r1=1.196&r2=1.197&ty=u Index: ZendEngine2/zend_API.h diff -u ZendEngine2/zend_API.h:1.196 ZendEngine2/zend_API.h:1.197 --- ZendEngine2/zend_API.h:1.196 Tue Apr 19 18:04:57 2005 +++ ZendEngine2/zend_API.h Wed Apr 27 11:45:35 2005 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_API.h,v 1.196 2005/04/19 22:04:57 helly Exp $ */ +/* $Id: zend_API.h,v 1.197 2005/04/27 15:45:35 dmitry Exp $ */ #ifndef ZEND_API_H #define ZEND_API_H @@ -184,7 +184,11 @@ ZEND_API int zend_disable_class(char *class_name, uint class_name_length TSRMLS_DC); ZEND_API void zend_wrong_param_count(TSRMLS_D); -ZEND_API zend_bool zend_is_callable(zval *callable, zend_bool syntax_only, char **callable_name); + +#define IS_CALLABLE_CHECK_SYNTAX_ONLY (1<<0) +#define IS_CALLABLE_CHECK_NO_ACCESS (1<<1) + +ZEND_API zend_bool zend_is_callable(zval *callable, uint check_flags, char **callable_name); ZEND_API zend_bool zend_make_callable(zval *callable, char **callable_name TSRMLS_DC); ZEND_API char *zend_get_module_version(char *module_name); ZEND_API int zend_get_module_started(char *module_name); http://cvs.php.net/diff.php/ZendEngine2/zend_object_handlers.c?r1=1.118&r2=1.119&ty=u Index: ZendEngine2/zend_object_handlers.c diff -u ZendEngine2/zend_object_handlers.c:1.118 ZendEngine2/zend_object_handlers.c:1.119 --- ZendEngine2/zend_object_handlers.c:1.118 Mon Apr 25 16:41:26 2005 +++ ZendEngine2/zend_object_handlers.c Wed Apr 27 11:45:35 2005 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_object_handlers.c,v 1.118 2005/04/25 20:41:26 andrei Exp $ */ +/* $Id: zend_object_handlers.c,v 1.119 2005/04/27 15:45:35 dmitry Exp $ */ #include "zend.h" #include "zend_globals.h" @@ -531,7 +531,7 @@ * Returns the function address that should be called, or NULL * if no such function exists. */ -static inline zend_function *zend_check_private(zend_function *fbc, zend_class_entry *ce, int fn_flags, char *function_name_strval, int function_name_strlen TSRMLS_DC) +static inline zend_function *zend_check_private_int(zend_function *fbc, zend_class_entry *ce, char *function_name_strval, int function_name_strlen TSRMLS_DC) { if (!ce) { return 0; @@ -566,6 +566,12 @@ } +ZEND_API int zend_check_private(zend_function *fbc, zend_class_entry *ce, char *function_name_strval, int function_name_strlen TSRMLS_DC) +{ + return zend_check_private_int(fbc, ce, function_name_strval, function_name_strlen TSRMLS_CC) != NULL; +} + + /* Ensures that we're allowed to call a protected method. */ ZEND_API int zend_check_protected(zend_class_entry *ce, zend_class_entry *scope) @@ -643,7 +649,7 @@ /* Ensure that if we're calling a private function, we're allowed to do so. */ - updated_fbc = zend_check_private(fbc, object->value.obj.handlers->get_class_entry(object TSRMLS_CC), fbc->common.fn_flags, lc_method_name, method_len TSRMLS_CC); + updated_fbc = zend_check_private_int(fbc, object->value.obj.handlers->get_class_entry(object TSRMLS_CC), lc_method_name, method_len TSRMLS_CC); if (!updated_fbc) { zend_error(E_ERROR, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), method_name, EG(scope) ? EG(scope)->name : ""); } @@ -681,7 +687,7 @@ /* Ensure that if we're calling a private function, we're allowed to do so. */ - updated_fbc = zend_check_private(fbc, EG(scope), fbc->common.fn_flags, function_name_strval, function_name_strlen TSRMLS_CC); + updated_fbc = zend_check_private_int(fbc, EG(scope), function_name_strval, function_name_strlen TSRMLS_CC); if (!updated_fbc) { zend_error(E_ERROR, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), function_name_strval, EG(scope) ? EG(scope)->name : ""); } http://cvs.php.net/diff.php/ZendEngine2/zend_object_handlers.h?r1=1.43&r2=1.44&ty=u Index: ZendEngine2/zend_object_handlers.h diff -u ZendEngine2/zend_object_handlers.h:1.43 ZendEngine2/zend_object_handlers.h:1.44 --- ZendEngine2/zend_object_handlers.h:1.43 Fri Apr 8 07:35:11 2005 +++ ZendEngine2/zend_object_handlers.h Wed Apr 27 11:45:35 2005 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_object_handlers.h,v 1.43 2005/04/08 11:35:11 helly Exp $ */ +/* $Id: zend_object_handlers.h,v 1.44 2005/04/27 15:45:35 dmitry Exp $ */ #ifndef ZEND_OBJECT_HANDLERS_H #define ZEND_OBJECT_HANDLERS_H @@ -139,6 +139,8 @@ #define IS_ZEND_STD_OBJECT(z) ((z).type == IS_OBJECT && (Z_OBJ_HT((z))->get_class_entry != NULL)) #define HAS_CLASS_ENTRY(z) (Z_OBJ_HT(z)->get_class_entry != NULL) +ZEND_API int zend_check_private(union _zend_function *fbc, zend_class_entry *ce, char *function_name_strval, int function_name_strlen TSRMLS_DC); + ZEND_API int zend_check_protected(zend_class_entry *ce, zend_class_entry *scope); ZEND_API int zend_check_property_access(zend_object *zobj, char *prop_info_name TSRMLS_DC); http://cvs.php.net/diff.php/ZendEngine2/tests/bug29210.phpt?r1=1.1&r2=1.2&ty=u Index: ZendEngine2/tests/bug29210.phpt diff -u /dev/null ZendEngine2/tests/bug29210.phpt:1.2 --- /dev/null Wed Apr 27 11:45:36 2005 +++ ZendEngine2/tests/bug29210.phpt Wed Apr 27 11:45:36 2005 @@ -0,0 +1,104 @@ +--TEST-- +Bug #29210 Function: is_callable - no support for private and protected classes +--FILE-- +<?php +class test_class { + private function test_func1() { + echo "test_func1\n"; + } + protected function test_func2() { + echo "test_func2\n"; + } + static private function test_func3() { + echo "test_func3\n"; + } + static protected function test_func4() { + echo "test_func4\n"; + } + function test() { + if (is_callable(array($this,'test_func1'))) { + $this->test_func1(); + } else { + echo "test_func1 isn't callable from inside\n"; + } + if (is_callable(array($this,'test_func2'))) { + $this->test_func2(); + } else { + echo "test_func2 isn't callable from inside\n"; + } + if (is_callable(array('test_class','test_func3'))) { + test_class::test_func3(); + } else { + echo "test_func3 isn't callable from inside\n"; + } + if (is_callable(array('test_class','test_func4'))) { + test_class::test_func4(); + } else { + echo "test_func4 isn't callable from inside\n"; + } + } +} + +class foo extends test_class { + function test() { + if (is_callable(array($this,'test_func1'))) { + $this->test_func1(); + } else { + echo "test_func1 isn't callable from child\n"; + } + if (is_callable(array($this,'test_func2'))) { + $this->test_func2(); + } else { + echo "test_func2 isn't callable from child\n"; + } + if (is_callable(array('test_class','test_func3'))) { + test_class::test_func3(); + } else { + echo "test_func3 isn't callable from child\n"; + } + if (is_callable(array('test_class','test_func4'))) { + test_class::test_func4(); + } else { + echo "test_func4 isn't callable from child\n"; + } + } +} + +$object = new test_class; +$object->test(); +if (is_callable(array($object,'test_func1'))) { + $object->test_func1(); +} else { + echo "test_func1 isn't callable from outside\n"; +} +if (is_callable(array($object,'test_func2'))) { + $object->test_func2(); +} else { + echo "test_func2 isn't callable from outside\n"; +} +if (is_callable(array('test_class','test_func3'))) { + test_class::test_func3(); +} else { + echo "test_func3 isn't callable from outside\n"; +} +if (is_callable(array('test_class','test_func4'))) { + test_class::test_func4(); +} else { + echo "test_func4 isn't callable from outside\n"; +} +$object = new foo(); +$object->test(); +?> +--EXPECT-- +test_func1 +test_func2 +test_func3 +test_func4 +test_func1 isn't callable from outside +test_func2 isn't callable from outside +test_func3 isn't callable from outside +test_func4 isn't callable from outside +test_func1 isn't callable from child +test_func2 +test_func3 isn't callable from child +test_func4 http://cvs.php.net/diff.php/php-src/ext/standard/basic_functions.c?r1=1.710&r2=1.711&ty=u Index: php-src/ext/standard/basic_functions.c diff -u php-src/ext/standard/basic_functions.c:1.710 php-src/ext/standard/basic_functions.c:1.711 --- php-src/ext/standard/basic_functions.c:1.710 Thu Apr 21 10:44:29 2005 +++ php-src/ext/standard/basic_functions.c Wed Apr 27 11:45:36 2005 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: basic_functions.c,v 1.710 2005/04/21 14:44:29 sniper Exp $ */ +/* $Id: basic_functions.c,v 1.711 2005/04/27 15:45:36 dmitry Exp $ */ #include "php.h" #include "php_streams.h" @@ -2051,7 +2051,7 @@ convert_to_string_ex(params[0]); } - if (!zend_is_callable(*params[0], 0, &name)) { + if (!zend_is_callable(*params[0], IS_CALLABLE_CHECK_NO_ACCESS, &name)) { php_error_docref1(NULL TSRMLS_CC, name, E_WARNING, "First argument is expected to be a valid callback"); efree(name); efree(params); @@ -2106,7 +2106,7 @@ convert_to_string_ex(func); } - if (!zend_is_callable(*func, 0, &name)) { + if (!zend_is_callable(*func, IS_CALLABLE_CHECK_NO_ACCESS, &name)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "First argument is expected to be a valid callback, '%s' was given", name); efree(name); RETURN_NULL();