com php-src: Fixed bug #74019 (Segfault with list): NEWS ext/opcache/Optimizer/zend_optimizer.c ext/opcache/tests/ bug74019.phpt
| From: | Xinchen Hui | Date: | Fri, 10 Feb 2017 06:24:01 +0000 |
| Subject: | com php-src: Fixed bug #74019 (Segfault with list): NEWS ext/opcache/Optimizer/zend_optimizer.c ext/opcache/tests/ bug74019.phpt | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-97046@lists.php.net to get a copy of this message | ||
Commit: 185304a61e08c07228e718139ef5284a7021bbbd
Author: Xinchen Hui <laruence@gmail.com> 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)