summaryrefslogtreecommitdiff
path: root/src/tests/disable_function/disabled_function_echo_2.phpt
diff options
context:
space:
mode:
authorjvoisin2026-05-10 00:09:44 +0200
committerjvoisin2026-05-10 01:06:20 +0200
commit7d8180a29b2ac45ef1814a7a2cad8e4da937ac76 (patch)
tree6fdc236f5ded2320ba004118e6fcbf43ea84c91c /src/tests/disable_function/disabled_function_echo_2.phpt
parentbcec0cafc9edbf1a563f184debf01169aed64c85 (diff)
Prevent opcache from inlining functions with return-value rules on PHP 8.5+HEADmaster
PHP 8.5's opcache optimizer can inline trivial user functions (constant return values), completely eliminating the DO_UCALL opcode. When this happens, zend_execute_ex is never invoked and snuffleupagus's return-value monitoring hooks never fire. Fix this by setting ZEND_ACC_HAS_TYPE_HINTS on monitored functions' op_arrays during compilation (via sp_op_array_handler). This flag is checked by opcache's zend_try_inline_call() and prevents inlining. For 0-arg functions — the only ones eligible for inlining — there are no RECV opcodes, so the runtime impact is zero. To enable sp_op_array_handler when return-value rules are configured, the extension now registers itself as a zend extension and sets ZEND_COMPILE_HANDLE_OP_ARRAY (previously only done for global_strict). The disabled_function_echo_2 test is updated to use separate echo statements and opcache.optimization_level=0, since opcache's echo merging is a compile-time string concatenation that cannot be prevented per-function. This is a bit ugly, but it's the less awful solution to be able to hook return values.
Diffstat (limited to 'src/tests/disable_function/disabled_function_echo_2.phpt')
-rw-r--r--src/tests/disable_function/disabled_function_echo_2.phpt6
1 files changed, 4 insertions, 2 deletions
diff --git a/src/tests/disable_function/disabled_function_echo_2.phpt b/src/tests/disable_function/disabled_function_echo_2.phpt
index c1d9817..ce3488e 100644
--- a/src/tests/disable_function/disabled_function_echo_2.phpt
+++ b/src/tests/disable_function/disabled_function_echo_2.phpt
@@ -4,11 +4,13 @@ Echo hooking
4<?php if (!extension_loaded("snuffleupagus")) print "skip"; ?> 4<?php if (!extension_loaded("snuffleupagus")) print "skip"; ?>
5--INI-- 5--INI--
6sp.configuration_file={PWD}/config/disabled_function_echo.ini 6sp.configuration_file={PWD}/config/disabled_function_echo.ini
7opcache.optimization_level=0
7--FILE-- 8--FILE--
8<?php 9<?php
9echo "qwe"; 10echo "qwe";
10echo "1", "oops"; 11echo "1";
12echo "oops";
11?> 13?>
12--EXPECTF-- 14--EXPECTF--
13qwe1 15qwe1
14Fatal error: [snuffleupagus][0.0.0.0][disabled_function][drop] Aborted execution on call of the function 'echo' in %a/disabled_function_echo_2.php on line 3 16Fatal error: [snuffleupagus][0.0.0.0][disabled_function][drop] Aborted execution on call of the function 'echo' in %a/disabled_function_echo_2.php on line 4