summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2021-03-17 22:59:59 +0300
committerDmitry Stogov <dmitry@zend.com>2021-03-17 22:59:59 +0300
commit7e494d92258b0150e228bae82021a92b64e415b8 (patch)
tree028177d39c5d1dc712ffd3f979b6586b4c3cec04
parent34e39ebaf51803a7c8e4c470163c76b7bcbd7dfb (diff)
downloadphp-git-7e494d92258b0150e228bae82021a92b64e415b8.tar.gz
Fixed bug #80861 (erronous array key overflow in 2D array with JIT)
-rw-r--r--NEWS2
-rw-r--r--ext/opcache/jit/zend_jit_x86.dasc2
-rw-r--r--ext/opcache/tests/jit/bug80861.phpt111
3 files changed, 114 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index ac6b906aba..07451ebd00 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,8 @@ PHP NEWS
- Opcache:
. Fixed bug #80839 (PHP problem with JIT). (Dmitry)
+ . Fixed bug #80861 (erronous array key overflow in 2D array with JIT).
+ (Dmitry)
01 Apr 2021, PHP 8.0.4
diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc
index 04243cf34a..3b96db9361 100644
--- a/ext/opcache/jit/zend_jit_x86.dasc
+++ b/ext/opcache/jit/zend_jit_x86.dasc
@@ -15511,7 +15511,7 @@ static zend_regset zend_jit_get_scratch_regset(const zend_op *opline, const zend
op2_info = OP2_INFO();
if (opline->op1_type == IS_CV
&& !(op2_info & MAY_BE_UNDEF)
- && !(op1_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_RESOURCE|MAY_BE_REF))) {
+ && !(op1_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))) {
if ((op2_info & (MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_DOUBLE) {
regset = ZEND_REGSET(ZREG_XMM0);
} else if ((op2_info & (MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_LONG) {
diff --git a/ext/opcache/tests/jit/bug80861.phpt b/ext/opcache/tests/jit/bug80861.phpt
new file mode 100644
index 0000000000..3ae93d66d7
--- /dev/null
+++ b/ext/opcache/tests/jit/bug80861.phpt
@@ -0,0 +1,111 @@
+--TEST--
+Bug #80839: PHP problem with JIT
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.jit_buffer_size=1M
+opcache.jit=tracing
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+declare(strict_types=1);
+
+// --------------------------------------------------------------------
+class Node
+{
+ public $column = null;
+ public $left = null;
+ public $right = null;
+ public $up = null;
+ public $down = null;
+
+ public static function joinLR(Node $a, Node $b): void
+ {
+ $a->right = $b;
+ $b->left = $a;
+ }
+
+ public static function joinDU(Node $a, Node $b): void
+ {
+ $a->up = $b;
+ $b->down = $a;
+ }
+}
+
+// --------------------------------------------------------------------
+class Column extends Node
+{
+ public function __construct()
+ {
+ $this->column = $this;
+ $this->up = $this;
+ $this->down = $this;
+ }
+}
+
+// --------------------------------------------------------------------
+class Matrix
+{
+ public $head = null;
+
+ public function __construct()
+ {
+ $this->head = new Node();
+ Node::joinLR($this->head, $this->head);
+ }
+
+ // $from is array[][] of bool
+ public static function fromArray(array $from): Matrix
+ {
+ $m = new Matrix();
+ $rowCount = count($from);
+ if ($rowCount == 0) {
+ return $m;
+ }
+ $columnCount = count($from[0]);
+ if ($columnCount == 0) {
+ return $m;
+ }
+ // we generate 2D double linked circular list of nodes from the input 2D bool array
+ // might be not relevant for the bug
+ $c = new Column();
+ Node::joinLR($m->head, $c);
+ for ($j = 1; $j < $columnCount; $j++) {
+ $nextCol = new Column();
+ Node::joinLR($c, $nextCol);
+ $c = $c->right;
+ }
+ Node::joinLR($c, $m->head);
+ $c = $m->head->right;
+ error_log("These are the array bounds: $rowCount * $columnCount");
+ for ($j = 0; $j < $columnCount; $j++) {
+ $prev = $c;
+ for ($i = 0; $i < $rowCount; $i++) {
+ // next line generates the warnings despite $i and $j is within bounds
+ if ($from[$i][$j]) {
+ $node = new Node();
+ $node->column = $c;
+ Node::joinDU($node, $prev);
+ Node::joinLR($node, $node);
+ $prev = $node;
+ // ... code to generate $m excluded
+ }
+ }
+ Node::joinDU($c, $prev);
+ $c = $c->right;
+ }
+ return $m;
+ }
+}
+
+// --------------------------------------------------------------------
+// simple driver code - fills up a 2D bool matrix and calls the static matrix constructing function above
+for ($y = 0; $y < 10; $y++) {
+ for ($x = 0; $x < 10; $x++) {
+ $a[$y][$x] = true;
+ }
+}
+$m = Matrix::fromArray($a);
+--EXPECT--
+These are the array bounds: 10 * 10