Fixed bug #74152 (if statement says true to a null variable)
authorXinchen Hui <laruence@gmail.com>
Thu, 23 Feb 2017 04:33:17 +0000 (12:33 +0800)
committerXinchen Hui <laruence@gmail.com>
Thu, 23 Feb 2017 04:33:17 +0000 (12:33 +0800)
NEWS
ext/opcache/Optimizer/block_pass.c
ext/opcache/tests/bug74152.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index f5ae82bcfbcfbbfd1be2da89652887533961e462..d3a832895f815d4598196d73dae0b3881998cd26 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -43,6 +43,7 @@ PHP                                                                        NEWS
     (Andrew Nester, Nikita)
 
 - Opcache:
+  . Fixed bug #74152 (if statement says true to a null variable). (Laruence)
   . Fixed bug #74019 (Segfault with list). (Laruence)
 
 - OpenSSL:
index 862dfaf14432d1063568893333ce5fbcf447bd98..f69199b24e45299481c55739981ab2420ae23c29 100644 (file)
@@ -561,6 +561,17 @@ static void zend_rebuild_access_path(zend_cfg *cfg, zend_op_array *op_array, int
                convert_to_string((v)); \
        }
 
+static int is_predecessor_smart_branch(zend_op *start, zend_op *predecessor) {
+       do {
+               if (predecessor == start) {
+                       return 0;
+               }
+               predecessor--;
+       } while (predecessor->opcode == ZEND_NOP);
+
+       return zend_is_smart_branch(predecessor);
+}
+
 static void strip_nop(zend_code_block *block, zend_op_array *op_array, zend_optimizer_ctx *ctx)
 {
        zend_op *opline = block->start_opline;
@@ -602,8 +613,7 @@ static void strip_nop(zend_code_block *block, zend_op_array *op_array, zend_opti
                         && ((opline + 1)->opcode == ZEND_JMPZ
                          || (opline + 1)->opcode == ZEND_JMPNZ)
                         && (opline + 1)->op1_type & (IS_CV|IS_CONST)
-                        && opline > op_array->opcodes
-                        && zend_is_smart_branch(opline - 1)) {
+                        && is_predecessor_smart_branch(op_array->opcodes, opline)) {
                                /* don't remove NOP, that splits incorrect smart branch */
                                opline++;
                                break;
diff --git a/ext/opcache/tests/bug74152.phpt b/ext/opcache/tests/bug74152.phpt
new file mode 100644 (file)
index 0000000..f51c26b
--- /dev/null
@@ -0,0 +1,27 @@
+--TEST--
+Bug #74152 (if statement says true to a null variable)
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.optimization_level=-1
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$foo = 'foo';
+
+$bar = null;
+
+switch ($foo) {
+default:
+case 'foo':
+       if ($bar) {
+               echo 'true';
+       } else {
+               echo 'false';
+       }
+}
+?>
+--EXPECT--
+false