Fixed bug #70631 (Another Segfault in gc_remove_from_buffer())

This commit is contained in:
Xinchen Hui 2015-10-03 20:08:21 -07:00
parent 925412ee1c
commit 4744eec753
3 changed files with 50 additions and 1 deletions

1
NEWS
View File

@ -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

View File

@ -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

View File

@ -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;