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)