Skip to content

Commit 9cd4371

Browse files
committed
Fixed bug #81225 (Wrong result with pow operator with JIT enabled)
1 parent 9fbcaa5 commit 9cd4371

File tree

3 files changed

+42
-3
lines changed

3 files changed

+42
-3
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ PHP NEWS
1111
- CGI:
1212
. Fixed bug #80849 (HTTP Status header truncation). (cmb)
1313

14+
- Opcache:
15+
. Fixed bug #81225 (Wrong result with pow operator with JIT enabled).
16+
(Dmitry)
17+
1418
- Standard:
1519
. Fixed bug #72146 (Integer overflow on substr_replace). (cmb)
1620
. Fixed bug #81265 (getimagesize returns 0 for 256px ICO images).

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4274,17 +4274,20 @@ static int zend_jit_math_long_long(dasm_State **Dst,
42744274
} else if (opcode == ZEND_ADD &&
42754275
!may_overflow &&
42764276
Z_MODE(op1_addr) == IS_REG &&
4277-
Z_MODE(op2_addr) == IS_CONST_ZVAL) {
4277+
Z_MODE(op2_addr) == IS_CONST_ZVAL &&
4278+
IS_SIGNED_32BIT(Z_LVAL_P(Z_ZV(op2_addr)))) {
42784279
| lea Ra(result_reg), [Ra(Z_REG(op1_addr))+Z_LVAL_P(Z_ZV(op2_addr))]
42794280
} else if (opcode == ZEND_ADD &&
42804281
!may_overflow &&
42814282
Z_MODE(op2_addr) == IS_REG &&
4282-
Z_MODE(op1_addr) == IS_CONST_ZVAL) {
4283+
Z_MODE(op1_addr) == IS_CONST_ZVAL &&
4284+
IS_SIGNED_32BIT(Z_LVAL_P(Z_ZV(op1_addr)))) {
42834285
| lea Ra(result_reg), [Ra(Z_REG(op2_addr))+Z_LVAL_P(Z_ZV(op1_addr))]
42844286
} else if (opcode == ZEND_SUB &&
42854287
!may_overflow &&
42864288
Z_MODE(op1_addr) == IS_REG &&
4287-
Z_MODE(op2_addr) == IS_CONST_ZVAL) {
4289+
Z_MODE(op2_addr) == IS_CONST_ZVAL &&
4290+
IS_SIGNED_32BIT(Z_LVAL_P(Z_ZV(op2_addr)))) {
42884291
| lea Ra(result_reg), [Ra(Z_REG(op1_addr))-Z_LVAL_P(Z_ZV(op2_addr))]
42894292
} else {
42904293
| GET_ZVAL_LVAL result_reg, op1_addr

ext/opcache/tests/jit/bug81225.phpt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
--TEST--
2+
Bug #81225: Wrong result with pow operator with JIT enabled
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.jit_buffer_size=1M
7+
opcache.jit=tracing
8+
--SKIPIF--
9+
<?php require_once('skipif.inc'); ?>
10+
--FILE--
11+
<?php
12+
13+
function unsignedLong(int $offset): int
14+
{
15+
$normalizedOffset = $offset % (2 ** 32);
16+
17+
if ($normalizedOffset < 0) {
18+
$normalizedOffset += 2 ** 32;
19+
}
20+
21+
return $normalizedOffset;
22+
}
23+
24+
$offset = -0x100000000 + 2;
25+
26+
for ($i = 0; $i < 200; ++$i) {
27+
assert(unsignedLong($offset) === 2);
28+
}
29+
?>
30+
OK
31+
--EXPECT--
32+
OK

0 commit comments

Comments
 (0)