Description
Description
Hi,
Given an internal function named Acme\\example
with the following return type (a resource
):
zend_type return_type = {
.ptr = NULL,
.type_mask = MAY_BE_RESOURCE,
};
The following code:
<?php
$fn = new ReflectionFunction('Acme\\example');
$ty = $fn->getReturnType()?->getName();
var_dump($ty);
Resulted in this output:
Segmentation fault (core dumped).
GDB core dump:
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x000055d3178b7c25 in zim_ReflectionNamedType_getName (execute_data=0x7f23f7c1a4c0, return_value=0x7f23f7c1a2d0)
at /php-src/ext/reflection/php_reflection.c:3065
3065 RETURN_STR(zend_type_to_string_without_null(param->type));
(gdb) bt
#0 0x000055d3178b7c25 in zim_ReflectionNamedType_getName (execute_data=0x7f23f7c1a4c0, return_value=0x7f23f7c1a2d0)
at /php-src/ext/reflection/php_reflection.c:3065
#1 0x000055d317b6166a in ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER ()
at /php-src/Zend/zend_vm_execute.h:1976
#2 0x000055d317be151c in execute_ex (ex=0x7f23f7c18020)
at /php-src/Zend/zend_vm_execute.h:57246
#3 0x000055d317be5d57 in zend_execute (op_array=0x7f23f7c8c000, return_value=0x0)
at /php-src/Zend/zend_vm_execute.h:61598
#4 0x000055d317b1ad40 in zend_execute_scripts (type=8, retval=0x0, file_count=3)
at /php-src/Zend/zend.c:1881
#5 0x000055d317a562aa in php_execute_script (primary_file=0x7ffdf97060f0)
at /php-src/main/main.c:2501
#6 0x000055d317ca8772 in do_cli (argc=6, argv=0x55d31a302b80)
at /php-src/sapi/cli/php_cli.c:966
#7 0x000055d317ca953f in main (argc=6, argv=0x55d31a302b80)
at /php-src/sapi/cli/php_cli.c:1340
But I expected this output instead:
string(8) "resource"
There are two problems here.
The root is that zend_type_to_string
does not handle the MAY_BE_RESOURCE
flag, thus returning a NULL
pointer in this case.
Then, looking at the core dump, we can see that zim_ReflectionNamedType_getName
does not handle the NULL
pointer case, hence the segfault.
A possible fix would be to make zend_type_to_string
return "resource"
when the type is a resource. Eventhough this type is not nameable in userland PHP, it is a real type in the engine, and this information can be valuable to expose to the reflection API. This would be a breaking change though (i.e. a codegen tool using reflection type info, would now generate an invalid type).
Or maybe a ReflectionType::isResource()
method ?
Or just fix the null pointer dereference and call it a day...
WDYT?
PHP Version
PHP 8.3-dev
Operating System
irrelevant