Skip to content

Commit eb8f5e4

Browse files
committed
Merge branch 'PHP-8.0'
* PHP-8.0: Fixed bug #80861 (erronous array key overflow in 2D array with JIT)
2 parents d628d7e + 7e494d9 commit eb8f5e4

File tree

2 files changed

+112
-1
lines changed

2 files changed

+112
-1
lines changed

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15514,7 +15514,7 @@ static zend_regset zend_jit_get_scratch_regset(const zend_op *opline, const zend
1551415514
op2_info = OP2_INFO();
1551515515
if (opline->op1_type == IS_CV
1551615516
&& !(op2_info & MAY_BE_UNDEF)
15517-
&& !(op1_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_RESOURCE|MAY_BE_REF))) {
15517+
&& !(op1_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))) {
1551815518
if ((op2_info & (MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_DOUBLE) {
1551915519
regset = ZEND_REGSET(ZREG_XMM0);
1552015520
} else if ((op2_info & (MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_LONG) {

ext/opcache/tests/jit/bug80861.phpt

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
--TEST--
2+
Bug #80839: PHP problem with JIT
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+
declare(strict_types=1);
13+
14+
// --------------------------------------------------------------------
15+
class Node
16+
{
17+
public $column = null;
18+
public $left = null;
19+
public $right = null;
20+
public $up = null;
21+
public $down = null;
22+
23+
public static function joinLR(Node $a, Node $b): void
24+
{
25+
$a->right = $b;
26+
$b->left = $a;
27+
}
28+
29+
public static function joinDU(Node $a, Node $b): void
30+
{
31+
$a->up = $b;
32+
$b->down = $a;
33+
}
34+
}
35+
36+
// --------------------------------------------------------------------
37+
class Column extends Node
38+
{
39+
public function __construct()
40+
{
41+
$this->column = $this;
42+
$this->up = $this;
43+
$this->down = $this;
44+
}
45+
}
46+
47+
// --------------------------------------------------------------------
48+
class Matrix
49+
{
50+
public $head = null;
51+
52+
public function __construct()
53+
{
54+
$this->head = new Node();
55+
Node::joinLR($this->head, $this->head);
56+
}
57+
58+
// $from is array[][] of bool
59+
public static function fromArray(array $from): Matrix
60+
{
61+
$m = new Matrix();
62+
$rowCount = count($from);
63+
if ($rowCount == 0) {
64+
return $m;
65+
}
66+
$columnCount = count($from[0]);
67+
if ($columnCount == 0) {
68+
return $m;
69+
}
70+
// we generate 2D double linked circular list of nodes from the input 2D bool array
71+
// might be not relevant for the bug
72+
$c = new Column();
73+
Node::joinLR($m->head, $c);
74+
for ($j = 1; $j < $columnCount; $j++) {
75+
$nextCol = new Column();
76+
Node::joinLR($c, $nextCol);
77+
$c = $c->right;
78+
}
79+
Node::joinLR($c, $m->head);
80+
$c = $m->head->right;
81+
error_log("These are the array bounds: $rowCount * $columnCount");
82+
for ($j = 0; $j < $columnCount; $j++) {
83+
$prev = $c;
84+
for ($i = 0; $i < $rowCount; $i++) {
85+
// next line generates the warnings despite $i and $j is within bounds
86+
if ($from[$i][$j]) {
87+
$node = new Node();
88+
$node->column = $c;
89+
Node::joinDU($node, $prev);
90+
Node::joinLR($node, $node);
91+
$prev = $node;
92+
// ... code to generate $m excluded
93+
}
94+
}
95+
Node::joinDU($c, $prev);
96+
$c = $c->right;
97+
}
98+
return $m;
99+
}
100+
}
101+
102+
// --------------------------------------------------------------------
103+
// simple driver code - fills up a 2D bool matrix and calls the static matrix constructing function above
104+
for ($y = 0; $y < 10; $y++) {
105+
for ($x = 0; $x < 10; $x++) {
106+
$a[$y][$x] = true;
107+
}
108+
}
109+
$m = Matrix::fromArray($a);
110+
--EXPECT--
111+
These are the array bounds: 10 * 10

0 commit comments

Comments
 (0)