- DOM:
. Fixed bug #80268 (loadHTML() truncates at NUL bytes). (cmb)
+- FFI:
+ . Fixed bug #79177 (FFI doesn't handle well PHP exceptions within callback).
+ (cmb, Dmitry, Nikita)
+
- IMAP:
. Fixed bug #64076 (imap_sort() does not return FALSE on failure). (cmb)
. Fixed bug #76618 (segfault on imap_reopen). (girgias)
}
free_alloca(fci.params, use_heap);
+ if (EG(exception)) {
+ zend_error(E_ERROR, "Throwing from FFI callbacks is not allowed");
+ }
+
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);
--- /dev/null
+--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
+
+Warning: Uncaught RuntimeException: Not allowed in %s:%d
+Stack trace:
+#0 %s(%d): {closure}('After\n', 6)
+#1 {main}
+ thrown in %s on line %d
+
+Fatal error: Throwing from FFI callbacks is not allowed in %s on line %d