summaryrefslogtreecommitdiff
path: root/Zend/zend_opcode.c
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-10-21 12:17:43 +0200
committerNikita Popov <nikita.ppv@gmail.com>2019-10-21 12:17:43 +0200
commitd927b745d6c341053f90145e9781d82eb1b9922b (patch)
treeb072ec54b850c726944576d8d79f8d9dc4fbd782 /Zend/zend_opcode.c
parent065d00f241d452a888ad187260718e46e331db30 (diff)
parent3d55386aa895d483dafdb1b4e1870b552dba7b31 (diff)
downloadphp-git-d927b745d6c341053f90145e9781d82eb1b9922b.tar.gz
Merge branch 'PHP-7.4'
* PHP-7.4: Fix static prop cleanup for dl'ed internal classes
Diffstat (limited to 'Zend/zend_opcode.c')
-rw-r--r--Zend/zend_opcode.c48
1 files changed, 34 insertions, 14 deletions
diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c
index 54886a3d07..626eacd35d 100644
--- a/Zend/zend_opcode.c
+++ b/Zend/zend_opcode.c
@@ -152,22 +152,42 @@ ZEND_API void zend_cleanup_internal_class_data(zend_class_entry *ce)
zval *static_members = CE_STATIC_MEMBERS(ce);
zval *p = static_members;
zval *end = p + ce->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);
}
}