Skip to content

Commit

Permalink
fix krakjoe#172: handle ZEND_VERIFY_NEVER_TYPE when uopz.exit is disa…
Browse files Browse the repository at this point in the history
…bled
  • Loading branch information
kornrunner committed Jul 12, 2023
1 parent 514e2c2 commit bf6fe81
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 4 deletions.
21 changes: 17 additions & 4 deletions src/handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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)
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -267,14 +274,20 @@ 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;
zend_function *constructor;
zend_class_entry *ce;
zend_execute_data *call;
zend_object *obj = NULL;

UOPZ_SAVE_OPLINE();

if (opline->op1_type == IS_CONST) {
Expand Down
4 changes: 4 additions & 0 deletions src/handlers.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
void uopz_handlers_init(void);
void uopz_handlers_shutdown(void);

#ifndef ZEND_VERIFY_RETURN_TYPE
#define ZEND_VERIFY_RETURN_TYPE 124
#endif

#endif /* UOPZ_HANDLERS_H */

/*
Expand Down
29 changes: 29 additions & 0 deletions tests/bugs/gh172.phpt
Original file line number Diff line number Diff line change
@@ -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--
<?php

function x(): never {
exit(10);
}

x();

var_dump(uopz_get_exit_status());

uopz_allow_exit(true);

exit(20);

echo "not here\n";

?>
--EXPECT--
int(10)
20 changes: 20 additions & 0 deletions tests/bugs/gh172a.phpt
Original file line number Diff line number Diff line change
@@ -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--
<?php

function x(): never {
return "here";
}
x();

?>
--EXPECTF--
Fatal error: A never-returning function must not return in %s

0 comments on commit bf6fe81

Please sign in to comment.