|
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