|
2 | 2 | Bug #79177 (FFI doesn't handle well PHP exceptions within callback) |
3 | 3 | --SKIPIF-- |
4 | 4 | <?php |
5 | | -require_once('skipif.inc'); |
6 | | -require_once('utils.inc'); |
7 | | -try { |
8 | | - ffi_cdef("extern void *zend_printf;", ffi_get_php_dll_name()); |
9 | | -} catch (Throwable $e) { |
10 | | - die('skip PHP symbols not available'); |
11 | | -} |
| 5 | +if (!extension_loaded('ffi')) die('skip ffi extension not available'); |
| 6 | +if (!extension_loaded('zend-test')) die('skip zend-test extension not available'); |
12 | 7 | ?> |
13 | 8 | --FILE-- |
14 | 9 | <?php |
15 | | -require_once('utils.inc'); |
16 | | -$php = ffi_cdef(" |
17 | | -typedef char (*zend_write_func_t)(const char *str, size_t str_length); |
18 | | -extern zend_write_func_t zend_write; |
19 | | -", ffi_get_php_dll_name()); |
| 10 | +require_once __DIR__ . '/utils.inc'; |
| 11 | +$header = <<<HEADER |
| 12 | +extern int *(*bug79177_cb)(void); |
| 13 | +void bug79177(void); |
| 14 | +HEADER; |
20 | 15 |
|
21 | | -echo "Before\n"; |
| 16 | +if (PHP_OS_FAMILY !== 'Windows') { |
| 17 | + $ffi = FFI::cdef($header); |
| 18 | +} else { |
| 19 | + try { |
| 20 | + $ffi = FFI::cdef($header, 'php_zend_test.dll'); |
| 21 | + } catch (FFI\Exception $ex) { |
| 22 | + $ffi = FFI::cdef($header, ffi_get_php_dll_name()); |
| 23 | + } |
| 24 | +} |
22 | 25 |
|
23 | | -$originalHandler = clone $php->zend_write; |
24 | | -$php->zend_write = function($str, $len): string { |
| 26 | +$ffi->bug79177_cb = function() { |
25 | 27 | throw new \RuntimeException('Not allowed'); |
26 | 28 | }; |
27 | 29 | try { |
28 | | - echo "After\n"; |
29 | | -} catch (\Throwable $exception) { |
30 | | - // Do not output anything here, as handler is overridden |
31 | | -} finally { |
32 | | - $php->zend_write = $originalHandler; |
33 | | -} |
34 | | -if (isset($exception)) { |
35 | | - echo $exception->getMessage(), PHP_EOL; |
36 | | -} |
| 30 | + $ffi->bug79177(); // this is supposed to raise a fatal error |
| 31 | +} catch (\Throwable $exception) {} |
| 32 | +echo "done\n"; |
37 | 33 | ?> |
38 | 34 | --EXPECTF-- |
39 | | -Before |
40 | | - |
41 | 35 | Warning: Uncaught RuntimeException: Not allowed in %s:%d |
42 | 36 | Stack trace: |
43 | | -#0 %s(%d): {closure}('After\n', 6) |
44 | | -#1 {main} |
| 37 | +#0 %s(%d): {closure}() |
| 38 | +#1 %s(%d): FFI->bug79177() |
| 39 | +#2 {main} |
45 | 40 | thrown in %s on line %d |
46 | 41 |
|
47 | 42 | Fatal error: Throwing from FFI callbacks is not allowed in %s on line %d |
0 commit comments