Bug #79177 [Opn]: FFI doesn't handle well PHP exceptions within callback body
| From: | lisachenko dot it at gmail dot com | Date: | Tue, 28 Jan 2020 08:40:48 +0000 |
| Subject: | Bug #79177 [Opn]: FFI doesn't handle well PHP exceptions within callback body | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-225183@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=79177&edit=1
ID: 79177
User updated by: lisachenko dot it at gmail dot com
Reported by: lisachenko dot it at gmail dot com
Summary: FFI doesn't handle well PHP exceptions within
callback body
Status: Open
Type: Bug
Package: *Extensibility Functions
Operating System: Unix
PHP Version: 7.4.2
Block user comment: N
Private report: N
New Comment:
Test example to reproduce this case:
use FFI\CData;
$php = FFI::cdef("
typedef unsigned int fake_struct;
typedef fake_struct* (*zend_write_func_t)(const char *str, size_t str_length);
extern zend_write_func_t zend_write;
");
echo "Before", PHP_EOL;
$originalHandler = clone $php->zend_write;
$php->zend_write = function($str, $len): CData {
throw new \RuntimeException('Not allowed');
};
try {
echo "After", PHP_EOL;
} catch (\Throwable $exception) {
// Do not output anything here, as handler is overridden
} finally {
$php->zend_write = $originalHandler;
}
echo get_class($exception), ': ', $exception->getMessage(), PHP_EOL;
// Output:
// Before
// FFI\Exception: Incompatible types when assigning to type 'uint32_t*' from PHP
'unknown'
// Expected:
// Before
// RuntimeException: Not allowed
Previous Comments:
------------------------------------------------------------------------
[2020-01-27 18:46:17] requinix@php.net
Example?
------------------------------------------------------------------------
[2020-01-27 18:05:51] lisachenko dot it at gmail dot com
Description:
------------
If we define a C callback handler in PHP and this handler should return a pointer (not a simple
value like int, float, etc), then FFI doesn't check if correct value was returned or not. For
example when we throw our custom exception within callback body.
This typically results in exception from FFI: Incompatible types when assigning to type 'struct
some_native_type*' from PHP 'unknown'
Exception is thrown because there is no check for Z_TYPE(retval) != IS_UNDEF inside FFI's
function zend_ffi_callback_trampoline before call to zend_ffi_zval_to_cdata(ret, ret_type,
&retval)
Expected result:
----------------
Exception is thrown within callback and not from FFI itself about missing type conversion
Actual result:
--------------
Incompatible types when assigning to type 'struct some_native_type*' from PHP
'unknown'
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=79177&edit=1