From: Christoph M. Becker Date: Wed, 28 Oct 2020 11:01:28 +0000 (+0100) Subject: Fix #79177: FFI doesn't handle well PHP exceptions within callback X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f547412cba52b499a4a130b0de1b6af2ea746e3a;p=php Fix #79177: FFI doesn't handle well PHP exceptions within callback We have to error on unhandled exceptions in FFI callbacks, to avoid passing back undefined values. This has been discussed and agreed upon in a previous PR[1]. [1] Closes GH-6366. --- diff --git a/NEWS b/NEWS index 95de673b3f..017896befa 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,10 @@ PHP NEWS - 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) diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index f350f91d8a..d119ea050c 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -886,6 +886,10 @@ static void zend_ffi_callback_trampoline(ffi_cif* cif, void* ret, void** args, v } 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); diff --git a/ext/ffi/tests/bug79177.phpt b/ext/ffi/tests/bug79177.phpt new file mode 100644 index 0000000000..d764437b2d --- /dev/null +++ b/ext/ffi/tests/bug79177.phpt @@ -0,0 +1,47 @@ +--TEST-- +Bug #79177 (FFI doesn't handle well PHP exceptions within callback) +--SKIPIF-- + +--FILE-- +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