1
0
mirror of https://github.com/php/php-src.git synced 2026-04-28 02:33:17 +02:00

Merge branch 'PHP-7.4'

This commit is contained in:
Nikita Popov
2019-08-28 12:32:22 +02:00
2 changed files with 73 additions and 48 deletions
+28
View File
@@ -0,0 +1,28 @@
--TEST--
Bug #78335: Static properties/variables containing cycles report as leak
--FILE--
<?php
class Test {
public static $test;
public static function method() {
static $foo;
$foo = [&$foo];
}
}
function test() {
static $foo;
$foo = [&$foo];
}
$foo = [&$foo];
Test::$test = $foo;
test();
Test::method();
?>
===DONE===
--EXPECT--
===DONE===
+45 -48
View File
@@ -268,9 +268,54 @@ void shutdown_executor(void) /* {{{ */
zend_close_rsrc_list(&EG(regular_list));
} zend_end_try();
/* No PHP callback functions should be called after this point. */
EG(active) = 0;
if (!fast_shutdown) {
zend_hash_graceful_reverse_destroy(&EG(symbol_table));
/* Release static properties and static variables prior to the final GC run,
* as they may hold GC roots. */
ZEND_HASH_REVERSE_FOREACH_VAL(EG(function_table), zv) {
zend_op_array *op_array = Z_PTR_P(zv);
if (op_array->type == ZEND_INTERNAL_FUNCTION) {
break;
}
if (op_array->static_variables) {
HashTable *ht = ZEND_MAP_PTR_GET(op_array->static_variables_ptr);
if (ht) {
ZEND_ASSERT(GC_REFCOUNT(ht) == 1);
zend_array_destroy(ht);
ZEND_MAP_PTR_SET(op_array->static_variables_ptr, NULL);
}
}
} ZEND_HASH_FOREACH_END();
ZEND_HASH_REVERSE_FOREACH_VAL(EG(class_table), zv) {
zend_class_entry *ce = Z_PTR_P(zv);
if (ce->type == ZEND_INTERNAL_CLASS) {
break;
}
if (ce->default_static_members_count) {
zend_cleanup_internal_class_data(ce);
}
if (ce->ce_flags & ZEND_HAS_STATIC_IN_METHODS) {
zend_op_array *op_array;
ZEND_HASH_FOREACH_PTR(&ce->function_table, op_array) {
if (op_array->type == ZEND_USER_FUNCTION) {
if (op_array->static_variables) {
HashTable *ht = ZEND_MAP_PTR_GET(op_array->static_variables_ptr);
if (ht) {
if (GC_DELREF(ht) == 0) {
zend_array_destroy(ht);
}
ZEND_MAP_PTR_SET(op_array->static_variables_ptr, NULL);
}
}
}
} ZEND_HASH_FOREACH_END();
}
} ZEND_HASH_FOREACH_END();
#if ZEND_DEBUG
if (gc_enabled() && !CG(unclean_shutdown)) {
gc_collect_cycles();
@@ -282,10 +327,6 @@ void shutdown_executor(void) /* {{{ */
zend_weakrefs_shutdown();
/* All resources and objects are destroyed. */
/* No PHP callback functions may be called after this point. */
EG(active) = 0;
zend_try {
zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_deactivator);
} zend_end_try();
@@ -346,23 +387,6 @@ void shutdown_executor(void) /* {{{ */
zend_string_release_ex(key, 0);
} ZEND_HASH_FOREACH_END_DEL();
/* Cleanup preloaded immutable functions */
ZEND_HASH_REVERSE_FOREACH_VAL(EG(function_table), zv) {
zend_op_array *op_array = Z_PTR_P(zv);
if (op_array->type == ZEND_INTERNAL_FUNCTION) {
break;
}
ZEND_ASSERT(op_array->fn_flags & ZEND_ACC_IMMUTABLE);
if (op_array->static_variables) {
HashTable *ht = ZEND_MAP_PTR_GET(op_array->static_variables_ptr);
if (ht) {
ZEND_ASSERT(GC_REFCOUNT(ht) == 1);
zend_array_destroy(ht);
ZEND_MAP_PTR_SET(op_array->static_variables_ptr, NULL);
}
}
} ZEND_HASH_FOREACH_END();
ZEND_HASH_REVERSE_FOREACH_STR_KEY_VAL(EG(class_table), key, zv) {
if (_idx == EG(persistent_classes_count)) {
break;
@@ -370,33 +394,6 @@ void shutdown_executor(void) /* {{{ */
destroy_zend_class(zv);
zend_string_release_ex(key, 0);
} ZEND_HASH_FOREACH_END_DEL();
/* Cleanup preloaded immutable classes */
ZEND_HASH_REVERSE_FOREACH_VAL(EG(class_table), zv) {
zend_class_entry *ce = Z_PTR_P(zv);
if (ce->type == ZEND_INTERNAL_CLASS) {
break;
}
ZEND_ASSERT(ce->ce_flags & ZEND_ACC_IMMUTABLE);
if (ce->default_static_members_count) {
zend_cleanup_internal_class_data(ce);
}
if (ce->ce_flags & ZEND_HAS_STATIC_IN_METHODS) {
zend_op_array *op_array;
ZEND_HASH_FOREACH_PTR(&ce->function_table, op_array) {
if (op_array->type == ZEND_USER_FUNCTION) {
if (op_array->static_variables) {
HashTable *ht = ZEND_MAP_PTR_GET(op_array->static_variables_ptr);
if (ht) {
ZEND_ASSERT(GC_REFCOUNT(ht) == 1);
zend_array_destroy(ht);
ZEND_MAP_PTR_SET(op_array->static_variables_ptr, NULL);
}
}
}
} ZEND_HASH_FOREACH_END();
}
} ZEND_HASH_FOREACH_END();
}
zend_cleanup_internal_classes();