From 3d55386aa895d483dafdb1b4e1870b552dba7b31 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 21 Oct 2019 11:30:00 +0200 Subject: Fix static prop cleanup for dl'ed internal classes --- Zend/tests/bug78335_2.phpt | 2 ++ Zend/zend_opcode.c | 48 ++++++++++++++++++++++++++++++++-------------- 2 files changed, 36 insertions(+), 14 deletions(-) (limited to 'Zend') diff --git a/Zend/tests/bug78335_2.phpt b/Zend/tests/bug78335_2.phpt index bc9e8f5f0c..5fb5fcb788 100644 --- a/Zend/tests/bug78335_2.phpt +++ b/Zend/tests/bug78335_2.phpt @@ -1,5 +1,7 @@ --TEST-- Bug #78335: Static properties containing cycles report as leak (internal class variant) +--SKIPIF-- + --FILE-- default_static_members_count; - - ZEND_MAP_PTR_SET(ce->static_members_table, NULL); - while (p != end) { - if (UNEXPECTED(Z_ISREF_P(p))) { - zend_property_info *prop_info; - ZEND_REF_FOREACH_TYPE_SOURCES(Z_REF_P(p), prop_info) { - if (prop_info->ce == ce && p - static_members == prop_info->offset) { - ZEND_REF_DEL_TYPE_SOURCE(Z_REF_P(p), prop_info); - break; /* stop iteration here, the array might be realloc()'ed */ - } - } ZEND_REF_FOREACH_TYPE_SOURCES_END(); + if (UNEXPECTED(ZEND_MAP_PTR(ce->static_members_table) == &ce->default_static_members_table)) { + /* Special case: If this is a static property on a dl'ed internal class, then the + * static property table and the default property table are the same. In this case we + * destroy the values here, but leave behind valid UNDEF zvals and don't free the + * table itself. */ + while (p != end) { + if (UNEXPECTED(Z_ISREF_P(p))) { + zend_property_info *prop_info; + ZEND_REF_FOREACH_TYPE_SOURCES(Z_REF_P(p), prop_info) { + if (prop_info->ce == ce && p - static_members == prop_info->offset) { + ZEND_REF_DEL_TYPE_SOURCE(Z_REF_P(p), prop_info); + break; /* stop iteration here, the array might be realloc()'ed */ + } + } ZEND_REF_FOREACH_TYPE_SOURCES_END(); + } + i_zval_ptr_dtor(p); + ZVAL_UNDEF(p); + p++; + } + } else { + ZEND_MAP_PTR_SET(ce->static_members_table, NULL); + while (p != end) { + if (UNEXPECTED(Z_ISREF_P(p))) { + zend_property_info *prop_info; + ZEND_REF_FOREACH_TYPE_SOURCES(Z_REF_P(p), prop_info) { + if (prop_info->ce == ce && p - static_members == prop_info->offset) { + ZEND_REF_DEL_TYPE_SOURCE(Z_REF_P(p), prop_info); + break; /* stop iteration here, the array might be realloc()'ed */ + } + } ZEND_REF_FOREACH_TYPE_SOURCES_END(); + } + i_zval_ptr_dtor(p); + p++; } - i_zval_ptr_dtor(p); - p++; + efree(static_members); } - efree(static_members); } } -- cgit v1.2.1