From 7d8180a29b2ac45ef1814a7a2cad8e4da937ac76 Mon Sep 17 00:00:00 2001 From: jvoisin Date: Sun, 10 May 2026 00:09:44 +0200 Subject: Prevent opcache from inlining functions with return-value rules on PHP 8.5+ 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. --- src/tests/disable_function/disabled_function_echo_2.phpt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/tests') 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 --INI-- sp.configuration_file={PWD}/config/disabled_function_echo.ini +opcache.optimization_level=0 --FILE-- --EXPECTF-- qwe1 -Fatal 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 +Fatal 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 -- cgit v1.3