]> granicus.if.org Git - php/commitdiff
Fix bug #76281
authorNikita Popov <nikita.ppv@gmail.com>
Fri, 27 Apr 2018 20:17:59 +0000 (22:17 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Fri, 27 Apr 2018 20:21:59 +0000 (22:21 +0200)
Make sure we keep the smart-branch inhibiting NOP even if there
are multiple NOPs in sequence.

NEWS
ext/opcache/Optimizer/dfa_pass.c
ext/opcache/tests/bug76281.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index c9b985012e6bb532aecd0e7e84275a0ed0ad275c..02a936700874d5d458ae2de9f8273cda149540d2 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,8 @@ PHP                                                                        NEWS
 - Opcache:
   . Fixed bug #76275 (Assertion failure in file cache when unserializing empty
     try_catch_array). (Nikita)
+  . Fixed bug #76281 (Opcache causes incorrect "undefined variable" errors).
+    (Nikita)
 
 - Reflection:
   . Fixed arginfo for array_replace(_recursive) and array_merge(_recursive).
index bb22665594ce979a5aa2d854ab1f5c8d2809b077..34d5de835a47fb2fa65ee26c9d79b1a9ed07fe6c 100644 (file)
@@ -144,12 +144,13 @@ static void zend_ssa_remove_nops(zend_op_array *op_array, zend_ssa *ssa)
                        while (i < end) {
                                shiftlist[i] = i - target;
                                if (EXPECTED(op_array->opcodes[i].opcode != ZEND_NOP) ||
-                                  /*keep NOP to support ZEND_VM_SMART_BRANCH */
-                                  (i > 0 &&
+                                  /* Keep NOP to support ZEND_VM_SMART_BRANCH. Using "target-1" instead of
+                                   * "i-1" here to check the last non-NOP instruction. */
+                                  (target > 0 &&
                                    i + 1 < op_array->last &&
                                    (op_array->opcodes[i+1].opcode == ZEND_JMPZ ||
                                     op_array->opcodes[i+1].opcode == ZEND_JMPNZ) &&
-                                   zend_is_smart_branch(op_array->opcodes + i - 1))) {
+                                   zend_is_smart_branch(op_array->opcodes + target - 1))) {
                                        if (i != target) {
                                                op_array->opcodes[target] = op_array->opcodes[i];
                                                ssa->ops[target] = ssa->ops[i];
diff --git a/ext/opcache/tests/bug76281.phpt b/ext/opcache/tests/bug76281.phpt
new file mode 100644 (file)
index 0000000..83c42f3
--- /dev/null
@@ -0,0 +1,28 @@
+--TEST--
+Bug #76281: Opcache causes incorrect "undefined variable" errors
+--FILE--
+<?php
+
+function test($r, $action) {
+    $user_sub_resource = in_array($action, array('get_securityquestions', 'get_status', 'get_groupstats'));
+
+    $user_id = null;
+    if ($user_sub_resource && isset($r['user_id'])) {
+        $user_id = $r['user_id'];
+    }
+    else if (isset($r['id']))  {
+        $user_id = $r['id'];
+    }
+
+    if ($user_sub_resource) {
+        return 'foo';
+    }
+
+    return 'bar';
+}
+
+var_dump(test(['user_id' => 1, 'id' => 2], 'foo'));
+
+?>
+--EXPECT--
+string(3) "bar"