From ace30a8caefed1f8291a8d17f0ffa97238ab2f3d Mon Sep 17 00:00:00 2001 From: Andy Postnikov Date: Mon, 16 Feb 2026 02:31:29 +0100 Subject: [PATCH 1/3] Fix PHP 8.5 compatibility: segfault and IS_UNDEF crashes Restore EG(current_execute_data) after walking execution frames in meminfo_browse_exec_frames(), skip IS_UNDEF zvals after IS_INDIRECT dereferencing, and safely extract object pointer in frame label builder. Also fix dynamic property deprecation in test for PHP 8.2+. --- extension/meminfo.c | 21 +++++++++++++++++-- ...hub-76_children_items_not_linked_php7.phpt | 1 + 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/extension/meminfo.c b/extension/meminfo.c index b91b5b5..fb5ff4e 100644 --- a/extension/meminfo.c +++ b/extension/meminfo.c @@ -90,9 +90,11 @@ PHP_FUNCTION(meminfo_dump) */ void meminfo_browse_exec_frames(php_stream *stream, HashTable *visited_items, int *first_element) { - zend_execute_data *exec_frame, *prev_frame; + zend_execute_data *exec_frame; + zend_execute_data *original_execute_data; zend_array *p_symbol_table; + original_execute_data = EG(current_execute_data); exec_frame = EG(current_execute_data); char frame_label[500]; @@ -122,6 +124,8 @@ void meminfo_browse_exec_frames(php_stream *stream, HashTable *visited_items, i } exec_frame = exec_frame->prev_execute_data; } + + EG(current_execute_data) = original_execute_data; } /** @@ -246,6 +250,11 @@ void meminfo_hash_dump(php_stream *stream, HashTable *ht, zend_bool is_object, H zval = Z_INDIRECT_P(zval); } + if (Z_TYPE_P(zval) == IS_UNDEF) { + zend_hash_move_forward_ex(ht, &pos); + continue; + } + if (Z_ISREF_P(zval)) { ZVAL_DEREF(zval); } @@ -311,6 +320,10 @@ void meminfo_zval_dump(php_stream * stream, char * frame_label, zend_string * sy zv = Z_INDIRECT_P(zv); } + if (Z_TYPE_P(zv) == IS_UNDEF) { + return; + } + if (Z_ISREF_P(zv)) { ZVAL_DEREF(zv); } @@ -447,7 +460,11 @@ void meminfo_build_frame_label(char* frame_label, int frame_label_len, zend_exec zend_object *object; zend_execute_data *ptr; - object = Z_OBJ(frame->This); + if (Z_TYPE(frame->This) == IS_OBJECT) { + object = Z_OBJ(frame->This); + } else { + object = NULL; + } ptr = frame->prev_execute_data; if (frame->func) { diff --git a/extension/tests/bug-github-76_children_items_not_linked_php7.phpt b/extension/tests/bug-github-76_children_items_not_linked_php7.phpt index 676c7e6..12aa37f 100644 --- a/extension/tests/bug-github-76_children_items_not_linked_php7.phpt +++ b/extension/tests/bug-github-76_children_items_not_linked_php7.phpt @@ -9,6 +9,7 @@ Check that all children items are properly linked through their identifiers Date: Mon, 16 Feb 2026 03:18:45 +0100 Subject: [PATCH 2/3] fix clang 21 warning --- extension/meminfo.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/extension/meminfo.c b/extension/meminfo.c index fb5ff4e..9beb8d1 100644 --- a/extension/meminfo.c +++ b/extension/meminfo.c @@ -196,7 +196,7 @@ void meminfo_browse_zvals_from_symbol_table(php_stream *stream, char* frame_labe HashPosition pos; zend_string *key; - zend_long index; + zend_ulong index; zend_hash_internal_pointer_reset_ex(p_symbol_table, &pos); @@ -299,6 +299,8 @@ void meminfo_hash_dump(php_stream *stream, HashTable *ht, zend_bool is_object, H case HASH_KEY_IS_LONG: php_stream_printf(stream, " \"%ld\":\"%s\"", num_key, zval_id); break; + default: + break; } zend_hash_move_forward_ex(ht, &pos); From 86b7699f2681ddd71ad75a1ba260edf5d3623cf2 Mon Sep 17 00:00:00 2001 From: Andy Postnikov Date: Mon, 16 Feb 2026 03:27:58 +0100 Subject: [PATCH 3/3] use ZEND_ULONG_FMT for compatibility with 32 and 64 bits --- extension/meminfo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extension/meminfo.c b/extension/meminfo.c index 9beb8d1..e6273af 100644 --- a/extension/meminfo.c +++ b/extension/meminfo.c @@ -297,7 +297,7 @@ void meminfo_hash_dump(php_stream *stream, HashTable *ht, zend_bool is_object, H break; case HASH_KEY_IS_LONG: - php_stream_printf(stream, " \"%ld\":\"%s\"", num_key, zval_id); + php_stream_printf(stream, " \"" ZEND_ULONG_FMT "\":\"%s\"", num_key, zval_id); break; default: break; @@ -348,7 +348,7 @@ void meminfo_zval_dump(php_stream * stream, char * frame_label, zend_string * sy php_stream_printf(stream, " \"%s\" : {\n", zval_identifier); php_stream_printf(stream, " \"type\" : \"%s\",\n", zend_get_type_by_const(Z_TYPE_P(zv))); - php_stream_printf(stream, " \"size\" : \"%ld\",\n", meminfo_get_element_size(zv)); + php_stream_printf(stream, " \"size\" : \"" ZEND_ULONG_FMT "\",\n", meminfo_get_element_size(zv)); if (frame_label) { zend_string * escaped_frame_label;