Skip to content

Commit 6de8b08

Browse files
committed
Don't undef result operand if there is none
The mod_by_zero and negative_shift helper may also be used by ASSIGN_OP, in which case there is not necessarily a result operand. If the stars aligned just right, this used to clobber other parts of the call frame. For these two helpers, check whether the result_type is TMP/VAR before setting to UNDEF:
1 parent 23327bf commit 6de8b08

File tree

2 files changed

+40
-2
lines changed

2 files changed

+40
-2
lines changed

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,15 @@ static void* dasm_labels[zend_lb_MAX];
558558
| SET_Z_TYPE_INFO FP + r0, IS_UNDEF
559559
|.endmacro
560560

561+
|.macro UNDEF_OPLINE_RESULT_IF_USED
562+
| mov r0, EX->opline
563+
| test byte OP:r0->result_type, (IS_TMP_VAR|IS_VAR)
564+
| jz >1
565+
| mov eax, dword OP:r0->result.var
566+
| SET_Z_TYPE_INFO FP + r0, IS_UNDEF
567+
|1:
568+
|.endmacro
569+
561570
|.macro SSE_AVX_INS, sse_ins, avx_ins, op1, op2
562571
|| if (CAN_USE_AVX()) {
563572
| avx_ins op1, op2
@@ -2139,7 +2148,7 @@ static int zend_jit_undefined_function_stub(dasm_State **Dst)
21392148
static int zend_jit_negative_shift_stub(dasm_State **Dst)
21402149
{
21412150
|->negative_shift:
2142-
| UNDEF_OPLINE_RESULT
2151+
| UNDEF_OPLINE_RESULT_IF_USED
21432152
|.if X64
21442153
|.if WIN
21452154
| LOAD_ADDR CARG1, &zend_ce_arithmetic_error
@@ -2168,7 +2177,7 @@ static int zend_jit_negative_shift_stub(dasm_State **Dst)
21682177
static int zend_jit_mod_by_zero_stub(dasm_State **Dst)
21692178
{
21702179
|->mod_by_zero:
2171-
| UNDEF_OPLINE_RESULT
2180+
| UNDEF_OPLINE_RESULT_IF_USED
21722181
|.if X64
21732182
|.if WIN
21742183
| LOAD_ADDR CARG1, &zend_ce_division_by_zero_error
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
JIT ASSIGN_OP: 001
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.file_update_protection=0
7+
opcache.jit_buffer_size=1M
8+
--FILE--
9+
<?php
10+
function test1($a) {
11+
$a %= 0;
12+
}
13+
function test2($a) {
14+
$a <<= -1;
15+
}
16+
try {
17+
test1(1);
18+
} catch (DivisionByZeroError $e) {
19+
echo $e->getMessage(), "\n";
20+
}
21+
try {
22+
test2(1);
23+
} catch (ArithmeticError $e) {
24+
echo $e->getMessage(), "\n";
25+
}
26+
?>
27+
--EXPECT--
28+
Modulo by zero
29+
Bit shift by negative number

0 commit comments

Comments
 (0)