com php-src: Fixed bug #74019 (Segfault with list): NEWS ext/opcache/Optimizer/zend_optimizer.c ext/opcache/tests/ bug74019.phpt

[email protected] (Xinchen Hui)
Newsgroups php.cvs
Message-ID <[email protected]>
Commit:    185304a61e08c07228e718139ef5284a7021bbbd
Author:    Xinchen Hui <[email protected]>         Fri, 10 Feb 2017 14:24:01 +0800
Parents:   80c8d84af303d2fddc9ba9f181c7117b9040811d
Branches:  PHP-7.0 PHP-7.1 master

Link:       http://git.php.net/?p=php-src.git;a=commitdiff;h=185304a61e08c07228e718139ef5284a7021bbbd

Log:
Fixed bug #74019 (Segfault with list)

Bugs:
https://bugs.php.net/74019

Changed paths:
  M  NEWS
  M  ext/opcache/Optimizer/zend_optimizer.c
  A  ext/opcache/tests/bug74019.phpt


Diff:
diff --git a/NEWS b/NEWS
index 5ff0ee7..ccd6c85 100644
--- a/NEWS
+++ b/NEWS
@@ -18,6 +18,9 @@ PHP                                                                        NEWS
   . Fixed bug #74031 (ReflectionFunction for imagepng is missing last two
     parameters). (finwe)
 
+- Opcache:
+  . Fixed bug #74019 (Segfault with list). (Laruence)
+
 - OpenSSL:
   . Fixed bug #74022 (PHP Fast CGI crashes when reading from a pfx file).
     (Anatol)
diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c
index dd3b6bd..7ae0e06 100644
--- a/ext/opcache/Optimizer/zend_optimizer.c
+++ b/ext/opcache/Optimizer/zend_optimizer.c
@@ -406,12 +406,26 @@ int zend_optimizer_replace_by_const(zend_op_array *op_array,
 					break;
 				/* In most cases IS_TMP_VAR operand may be used only once.
 				 * The operands are usually destroyed by the opcode handler.
-				 * ZEND_CASE is an exception, that keeps operand unchanged,
-				 * and allows its reuse. The number of ZEND_CASE instructions
+				 * ZEND_CASE and ZEND_FETCH_LIST are exceptions, they keeps operand
+				 * unchanged, and allows its reuse. these instructions
 				 * usually terminated by ZEND_FREE that finally kills the value.
 				 */
-				case ZEND_FREE:
-				case ZEND_CASE: {
+				case ZEND_FETCH_LIST: {
+					zend_op *m = opline;
+					do {
+						if (m->opcode == ZEND_FETCH_LIST &&
+							ZEND_OP1_TYPE(m) == type &&
+							ZEND_OP1(m).var == var) {
+							zend_optimizer_update_op1_const(op_array, m, val);
+						}
+						m++;
+					} while (m->opcode != ZEND_FREE || ZEND_OP1_TYPE(m) != type || ZEND_OP1(m).var != var);
+					ZEND_ASSERT(m->opcode == ZEND_FREE && ZEND_OP1_TYPE(m) == type && ZEND_OP1(m).var == var);
+					MAKE_NOP(m);
+					return 1;
+				}
+				case ZEND_CASE:
+				case ZEND_FREE: {
 					zend_op *m, *n;
 					int brk = op_array->last_brk_cont;
 					zend_bool in_switch = 0;
diff --git a/ext/opcache/tests/bug74019.phpt b/ext/opcache/tests/bug74019.phpt
new file mode 100644
index 0000000..210e223
--- /dev/null
+++ b/ext/opcache/tests/bug74019.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Bug #74019	(Segfault with list)
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+class A {
+	public function seg() {
+		list($a, $b) = A::CONSTS;
+		var_dump($a, $b);
+		return;
+	}
+	const CONSTS = [1, 2];
+}
+
+$a = new A;
+$a->seg();
+?>
+--EXPECT--
+int(1)
+int(2)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.