Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ext/opcache/jit/zend_jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -1164,7 +1164,7 @@ static void zend_jit_allocate_registers(zend_jit_ctx *ctx, const zend_op_array *
if (range->start > op_num) {
/* further blocks will not be relevant... */
break;
} else if (op_num < range->end && var_num == (range->var & ~ZEND_LIVE_MASK)) {
} else if (op_num < range->end && EX_NUM_TO_VAR(var_num) == (range->var & ~ZEND_LIVE_MASK)) {
/* check if opcodes in range may throw */
do {
if (zend_may_throw(op_array->opcodes + op_num, ssa->ops + op_num, op_array, ssa)) {
Expand Down
47 changes: 47 additions & 0 deletions ext/opcache/tests/jit/gh24988.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
--TEST--
GH-24988 (JIT: crash in cleanup_live_vars when % by zero throws mid-expression)
--CREDITS--
waroad
jorgsowa
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.jit_buffer_size=64M
opcache.jit=function
opcache.optimization_level=0
--EXTENSIONS--
opcache
--FILE--
<?php

class D {
function self() { return $this; }
function __destruct() { echo "dtor\n"; }
}

// Leaves a stale object in the frame slot deep() uses for its first temporary
function pollute($a, $b, $c) {
return $a->self()->self();
}

function deep(int $a, int $b, int $c) {
$a &= 255;
return ($a + 1) - ($b + $b + (($a + 1) % ($b % $c)));
}

$o = new D;
var_dump(deep(15, 3, 7));
pollute($o, 1, 2);
try {
deep(15, 3, 0);
} catch (DivisionByZeroError $e) {
echo $e->getMessage(), "\n";
}
echo "end\n";

?>
--EXPECT--
int(9)
Modulo by zero
end
dtor
Loading