Merge branch 'bug69227' of https://github.com/Vektah/php-src into PHP-5.5

This commit is contained in:
Xinchen Hui 2015-03-14 00:42:36 +08:00
commit 1b5ad03f66
3 changed files with 37 additions and 30 deletions

View File

@ -86,6 +86,8 @@ typedef struct _spl_SplObjectStorage { /* {{{ */
long flags;
zend_function *fptr_get_hash;
HashTable *debug_info;
zval **gcdata;
long gcdata_len;
} spl_SplObjectStorage; /* }}} */
/* {{{ storage is an assoc aray of [zend_object_value]=>[zval *obj, zval *inf] */
@ -107,6 +109,10 @@ void spl_SplOjectStorage_free_storage(void *object TSRMLS_DC) /* {{{ */
efree(intern->debug_info);
}
if (intern->gcdata != NULL) {
efree(intern->gcdata);
}
efree(object);
} /* }}} */
@ -263,6 +269,9 @@ static zend_object_value spl_object_storage_new_ex(zend_class_entry *class_type,
zend_object_std_init(&intern->std, class_type TSRMLS_CC);
object_properties_init(&intern->std, class_type);
intern->gcdata = NULL;
intern->gcdata_len = 0;
zend_hash_init(&intern->storage, 0, NULL, (void (*)(void *))spl_object_storage_dtor, 0);
retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) spl_SplOjectStorage_free_storage, NULL TSRMLS_CC);
@ -324,7 +333,6 @@ static HashTable* spl_object_storage_debug_info(zval *obj, int *is_temp TSRMLS_D
*is_temp = 0;
props = Z_OBJPROP_P(obj);
zend_hash_del(props, "\x00gcdata", sizeof("\x00gcdata"));
if (intern->debug_info == NULL) {
ALLOC_HASHTABLE(intern->debug_info);
@ -360,46 +368,31 @@ static HashTable* spl_object_storage_debug_info(zval *obj, int *is_temp TSRMLS_D
}
/* }}} */
/* overriden for garbage collection
* This is very hacky */
/* overriden for garbage collection */
static HashTable *spl_object_storage_get_gc(zval *obj, zval ***table, int *n TSRMLS_DC) /* {{{ */
{
spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(obj TSRMLS_CC);
spl_SplObjectStorageElement *element;
HashTable *props;
HashPosition pos;
zval *gcdata_arr = NULL,
**gcdata_arr_pp;
long i = 0;
long requiredLength = intern->storage.nNumOfElements * 2;
props = std_object_handlers.get_properties(obj TSRMLS_CC);
*table = NULL;
*n = 0;
/* clean \x00gcdata, as it may be out of date */
if (zend_hash_find(props, "\x00gcdata", sizeof("\x00gcdata"), (void**) &gcdata_arr_pp) == SUCCESS) {
gcdata_arr = *gcdata_arr_pp;
zend_hash_clean(Z_ARRVAL_P(gcdata_arr));
}
if (gcdata_arr == NULL) {
MAKE_STD_ZVAL(gcdata_arr);
array_init(gcdata_arr);
/* don't decrease refcount of members when destroying */
Z_ARRVAL_P(gcdata_arr)->pDestructor = NULL;
/* name starts with \x00 to make tampering in user-land more difficult */
zend_hash_add(props, "\x00gcdata", sizeof("\x00gcdata"), &gcdata_arr, sizeof(gcdata_arr), NULL);
if (requiredLength > intern->gcdata_len) {
intern->gcdata = (zval**)erealloc(intern->gcdata, sizeof(zval*) * requiredLength);
intern->gcdata_len = requiredLength;
}
zend_hash_internal_pointer_reset_ex(&intern->storage, &pos);
while (zend_hash_get_current_data_ex(&intern->storage, (void **)&element, &pos) == SUCCESS) {
add_next_index_zval(gcdata_arr, element->obj);
add_next_index_zval(gcdata_arr, element->inf);
intern->gcdata[i++] = element->obj;
intern->gcdata[i++] = element->inf;
zend_hash_move_forward_ex(&intern->storage, &pos);
}
return props;
*table = intern->gcdata;
*n = i;
return std_object_handlers.get_properties(obj TSRMLS_CC);
}
/* }}} */
@ -782,7 +775,7 @@ SPL_METHOD(SplObjectStorage, serialize)
INIT_PZVAL(&members);
Z_ARRVAL(members) = zend_std_get_properties(getThis() TSRMLS_CC);
Z_TYPE(members) = IS_ARRAY;
zend_hash_del(Z_ARRVAL(members), "\x00gcdata", sizeof("\x00gcdata"));
pmembers = &members;
php_var_serialize(&buf, &pmembers, &var_hash TSRMLS_CC); /* finishes the string */

View File

@ -23,5 +23,5 @@ echo "Done.\n";
?>
--EXPECTF--
int(5)
int(4)
Done.

View File

@ -0,0 +1,14 @@
--TEST--
Bug #65967: SplObjectStorage contains corrupt member variables after garbage collection
--INI--
zend.enable_gc=1
--FILE--
<?php
$objstore = new SplObjectStorage();
gc_collect_cycles();
var_export($objstore);
?>
--EXPECT--
SplObjectStorage::__set_state(array(
))