com php-src: Fixed bug #70631 (Another Segfault in gc_remove _from_buffer()): NEWS ext/opcache/tests/bug7 0631.phpt ext/reflection/php_reflection.c
| From: | Xinchen Hui | Date: | Sun, 04 Oct 2015 03:08:21 +0000 |
| Subject: | com php-src: Fixed bug #70631 (Another Segfault in gc_remove _from_buffer()): NEWS ext/opcache/tests/bug7 0631.phpt ext/reflection/php_reflection.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-89278@lists.php.net to get a copy of this message | ||
Commit: 4744eec753786e18b28887463bdcb3f1e91efb60
Author: Xinchen Hui <laruence@gmail.com> Sat, 3 Oct 2015 20:08:21 -0700
Parents: 925412ee1c123c55e2b5badf6daf193e6c1bdd5b
Branches: PHP-5.6 PHP-7.0 master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=4744eec753786e18b28887463bdcb3f1e91efb60
Log:
Fixed bug #70631 (Another Segfault in gc_remove_from_buffer())
Bugs:
https://bugs.php.net/70631
Changed paths:
M NEWS
A ext/opcache/tests/bug70631.phpt
M ext/reflection/php_reflection.c
Diff:
diff --git a/NEWS b/NEWS
index 4adadb2..79ca987 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,7 @@ PHP NEWS
. Fixed bug #70572 segfault in mysqlnd_connect. (Andrey, Remi)
- Opcache:
+ . Fixed bug #70631 (Another Segfault in gc_remove_from_buffer()). (Laruence)
. Fixed bug #70601 (Segfault in gc_remove_from_buffer()). (Laruence)
01 Oct 2015, PHP 5.6.14
diff --git a/ext/opcache/tests/bug70631.phpt b/ext/opcache/tests/bug70631.phpt
new file mode 100644
index 0000000..1089329
--- /dev/null
+++ b/ext/opcache/tests/bug70631.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Bug #70631 (Another Segfault in gc_remove_from_buffer())
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.protect_memory=1
+--SKIPIF--
+<?php if (!extension_loaded('Zend OPcache') ||
!extension_loaded("Reflection")) die("skip"); ?>
+--FILE--
+<?php
+
+function x($x = array("Okay")) {}
+
+$func = new ReflectionFunction('x');
+$params = $func->getParameters();
+$value = $params[0]->getDefaultValue();
+echo $value[0];
+?>
+--EXPECT--
+Okay
diff --git a/ext/reflection/php_reflection..c b/ext/reflection/php_reflection.c
index eff8bdc..3bf49ea 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -242,6 +242,25 @@ static void _default_lookup_entry(zval *object, char *name, int name_len, zval
*
/* }}} */
#endif
+static void reflection_zval_deep_copy(zval **p)
+{
+ zval *value;
+
+ ALLOC_ZVAL(value);
+ *value = **p;
+ if (Z_TYPE_P(value) == IS_ARRAY) {
+ HashTable *ht;
+
+ ALLOC_HASHTABLE(ht);
+ zend_hash_init(ht, zend_hash_num_elements(Z_ARRVAL_P(value)), NULL, ZVAL_PTR_DTOR, 0);
+ zend_hash_copy(ht, Z_ARRVAL_P(value), (copy_ctor_func_t) reflection_zval_deep_copy, NULL,
sizeof(zval *));
+ Z_ARRVAL_P(value) = ht;
+ } else {
+ zval_copy_ctor(value);
+ }
+ INIT_PZVAL(value);
+ *p = value;
+}
static void reflection_register_implement(zend_class_entry *class_entry, zend_class_entry
*interface_entry TSRMLS_DC) /* {{{ */
{
zend_uint num_interfaces = ++class_entry->num_interfaces;
@@ -2606,7 +2625,16 @@ ZEND_METHOD(reflection_parameter, getDefaultValue)
*return_value = *precv->op2.zv;
INIT_PZVAL(return_value);
if (!IS_CONSTANT_TYPE(Z_TYPE_P(return_value))) {
- zval_copy_ctor(return_value);
+ if (Z_TYPE_P(return_value) != IS_ARRAY) {
+ zval_copy_ctor(return_value);
+ } else {
+ HashTable *ht;
+
+ ALLOC_HASHTABLE(ht);
+ zend_hash_init(ht, zend_hash_num_elements(Z_ARRVAL_P(return_value)), NULL, ZVAL_PTR_DTOR, 0);
+ zend_hash_copy(ht, Z_ARRVAL_P(return_value), (copy_ctor_func_t) reflection_zval_deep_copy, NULL,
sizeof(zval *));
+ Z_ARRVAL_P(return_value) = ht;
+ }
}
old_scope = EG(scope);
EG(scope) = param->fptr->common.scope;