php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #79177 FFI doesn't handle well PHP exceptions within callback body
Submitted: 2020-01-27 18:05 UTC Modified: 2020-10-21 17:27 UTC
From: lisachenko dot it at gmail dot com Assigned: cmb (profile)
Status: Closed Package: *Extensibility Functions
PHP Version: 7.4.2 OS: Unix
Private report: No CVE-ID: None
 [2020-01-27 18:05 UTC] 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'

Patches

Pull Requests

Pull requests:

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-01-27 18:46 UTC] requinix@php.net
Example?
 [2020-01-28 08:40 UTC] lisachenko dot it at gmail dot com
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
 [2020-10-21 17:27 UTC] cmb@php.net
The following pull request has been associated:

Patch Name: Fix #79177: FFI doesn't handle well PHP exceptions within callback
On GitHub:  https://github.com/php/php-src/pull/6366
Patch:      https://github.com/php/php-src/pull/6366.patch
 [2020-10-21 17:27 UTC] cmb@php.net
-Status: Open +Status: Verified -Assigned To: +Assigned To: cmb
 [2020-10-28 12:50 UTC] cmb@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=f547412cba52b499a4a130b0de1b6af2ea746e3a
Log: Fix #79177: FFI doesn't handle well PHP exceptions within callback
 [2020-10-28 12:50 UTC] cmb@php.net
-Status: Verified +Status: Closed
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 15:01:29 2024 UTC