summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS3
-rw-r--r--ext/opcache/Optimizer/zend_optimizer.c6
-rw-r--r--ext/opcache/tests/bug73402.phpt29
3 files changed, 35 insertions, 3 deletions
diff --git a/NEWS b/NEWS
index d495231f1a..c2f35898dd 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,9 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? 2016, PHP 5.6.29
+- Opcache:
+ . Fixed bug #73402 (Opcache segfault when using class constant to call a
+ method). (Laruence)
10 Nov 2016, PHP 5.6.28
diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c
index af1395c350..176cc29699 100644
--- a/ext/opcache/Optimizer/zend_optimizer.c
+++ b/ext/opcache/Optimizer/zend_optimizer.c
@@ -157,7 +157,7 @@ static void update_op1_const(zend_op_array *op_array,
opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC);
Z_HASH_P(&ZEND_OP1_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)) + 1);
op_array->literals[opline->op1.constant].cache_slot = op_array->last_cache_slot++;
- zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
+ Z_STRVAL_P(val) = zend_str_tolower_dup(Z_STRVAL_P(val), Z_STRLEN_P(val));
zend_optimizer_add_literal(op_array, val TSRMLS_CC);
op_array->literals[opline->op1.constant+1].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[opline->op1.constant+1].constant), Z_STRLEN(op_array->literals[opline->op1.constant+1].constant) + 1);
break;
@@ -205,13 +205,13 @@ static void update_op2_const(zend_op_array *op_array,
case ZEND_ADD_INTERFACE:
case ZEND_ADD_TRAIT:
op_array->literals[opline->op2.constant].cache_slot = op_array->last_cache_slot++;
- zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
+ Z_STRVAL_P(val) = zend_str_tolower_dup(Z_STRVAL_P(val), Z_STRLEN_P(val));
zend_optimizer_add_literal(op_array, val TSRMLS_CC);
op_array->literals[opline->op2.constant+1].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[opline->op2.constant+1].constant), Z_STRLEN(op_array->literals[opline->op2.constant+1].constant) + 1);
break;
case ZEND_INIT_METHOD_CALL:
case ZEND_INIT_STATIC_METHOD_CALL:
- zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
+ Z_STRVAL_P(val) = zend_str_tolower_dup(Z_STRVAL_P(val), Z_STRLEN_P(val));
zend_optimizer_add_literal(op_array, val TSRMLS_CC);
op_array->literals[opline->op2.constant+1].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[opline->op2.constant+1].constant), Z_STRLEN(op_array->literals[opline->op2.constant+1].constant) + 1);
/* break missing intentionally */
diff --git a/ext/opcache/tests/bug73402.phpt b/ext/opcache/tests/bug73402.phpt
new file mode 100644
index 0000000000..f325b798e5
--- /dev/null
+++ b/ext/opcache/tests/bug73402.phpt
@@ -0,0 +1,29 @@
+--TEST--
+Bug #73402 (Opcache segfault when using class constant to call a method)
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+class Logger {
+ public function info($msg) {
+ echo $msg;
+ }
+}
+
+class B
+{
+ const LOG_LEVEL = 'Info';
+ public function test()
+ {
+ $logger = new \Logger();
+ $logger->{self::LOG_LEVEL}('test');
+ }
+}
+
+$b = new B;
+$b->test();
+--EXPECT--
+test