Skip to content

Commit 7d48341

Browse files
committed
Fix relative offsets when copying JMPZNZ
This was doing a plain copy of JMPZNZ, even though it encodes offsets relative to the opline. As such, the offsets would be relative to target, while they should be relative to opline. Fix this by recomputing them. Fixes oss-fuzz #39295.
1 parent 823888c commit 7d48341

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
Check for correct treatment of relative JMPZNZ offsets when copying opline
3+
--FILE--
4+
<?php
5+
function test($c) {
6+
L1:
7+
if ($c) {
8+
goto L1;
9+
goto L1;
10+
}
11+
}
12+
test(false);
13+
?>
14+
===DONE===
15+
--EXPECT--
16+
===DONE===

ext/opcache/Optimizer/pass3.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx)
9595
ZVAL_COPY(&zv, &ZEND_OP1_LITERAL(opline));
9696
opline->op1.constant = zend_optimizer_add_literal(op_array, &zv);
9797
}
98+
/* Jump addresses may be encoded as offsets, recompute them. */
99+
ZEND_SET_OP_JMP_ADDR(opline, opline->op2, ZEND_OP2_JMP_ADDR(target));
100+
opline->extended_value = ZEND_OPLINE_TO_OFFSET(opline,
101+
ZEND_OFFSET_TO_OPLINE(target, target->extended_value));
98102
goto optimize_jmpznz;
99103
} else if ((target->opcode == ZEND_RETURN ||
100104
target->opcode == ZEND_RETURN_BY_REF ||

0 commit comments

Comments
 (0)