]> granicus.if.org Git - php/commitdiff
Fix bug79177.phpt wrt. JIT
authorChristoph M. Becker <cmbecker69@gmx.de>
Fri, 30 Oct 2020 11:44:37 +0000 (12:44 +0100)
committerChristoph M. Becker <cmbecker69@gmx.de>
Fri, 30 Oct 2020 14:47:18 +0000 (15:47 +0100)
JIT ignores that the `zend_write` callback is overwritten, so we define
our own callback and caller.

We also fix the "inconsistent DLL binding" warnings on Windows, by
introducing `PHP_ZEND_TEST_API`.

Closes GH-6391.

ext/ffi/tests/bug79177.phpt
ext/zend_test/php_test.h
ext/zend_test/test.c

index d764437b2d50c773bbf7d356e86f9322692559ea..0667faa52dee99163b454577094da8cc76727589 100644 (file)
@@ -2,46 +2,41 @@
 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');
-}
+if (!extension_loaded('ffi')) die('skip ffi extension not available');
+if (!extension_loaded('zend-test')) die('skip zend-test extension 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());
+require_once __DIR__ . '/utils.inc';
+$header = <<<HEADER
+extern int *(*bug79177_cb)(void);
+void bug79177(void);
+HEADER;
 
-echo "Before\n";
+if (PHP_OS_FAMILY !== 'Windows') {
+    $ffi = FFI::cdef($header);
+} else {
+    try {
+        $ffi = FFI::cdef($header, 'php_zend_test.dll');
+    } catch (FFI\Exception $ex) {
+        $ffi = FFI::cdef($header, ffi_get_php_dll_name());
+    }
+}
 
-$originalHandler = clone $php->zend_write;
-$php->zend_write = function($str, $len): string {
+$ffi->bug79177_cb = function() {
     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;
-}
+    $ffi->bug79177(); // this is supposed to raise a fatal error
+} catch (\Throwable $exception) {}
+echo "done\n";
 ?>
 --EXPECTF--
-Before
-
 Warning: Uncaught RuntimeException: Not allowed in %s:%d
 Stack trace:
-#0 %s(%d): {closure}('After\n', 6)
-#1 {main}
+#0 %s(%d): {closure}()
+#1 %s(%d): FFI->bug79177()
+#2 {main}
   thrown in %s on line %d
 
 Fatal error: Throwing from FFI callbacks is not allowed in %s on line %d
index da57f7efc9a0e0eb6b75b755146ceab4032b5e76..03e6d836e29f56b40208cc0a7d1c35b0969b0f67 100644 (file)
@@ -37,7 +37,18 @@ struct bug79096 {
        uint64_t b;
 };
 
-ZEND_API struct bug79096 bug79096(void);
-ZEND_API void bug79532(off_t *array, size_t elems);
+#ifdef PHP_WIN32
+#      define PHP_ZEND_TEST_API __declspec(dllexport)
+#elif defined(__GNUC__) && __GNUC__ >= 4
+#      define PHP_ZEND_TEST_API __attribute__ ((visibility("default")))
+#else
+#      define PHP_ZEND_TEST_API
+#endif
+
+PHP_ZEND_TEST_API struct bug79096 bug79096(void);
+PHP_ZEND_TEST_API void bug79532(off_t *array, size_t elems);
+
+extern PHP_ZEND_TEST_API int *(*bug79177_cb)(void);
+PHP_ZEND_TEST_API void bug79177(void);
 
 #endif
index dfae54e880d6ca27120d9a468c6f5d199845c17a..4f81adc6ac11a4e1d99adbd721ff95814450e0e9 100644 (file)
@@ -336,3 +336,9 @@ void bug79532(off_t *array, size_t elems)
                array[i] = i;
        }
 }
+
+PHP_ZEND_TEST_API int *(*bug79177_cb)(void);
+void bug79177(void)
+{
+       bug79177_cb();
+}