Skip to content

Commit d3eeeb6

Browse files
committed
Don't leak attributes on internal classes
Also add zend_hash_release() API to complement zend_array_release(), because the latter is specific to non-persistent zval arrays.
1 parent 8a7756c commit d3eeeb6

File tree

2 files changed

+20
-5
lines changed

2 files changed

+20
-5
lines changed

Zend/zend_hash.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,7 @@ static zend_always_inline void zend_hash_iterators_update(HashTable *ht, HashPos
324324
}
325325
}
326326

327+
/* For regular arrays (non-persistent, storing zvals). */
327328
static zend_always_inline void zend_array_release(zend_array *array)
328329
{
329330
if (!(GC_FLAGS(array) & IS_ARRAY_IMMUTABLE)) {
@@ -333,6 +334,17 @@ static zend_always_inline void zend_array_release(zend_array *array)
333334
}
334335
}
335336

337+
/* For general hashes (possibly persistent, storing any kind of value). */
338+
static zend_always_inline void zend_hash_release(zend_array *array)
339+
{
340+
if (!(GC_FLAGS(array) & IS_ARRAY_IMMUTABLE)) {
341+
if (GC_DELREF(array) == 0) {
342+
zend_hash_destroy(array);
343+
pefree(array, GC_FLAGS(array) & IS_ARRAY_PERSISTENT);
344+
}
345+
}
346+
}
347+
336348
END_EXTERN_C()
337349

338350
#define ZEND_INIT_SYMTABLE(ht) \

Zend/zend_opcode.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ ZEND_API void destroy_zend_class(zval *zv)
319319
zend_string_release_ex(prop_info->doc_comment, 0);
320320
}
321321
if (prop_info->attributes) {
322-
zend_array_release(prop_info->attributes);
322+
zend_hash_release(prop_info->attributes);
323323
}
324324
zend_type_release(prop_info->type, /* persistent */ 0);
325325
}
@@ -337,7 +337,7 @@ ZEND_API void destroy_zend_class(zval *zv)
337337
zend_string_release_ex(c->doc_comment, 0);
338338
}
339339
if (c->attributes) {
340-
zend_array_release(c->attributes);
340+
zend_hash_release(c->attributes);
341341
}
342342
}
343343
} ZEND_HASH_FOREACH_END();
@@ -358,7 +358,7 @@ ZEND_API void destroy_zend_class(zval *zv)
358358
zend_string_release_ex(ce->info.user.doc_comment, 0);
359359
}
360360
if (ce->attributes) {
361-
zend_array_release(ce->attributes);
361+
zend_hash_release(ce->attributes);
362362
}
363363

364364
if (ce->num_traits > 0) {
@@ -412,7 +412,7 @@ ZEND_API void destroy_zend_class(zval *zv)
412412
zend_string_release_ex(c->doc_comment, 1);
413413
}
414414
if (c->attributes) {
415-
zend_array_release(c->attributes);
415+
zend_hash_release(c->attributes);
416416
}
417417
}
418418
free(c);
@@ -428,6 +428,9 @@ ZEND_API void destroy_zend_class(zval *zv)
428428
if (ce->properties_info_table) {
429429
free(ce->properties_info_table);
430430
}
431+
if (ce->attributes) {
432+
zend_hash_release(ce->attributes);
433+
}
431434
free(ce);
432435
break;
433436
}
@@ -497,7 +500,7 @@ ZEND_API void destroy_op_array(zend_op_array *op_array)
497500
zend_string_release_ex(op_array->doc_comment, 0);
498501
}
499502
if (op_array->attributes) {
500-
zend_array_release(op_array->attributes);
503+
zend_hash_release(op_array->attributes);
501504
}
502505
if (op_array->live_range) {
503506
efree(op_array->live_range);

0 commit comments

Comments
 (0)