]> granicus.if.org Git - php/commitdiff
Fixed bug #73402 (Opcache segfault when using class constant to call a method)
authorXinchen Hui <laruence@gmail.com>
Sat, 29 Oct 2016 15:41:51 +0000 (23:41 +0800)
committerXinchen Hui <laruence@gmail.com>
Sat, 29 Oct 2016 15:41:51 +0000 (23:41 +0800)
NEWS
ext/opcache/Optimizer/zend_optimizer.c
ext/opcache/tests/bug73402.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index d495231f1ae3e5390d1c92db63e401716c3f1eeb..c2f35898dd6959394e1fea8e8b149dcb1f44a445 100644 (file)
--- 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
 
index af1395c3506a2151b8aa2fda2f59cd21f212f553..176cc29699645a72bfd59ded46e50bbb20de9558 100644 (file)
@@ -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 (file)
index 0000000..f325b79
--- /dev/null
@@ -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