From 5059dca0a87383396fc51b34daef5a9b44a59509 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boris=20Mom=C4=8Dilovi=C4=87?= Date: Wed, 12 Jul 2023 21:59:57 +0200 Subject: [PATCH 1/4] fix #172: handle ZEND_VERIFY_NEVER_TYPE when uopz.exit is disabled --- src/handlers.c | 21 +++++++++++++++++---- tests/bugs/gh172.phpt | 29 +++++++++++++++++++++++++++++ tests/bugs/gh172a.phpt | 20 ++++++++++++++++++++ uopz.h | 4 ++++ 4 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 tests/bugs/gh172.phpt create mode 100644 tests/bugs/gh172a.phpt diff --git a/src/handlers.c b/src/handlers.c index b5ffade..2d0e8e0 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -29,7 +29,7 @@ ZEND_EXTERN_MODULE_GLOBALS(uopz); -#define UOPZ_HANDLERS_COUNT 12 +#define UOPZ_HANDLERS_COUNT 13 #ifdef ZEND_VM_FP_GLOBAL_REG # define UOPZ_OPCODE_HANDLER_ARGS @@ -99,6 +99,7 @@ typedef struct _uopz_vm_handler_t { } uopz_vm_handler_t; zend_vm_handler_t zend_vm_exit; +zend_vm_handler_t zend_vm_verify_never_type; zend_vm_handler_t zend_vm_new; zend_vm_handler_t zend_vm_fetch_constant; zend_vm_handler_t zend_vm_do_fcall; @@ -112,6 +113,7 @@ zend_vm_handler_t zend_vm_init_method_call; zend_vm_handler_t zend_vm_init_static_method_call; int uopz_vm_exit(UOPZ_OPCODE_HANDLER_ARGS); +int uopz_vm_verify_never_type(UOPZ_OPCODE_HANDLER_ARGS); int uopz_vm_new(UOPZ_OPCODE_HANDLER_ARGS); int uopz_vm_fetch_constant(UOPZ_OPCODE_HANDLER_ARGS); int uopz_vm_do_fcall(UOPZ_OPCODE_HANDLER_ARGS); @@ -125,6 +127,7 @@ int uopz_vm_init_static_method_call(UOPZ_OPCODE_HANDLER_ARGS); UOPZ_HANDLERS_DECL_BEGIN() UOPZ_HANDLER_DECL(ZEND_EXIT, exit) + UOPZ_HANDLER_DECL(ZEND_VERIFY_NEVER_TYPE, verify_never_type) UOPZ_HANDLER_DECL(ZEND_NEW, new) UOPZ_HANDLER_DECL(ZEND_FETCH_CONSTANT, fetch_constant) UOPZ_HANDLER_DECL(ZEND_FETCH_CLASS_CONSTANT, fetch_class_constant) @@ -155,7 +158,7 @@ void uopz_handlers_init(void) { void uopz_handlers_shutdown(void) { uopz_vm_handler_t *handler = uopz_vm_handlers; - + while (handler) { if (!handler->opcode) { break; @@ -173,6 +176,10 @@ static zend_always_inline int _uopz_vm_dispatch(UOPZ_OPCODE_HANDLER_ARGS) { zend = zend_vm_exit; break; + case ZEND_VERIFY_NEVER_TYPE: + zend = zend_vm_verify_never_type; + break; + case ZEND_NEW: zend = zend_vm_new; break; @@ -195,7 +202,7 @@ static zend_always_inline int _uopz_vm_dispatch(UOPZ_OPCODE_HANDLER_ARGS) { case ZEND_INIT_STATIC_METHOD_CALL: zend = zend_vm_init_static_method_call; - break; + break; case ZEND_FETCH_CONSTANT: zend = zend_vm_fetch_constant; @@ -267,6 +274,12 @@ int uopz_vm_exit(UOPZ_OPCODE_HANDLER_ARGS) { /* {{{ */ } } /* }}} */ +int uopz_vm_verify_never_type(UOPZ_OPCODE_HANDLER_ARGS) { /* {{{ */ + if (UOPZ(exit)) { + UOPZ_VM_DISPATCH(); + } else UOPZ_VM_RETURN(); +} /* }}} */ + int uopz_vm_new(UOPZ_OPCODE_HANDLER_ARGS) { /* {{{ */ UOPZ_USE_OPLINE; zval *result; @@ -274,7 +287,7 @@ int uopz_vm_new(UOPZ_OPCODE_HANDLER_ARGS) { /* {{{ */ zend_class_entry *ce; zend_execute_data *call; zend_object *obj = NULL; - + UOPZ_SAVE_OPLINE(); if (opline->op1_type == IS_CONST) { diff --git a/tests/bugs/gh172.phpt b/tests/bugs/gh172.phpt new file mode 100644 index 0000000..da60704 --- /dev/null +++ b/tests/bugs/gh172.phpt @@ -0,0 +1,29 @@ +--TEST-- +handle ZEND_VERIFY_NEVER_TYPE when uopz.exit disabled +--EXTENSIONS-- +uopz +--INI-- +uopz.disable=0 +uopz.exit=0 +opcache.enable_cli=0 +xdebug.enable=0 +--FILE-- + +--EXPECT-- +int(10) \ No newline at end of file diff --git a/tests/bugs/gh172a.phpt b/tests/bugs/gh172a.phpt new file mode 100644 index 0000000..2120931 --- /dev/null +++ b/tests/bugs/gh172a.phpt @@ -0,0 +1,20 @@ +--TEST-- +do not handle ZEND_VERIFY_NEVER_TYPE if not uopz_allow_exit +--EXTENSIONS-- +uopz +--INI-- +uopz.disable=0 +uopz.exit=1 +opcache.enable_cli=0 +xdebug.enable=0 +--FILE-- + +--EXPECTF-- +Fatal error: A never-returning function must not return in %s \ No newline at end of file diff --git a/uopz.h b/uopz.h index fb34298..e505d10 100644 --- a/uopz.h +++ b/uopz.h @@ -51,6 +51,10 @@ ZEND_END_MODULE_GLOBALS(uopz) #define uopz_exception(message, ...) zend_throw_exception_ex\ (spl_ce_RuntimeException, 0, message, ##__VA_ARGS__) +#if PHP_VERSION_ID < 80100 +#define ZEND_VERIFY_NEVER_TYPE 201 +#endif + #endif /* UOPZ_H */ /* From 6c07b8a020abdff73a08e4d4e9368a918ecbfb01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boris=20Mom=C4=8Dilovi=C4=87?= Date: Fri, 14 Jul 2023 00:39:38 +0200 Subject: [PATCH 2/4] tests: skip if not PHP 8.1 #172 --- tests/bugs/gh172.phpt | 5 +++++ tests/bugs/gh172a.phpt | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/tests/bugs/gh172.phpt b/tests/bugs/gh172.phpt index da60704..72d6d35 100644 --- a/tests/bugs/gh172.phpt +++ b/tests/bugs/gh172.phpt @@ -1,5 +1,10 @@ --TEST-- handle ZEND_VERIFY_NEVER_TYPE when uopz.exit disabled +--SKIPIF-- + Date: Fri, 14 Jul 2023 00:56:19 +0200 Subject: [PATCH 3/4] tests: skip if not PHP 8.1 #172 --- tests/bugs/gh172.phpt | 8 +++++--- tests/bugs/gh172a.phpt | 7 ++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/bugs/gh172.phpt b/tests/bugs/gh172.phpt index 72d6d35..7aab6a6 100644 --- a/tests/bugs/gh172.phpt +++ b/tests/bugs/gh172.phpt @@ -1,12 +1,13 @@ --TEST-- handle ZEND_VERIFY_NEVER_TYPE when uopz.exit disabled +--EXTENSIONS-- +uopz --SKIPIF-- Date: Wed, 7 Aug 2024 12:42:02 +0200 Subject: [PATCH 4/4] handlers: ZEND_VERIFY_NEVER_TYPE conditional for PHP 8.1+ --- src/handlers.c | 14 ++++++++++++++ uopz.h | 4 ---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/handlers.c b/src/handlers.c index 2d0e8e0..ef4ba4a 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -29,7 +29,11 @@ ZEND_EXTERN_MODULE_GLOBALS(uopz); +#if PHP_VERSION_ID >= 80100 #define UOPZ_HANDLERS_COUNT 13 +#else +#define UOPZ_HANDLERS_COUNT 12 +#endif #ifdef ZEND_VM_FP_GLOBAL_REG # define UOPZ_OPCODE_HANDLER_ARGS @@ -99,7 +103,9 @@ typedef struct _uopz_vm_handler_t { } uopz_vm_handler_t; zend_vm_handler_t zend_vm_exit; +#if PHP_VERSION_ID >= 80100 zend_vm_handler_t zend_vm_verify_never_type; +#endif zend_vm_handler_t zend_vm_new; zend_vm_handler_t zend_vm_fetch_constant; zend_vm_handler_t zend_vm_do_fcall; @@ -113,7 +119,9 @@ zend_vm_handler_t zend_vm_init_method_call; zend_vm_handler_t zend_vm_init_static_method_call; int uopz_vm_exit(UOPZ_OPCODE_HANDLER_ARGS); +#if PHP_VERSION_ID >= 80100 int uopz_vm_verify_never_type(UOPZ_OPCODE_HANDLER_ARGS); +#endif int uopz_vm_new(UOPZ_OPCODE_HANDLER_ARGS); int uopz_vm_fetch_constant(UOPZ_OPCODE_HANDLER_ARGS); int uopz_vm_do_fcall(UOPZ_OPCODE_HANDLER_ARGS); @@ -127,7 +135,9 @@ int uopz_vm_init_static_method_call(UOPZ_OPCODE_HANDLER_ARGS); UOPZ_HANDLERS_DECL_BEGIN() UOPZ_HANDLER_DECL(ZEND_EXIT, exit) +#if PHP_VERSION_ID >= 80100 UOPZ_HANDLER_DECL(ZEND_VERIFY_NEVER_TYPE, verify_never_type) +#endif UOPZ_HANDLER_DECL(ZEND_NEW, new) UOPZ_HANDLER_DECL(ZEND_FETCH_CONSTANT, fetch_constant) UOPZ_HANDLER_DECL(ZEND_FETCH_CLASS_CONSTANT, fetch_class_constant) @@ -176,9 +186,11 @@ static zend_always_inline int _uopz_vm_dispatch(UOPZ_OPCODE_HANDLER_ARGS) { zend = zend_vm_exit; break; +#if PHP_VERSION_ID >= 80100 case ZEND_VERIFY_NEVER_TYPE: zend = zend_vm_verify_never_type; break; +#endif case ZEND_NEW: zend = zend_vm_new; @@ -274,11 +286,13 @@ int uopz_vm_exit(UOPZ_OPCODE_HANDLER_ARGS) { /* {{{ */ } } /* }}} */ +#if PHP_VERSION_ID >= 80100 int uopz_vm_verify_never_type(UOPZ_OPCODE_HANDLER_ARGS) { /* {{{ */ if (UOPZ(exit)) { UOPZ_VM_DISPATCH(); } else UOPZ_VM_RETURN(); } /* }}} */ +#endif int uopz_vm_new(UOPZ_OPCODE_HANDLER_ARGS) { /* {{{ */ UOPZ_USE_OPLINE; diff --git a/uopz.h b/uopz.h index e505d10..fb34298 100644 --- a/uopz.h +++ b/uopz.h @@ -51,10 +51,6 @@ ZEND_END_MODULE_GLOBALS(uopz) #define uopz_exception(message, ...) zend_throw_exception_ex\ (spl_ce_RuntimeException, 0, message, ##__VA_ARGS__) -#if PHP_VERSION_ID < 80100 -#define ZEND_VERIFY_NEVER_TYPE 201 -#endif - #endif /* UOPZ_H */ /*