Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions Zend/tests/bug64720.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,3 @@ $bar = new Bar();
$bar->test();
?>
--EXPECTF--
Fatal error: Uncaught Error: Access to undeclared static property: Stat::$requests in %sbug64720.php:12
Stack trace:
#0 [internal function]: Stat->__destruct()
#1 {main}
thrown in %sbug64720.php on line 12
7 changes: 0 additions & 7 deletions Zend/tests/bug68652.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,3 @@ class Bar {
$foo = new Foo();
?>
--EXPECTF--
Fatal error: Uncaught Error: Access to undeclared static property: Bar::$instance in %sbug68652.php:%d
Stack trace:
#0 %s(%d): Bar::getInstance()
#1 [internal function]: Foo->__destruct()
#2 {main}
thrown in %sbug68652.php on line %d

43 changes: 43 additions & 0 deletions Zend/tests/bug74053.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
--TEST--
Bug #74053 (Corrupted class entries on shutdown when a destructor spawns another object)
--FILE--
<?php
class b {
function __destruct() {
echo "b::destruct\n";
}
}
class a {
static $b;
static $new;
static $max = 10;
function __destruct() {
if (self::$max-- <= 0) return;
echo "a::destruct\n";
self::$b = new b;
self::$new[] = new a;
}
}
new a;
?>
--EXPECTF--
a::destruct
b::destruct
a::destruct
b::destruct
a::destruct
b::destruct
a::destruct
b::destruct
a::destruct
b::destruct
a::destruct
b::destruct
a::destruct
b::destruct
a::destruct
b::destruct
a::destruct
b::destruct
a::destruct
b::destruct
1 change: 1 addition & 0 deletions Zend/zend.c
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,7 @@ static void executor_globals_ctor(zend_executor_globals *executor_globals) /* {{
#ifdef ZEND_WIN32
zend_get_windows_version_info(&executor_globals->windows_version_info);
#endif
executor_globals->flags = EG_FLAGS_INITIAL;
}
/* }}} */

Expand Down
4 changes: 4 additions & 0 deletions Zend/zend_globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ struct _zend_executor_globals {

zend_bool active;
zend_bool valid_symbol_table;
zend_uchar flags;

zend_long assertions;

Expand All @@ -235,6 +236,9 @@ struct _zend_executor_globals {
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
};

#define EG_FLAGS_INITIAL 0x00
#define EG_FLAGS_IN_SHUTDOWN 0x01

struct _zend_ini_scanner_globals {
zend_file_handle *yy_in;
zend_file_handle *yy_out;
Expand Down
5 changes: 4 additions & 1 deletion Zend/zend_objects_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,10 @@ ZEND_API void zend_objects_store_put(zend_object *object)
{
int handle;

if (EG(objects_store).free_list_head != -1) {
/* When in shutdown sequesnce - do not reuse previously freed handles, to make sure
* the dtors for newly created objects are called in zend_objects_store_call_destructors() loop
*/
if (!(EG(flags) & EG_FLAGS_IN_SHUTDOWN) && EG(objects_store).free_list_head != -1) {
handle = EG(objects_store).free_list_head;
EG(objects_store).free_list_head = GET_OBJ_BUCKET_NUMBER(EG(objects_store).object_buckets[handle]);
} else {
Expand Down
2 changes: 2 additions & 0 deletions main/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1798,6 +1798,8 @@ void php_request_shutdown_for_hook(void *dummy)
void php_request_shutdown(void *dummy)
{
zend_bool report_memleaks;

EG(flags) |= EG_FLAGS_IN_SHUTDOWN;

report_memleaks = PG(report_memleaks);

Expand Down