From 2b23e4e205fdb80f64722960b9ab310a57ee4b31 Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Fri, 22 Dec 2006 15:38:42 +0000 Subject: [PATCH] MFB: Fixed bug #39884 (ReflectionParameter::getClass() throws exception for type hint self). --- ext/reflection/php_reflection.c | 36 +++++++++++++++++++++++++++++- ext/reflection/tests/bug39884.phpt | 22 ++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 ext/reflection/tests/bug39884.phpt diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 2d1d8406d8..b76d775dca 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -2009,7 +2009,41 @@ ZEND_METHOD(reflection_parameter, getClass) GET_REFLECTION_OBJECT_PTR(param); if (param->arg_info->class_name.v) { - if (zend_u_lookup_class_ex(UG(unicode)?IS_UNICODE:IS_STRING, param->arg_info->class_name, param->arg_info->class_name_len, 1, 1, &pce TSRMLS_CC) == FAILURE) { + + /* Class name is stored as a string, we might also get "self" or "parent" + * - For "self", simply use the function scope. If scope is NULL then + * the function is global and thus self does not make any sense + * + * - For "parent", use the function scope's parent. If scope is NULL then + * the function is global and thus parent does not make any sense. + * If the parent is NULL then the class does not extend anything and + * thus parent does not make any sense, either. + * + * TODO: Think about moving these checks to the compiler or some sort of + * lint-mode. + */ + if (0 == strncmp(param->arg_info->class_name.v, "self", sizeof("self")- 1)) { + zend_class_entry *ce= param->fptr->common.scope; + if (!ce) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Parameter uses 'self' as type hint but function is not a class member!"); + return; + } + pce= &ce; + } else if (0 == strncmp(param->arg_info->class_name.v, "parent", sizeof("parent")- 1)) { + zend_class_entry *ce= param->fptr->common.scope; + if (!ce) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Parameter uses 'parent' as type hint but function is not a class member!"); + return; + } + if (!ce->parent) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Parameter uses 'parent' as type hint although class does not have a parent!"); + return; + } + pce= &ce->parent; + } else if (zend_u_lookup_class_ex(UG(unicode)?IS_UNICODE:IS_STRING, param->arg_info->class_name, param->arg_info->class_name_len, 1, 1, &pce TSRMLS_CC) == FAILURE) { zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Class %v does not exist", param->arg_info->class_name); return; diff --git a/ext/reflection/tests/bug39884.phpt b/ext/reflection/tests/bug39884.phpt new file mode 100644 index 0000000000..dbc57ee521 --- /dev/null +++ b/ext/reflection/tests/bug39884.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #39884 (ReflectionParameter::getClass() throws exception for type hint self) +--FILE-- +paramTest($test2); +$refParam = new ReflectionParameter(array('stubParamTest', 'paramTest'), 'param'); +var_dump($refParam->getClass()); +?> +--EXPECT-- +object(ReflectionClass)#4 (1) { + ["name"]=> + string(13) "stubParamTest" +} -- 2.50.1