Browse Source

- Fixed sefaults (tests added)

experimental/first_unicode_implementation
Christian Seiler 18 years ago
parent
commit
d40f3ef30e
  1. 39
      ext/reflection/php_reflection.c
  2. 25
      ext/reflection/tests/closures_003.phpt
  3. 27
      ext/reflection/tests/closures_004.phpt
  4. 31
      ext/reflection/tests/reflectionParameter_invalidMethodInConstructor.phpt

39
ext/reflection/php_reflection.c

@ -228,6 +228,28 @@ static void reflection_register_implement(zend_class_entry *class_entry, zend_cl
}
/* }}} */
static zend_function *_copy_function(zend_function *fptr TSRMLS_DC) /* {{{ */
{
if (fptr
&& fptr->type == ZEND_INTERNAL_FUNCTION
&& (fptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0)
{
zend_function *copy_fptr;
copy_fptr = emalloc(sizeof(zend_function));
memcpy(copy_fptr, fptr, sizeof(zend_function));
if (UG(unicode)) {
copy_fptr->internal_function.function_name.u = eustrdup(fptr->internal_function.function_name.u);
} else {
copy_fptr->internal_function.function_name.s = estrdup(fptr->internal_function.function_name.s);
}
return copy_fptr;
} else {
/* no copy needed */
return fptr;
}
}
/* }}} */
static void _free_function(zend_function *fptr TSRMLS_DC) /* {{{ */
{
if (fptr
@ -1812,7 +1834,7 @@ ZEND_METHOD(reflection_function, getParameters)
zval *parameter;
ALLOC_ZVAL(parameter);
reflection_parameter_factory(fptr, arg_info, i, fptr->common.required_num_args, parameter TSRMLS_CC);
reflection_parameter_factory(_copy_function(fptr TSRMLS_CC), arg_info, i, fptr->common.required_num_args, parameter TSRMLS_CC);
add_next_index_zval(return_value, parameter);
arg_info++;
@ -1956,7 +1978,7 @@ ZEND_METHOD(reflection_parameter, __construct)
} else if (zend_u_hash_find(&ce->function_table, Z_TYPE_PP(method), lcname, lcname_len + 1, (void **) &fptr) == FAILURE) {
efree(lcname.v);
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
"Method %R::%R() does not exist", Z_TYPE_PP(classref), Z_UNIVAL_PP(classref), Z_TYPE_PP(method), Z_UNIVAL_PP(method));
"Method %v::%R() does not exist", ce->name, Z_TYPE_PP(method), Z_UNIVAL_PP(method));
return;
}
efree(lcname.v);
@ -2064,9 +2086,9 @@ ZEND_METHOD(reflection_parameter, getDeclaringFunction)
GET_REFLECTION_OBJECT_PTR(param);
if (!param->fptr->common.scope) {
reflection_function_factory(param->fptr, return_value TSRMLS_CC);
reflection_function_factory(_copy_function(param->fptr TSRMLS_CC), return_value TSRMLS_CC);
} else {
reflection_method_factory(param->fptr->common.scope, param->fptr, return_value TSRMLS_CC);
reflection_method_factory(param->fptr->common.scope, _copy_function(param->fptr TSRMLS_CC), return_value TSRMLS_CC);
}
}
/* }}} */
@ -2458,7 +2480,14 @@ ZEND_METHOD(reflection_method, getClosure)
/* Returns from this function */
}
zend_create_closure(return_value, mptr, mptr->common.scope, obj TSRMLS_CC);
/* This is an original closure object and __invoke is to be called. */
if (Z_OBJCE_P(obj) == zend_ce_closure && mptr->type == ZEND_INTERNAL_FUNCTION &&
(mptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0)
{
RETURN_ZVAL(obj, 1, 0);
} else {
zend_create_closure(return_value, mptr, mptr->common.scope, obj TSRMLS_CC);
}
}
}
/* }}} */

25
ext/reflection/tests/closures_003.phpt

@ -0,0 +1,25 @@
--TEST--
Reflection on closures: Segfaults with getParameters() and getDeclaringFunction()
--FILE--
<?php
$closure = function($a, $b = 0) { };
$method = new ReflectionMethod ($closure);
$params = $method->getParameters ();
unset ($method);
$method = $params[0]->getDeclaringFunction ();
unset ($params);
echo $method->getName ()."\n";
$parameter = new ReflectionParameter ($closure, 'b');
$method = $parameter->getDeclaringFunction ();
unset ($parameter);
echo $method->getName ()."\n";
?>
===DONE===
--EXPECTF--
__invoke
__invoke
===DONE===

27
ext/reflection/tests/closures_004.phpt

@ -0,0 +1,27 @@
--TEST--
Reflection on closures: Segfault with getClosure() on closure itself
--FILE--
<?php
$closure = function() { echo "Invoked!\n"; };
$method = new ReflectionMethod ($closure);
$closure2 = $method->getClosure ($closure);
$closure2 ();
$closure2->__invoke ();
unset ($closure);
$closure2 ();
$closure2->__invoke ();
?>
===DONE===
--EXPECTF--
Invoked!
Invoked!
Invoked!
Invoked!
===DONE===

31
ext/reflection/tests/reflectionParameter_invalidMethodInConstructor.phpt

@ -0,0 +1,31 @@
--TEST--
ReflectionParameter::__construct(): Invalid method as constructor
--FILE--
<?php
// Invalid class name
try {
new ReflectionParameter (array ('A', 'b'), 0);
} catch (ReflectionException $e) { echo $e->getMessage ()."\n"; }
// Invalid class method
try {
new ReflectionParameter (array ('C', 'b'), 0);
} catch (ReflectionException $e) { echo $e->getMessage ()."\n"; }
// Invalid object method
try {
new ReflectionParameter (array (new C, 'b'), 0);
} catch (ReflectionException $e) { echo $e->getMessage ()."\n"; }
echo "Done.\n";
class C {
}
?>
--EXPECTF--
Class A does not exist
Method C::b() does not exist
Method C::b() does not exist
Done.
Loading…
Cancel
Save