Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions ext/ffi/ffi.c
Original file line number Diff line number Diff line change
Expand Up @@ -886,6 +886,11 @@ static void zend_ffi_callback_trampoline(ffi_cif* cif, void* ret, void** args, v
}
free_alloca(fci.params, use_heap);

if (EG(exception)) {
zend_throw_error(zend_ffi_exception_ce, "Uncaught %s in PHP FFI callback", ZSTR_VAL(EG(exception)->ce->name));
zend_exception_error(EG(exception), E_ERROR);
}

ret_type = ZEND_FFI_TYPE(callback_data->type->func.ret_type);
if (ret_type->kind != ZEND_FFI_TYPE_VOID) {
zend_ffi_zval_to_cdata(ret, ret_type, &retval);
Expand Down
49 changes: 49 additions & 0 deletions ext/ffi/tests/bug79177.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
--TEST--
Bug #79177 (FFI doesn't handle well PHP exceptions within callback)
--SKIPIF--
<?php
require_once('skipif.inc');
require_once('utils.inc');
try {
ffi_cdef("extern void *zend_printf;", ffi_get_php_dll_name());
} catch (Throwable $e) {
die('skip PHP symbols not available');
}
?>
--FILE--
<?php
require_once('utils.inc');
$php = ffi_cdef("
typedef char (*zend_write_func_t)(const char *str, size_t str_length);
extern zend_write_func_t zend_write;
", ffi_get_php_dll_name());

echo "Before\n";

$originalHandler = clone $php->zend_write;
$php->zend_write = function($str, $len): string {
throw new \RuntimeException('Not allowed');
};
try {
echo "After\n";
} catch (\Throwable $exception) {
// Do not output anything here, as handler is overridden
} finally {
$php->zend_write = $originalHandler;
}
if (isset($exception)) {
echo $exception->getMessage(), PHP_EOL;
}
?>
--EXPECTF--
Before

Fatal error: Uncaught RuntimeException: Not allowed in %s:%d
Stack trace:
#0 %s(15): {closure}('After\n', 6)
#1 {main}

Next FFI\Exception: Uncaught RuntimeException in PHP FFI callback in %s:%d
Stack trace:
#0 {main}
thrown in %s on line %d