Skip to content

Commit 743a2e2

Browse files
committed
Fixed bug #51822i (Segfault with strange __destruct() for static class variables)
1 parent 7ea9e87 commit 743a2e2

File tree

2 files changed

+54
-2
lines changed

2 files changed

+54
-2
lines changed

Zend/tests/bug51822.phpt

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
--TEST--
2+
Bug #51822 (Segfault with strange __destruct() for static class variables)
3+
--FILE--
4+
<?php
5+
class DestructableObject
6+
{
7+
public function __destruct()
8+
{
9+
echo "2\n";
10+
}
11+
}
12+
13+
class DestructorCreator
14+
{
15+
public function __destruct()
16+
{
17+
$this->test = new DestructableObject;
18+
echo "1\n";
19+
}
20+
}
21+
22+
class Test
23+
{
24+
public static $mystatic;
25+
}
26+
27+
// Uncomment this to avoid segfault
28+
//Test::$mystatic = new DestructorCreator();
29+
30+
$x = new Test();
31+
32+
if (!isset(Test::$mystatic))
33+
Test::$mystatic = new DestructorCreator();
34+
35+
echo "bla\n";
36+
?>
37+
--EXPECT--
38+
bla
39+
1
40+
2

Zend/zend_opcode.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,17 @@ ZEND_API int zend_cleanup_class_data(zend_class_entry **pce TSRMLS_DC)
166166
/* Note that only run-time accessed data need to be cleaned up, pre-defined data can
167167
not contain objects and thus are not probelmatic */
168168
zend_hash_apply(&(*pce)->function_table, (apply_func_t) zend_cleanup_function_data_full TSRMLS_CC);
169-
(*pce)->static_members_table = NULL;
169+
if ((*pce)->static_members_table) {
170+
int i;
171+
172+
for (i = 0; i < (*pce)->default_static_members_count; i++) {
173+
if ((*pce)->static_members_table[i]) {
174+
zval_ptr_dtor(&(*pce)->static_members_table[i]);
175+
(*pce)->static_members_table[i] = NULL;
176+
}
177+
}
178+
(*pce)->static_members_table = NULL;
179+
}
170180
} else if (CE_STATIC_MEMBERS(*pce)) {
171181
int i;
172182

@@ -255,7 +265,9 @@ ZEND_API void destroy_zend_class(zend_class_entry **pce)
255265
int i;
256266

257267
for (i = 0; i < ce->default_static_members_count; i++) {
258-
zval_ptr_dtor(&ce->default_static_members_table[i]);
268+
if (ce->default_static_members_table[i]) {
269+
zval_ptr_dtor(&ce->default_static_members_table[i]);
270+
}
259271
}
260272
efree(ce->default_static_members_table);
261273
}

0 commit comments

Comments
 (0)