Skip to content

Commit 22a077b

Browse files
committed
Fix #69264: __debugInfo() ignored while extending SPL classes
We actually implement `::__debugInfo()` and drop the `get_debug_info()` handlers of all relevant SPL classes. This is cleaner and gives more flexibility regarding overriding the functionality in descendant classes.
1 parent c31b2bb commit 22a077b

File tree

7 files changed

+193
-36
lines changed

7 files changed

+193
-36
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ PHP NEWS
77
. Fixed bug #79441 (Segfault in mb_chr() if internal encoding is unsupported).
88
(Girgias)
99

10+
- SPL:
11+
. Fixed bug #69264 (__debugInfo() ignored while extending SPL classes). (cmb)
12+
1013
?? ??? ????, PHP 7.4.5
1114

1215
- Core:

ext/spl/spl_array.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,7 @@ static HashTable *spl_array_get_properties_for(zval *object, zend_prop_purpose p
822822
return ht;
823823
} /* }}} */
824824

825-
static HashTable* spl_array_get_debug_info(zval *obj, int *is_temp) /* {{{ */
825+
static inline HashTable* spl_array_get_debug_info(zval *obj) /* {{{ */
826826
{
827827
zval *storage;
828828
zend_string *zname;
@@ -834,11 +834,9 @@ static HashTable* spl_array_get_debug_info(zval *obj, int *is_temp) /* {{{ */
834834
}
835835

836836
if (intern->ar_flags & SPL_ARRAY_IS_SELF) {
837-
*is_temp = 0;
838-
return intern->std.properties;
837+
return zend_array_dup(intern->std.properties);
839838
} else {
840839
HashTable *debug_info;
841-
*is_temp = 1;
842840

843841
debug_info = zend_new_array(zend_hash_num_elements(intern->std.properties) + 1);
844842
zend_hash_copy(debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref);
@@ -1883,6 +1881,16 @@ SPL_METHOD(Array, __unserialize)
18831881
}
18841882
/* }}} */
18851883

1884+
/* {{{ proto void Array::__debugInfo() */
1885+
SPL_METHOD(Array, __debugInfo)
1886+
{
1887+
if (zend_parse_parameters_none() == FAILURE) {
1888+
return;
1889+
}
1890+
1891+
RETURN_ARR(spl_array_get_debug_info(getThis()));
1892+
} /* }}} */
1893+
18861894
/* {{{ arginfo and function table */
18871895
ZEND_BEGIN_ARG_INFO_EX(arginfo_array___construct, 0, 0, 0)
18881896
ZEND_ARG_INFO(0, input)
@@ -1957,6 +1965,7 @@ static const zend_function_entry spl_funcs_ArrayObject[] = {
19571965
SPL_ME(Array, serialize, arginfo_array_void, ZEND_ACC_PUBLIC)
19581966
SPL_ME(Array, __unserialize, arginfo_array_unserialize, ZEND_ACC_PUBLIC)
19591967
SPL_ME(Array, __serialize, arginfo_array_void, ZEND_ACC_PUBLIC)
1968+
SPL_ME(Array, __debugInfo, arginfo_array_void, ZEND_ACC_PUBLIC)
19601969
/* ArrayObject specific */
19611970
SPL_ME(Array, getIterator, arginfo_array_void, ZEND_ACC_PUBLIC)
19621971
SPL_ME(Array, exchangeArray, arginfo_array_exchangeArray, ZEND_ACC_PUBLIC)
@@ -1986,6 +1995,7 @@ static const zend_function_entry spl_funcs_ArrayIterator[] = {
19861995
SPL_ME(Array, serialize, arginfo_array_void, ZEND_ACC_PUBLIC)
19871996
SPL_ME(Array, __unserialize, arginfo_array_unserialize, ZEND_ACC_PUBLIC)
19881997
SPL_ME(Array, __serialize, arginfo_array_void, ZEND_ACC_PUBLIC)
1998+
SPL_ME(Array, __debugInfo, arginfo_array_void, ZEND_ACC_PUBLIC)
19891999
/* ArrayIterator specific */
19902000
SPL_ME(Array, rewind, arginfo_array_void, ZEND_ACC_PUBLIC)
19912001
SPL_ME(Array, current, arginfo_array_void, ZEND_ACC_PUBLIC)
@@ -2023,7 +2033,6 @@ PHP_MINIT_FUNCTION(spl_array)
20232033
spl_handler_ArrayObject.count_elements = spl_array_object_count_elements;
20242034

20252035
spl_handler_ArrayObject.get_properties_for = spl_array_get_properties_for;
2026-
spl_handler_ArrayObject.get_debug_info = spl_array_get_debug_info;
20272036
spl_handler_ArrayObject.get_gc = spl_array_get_gc;
20282037
spl_handler_ArrayObject.read_property = spl_array_read_property;
20292038
spl_handler_ArrayObject.write_property = spl_array_write_property;

ext/spl/spl_directory.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,7 @@ static char *spl_filesystem_object_get_pathname(spl_filesystem_object *intern, s
598598
}
599599
/* }}} */
600600

601-
static HashTable *spl_filesystem_object_get_debug_info(zval *object, int *is_temp) /* {{{ */
601+
static inline HashTable *spl_filesystem_object_get_debug_info(zval *object) /* {{{ */
602602
{
603603
spl_filesystem_object *intern = Z_SPLFILESYSTEM_P(object);
604604
zval tmp;
@@ -608,8 +608,6 @@ static HashTable *spl_filesystem_object_get_debug_info(zval *object, int *is_tem
608608
size_t path_len;
609609
char stmp[2];
610610

611-
*is_temp = 1;
612-
613611
if (!intern->std.properties) {
614612
rebuild_object_properties(&intern->std);
615613
}
@@ -1421,6 +1419,16 @@ SPL_METHOD(SplFileInfo, getPathInfo)
14211419
}
14221420
/* }}} */
14231421

1422+
/* {{{ proto void SplFileInfo::__debugInfo() */
1423+
SPL_METHOD(SplFileInfo, __debugInfo)
1424+
{
1425+
if (zend_parse_parameters_none() == FAILURE) {
1426+
return;
1427+
}
1428+
1429+
RETURN_ARR(spl_filesystem_object_get_debug_info(getThis()));
1430+
} /* }}} */
1431+
14241432
/* {{{ proto SplFileInfo::_bad_state_ex(void) */
14251433
SPL_METHOD(SplFileInfo, _bad_state_ex)
14261434
{
@@ -1947,6 +1955,7 @@ static const zend_function_entry spl_SplFileInfo_functions[] = {
19471955
SPL_ME(SplFileInfo, openFile, arginfo_info_openFile, ZEND_ACC_PUBLIC)
19481956
SPL_ME(SplFileInfo, setFileClass, arginfo_info_optinalFileClass, ZEND_ACC_PUBLIC)
19491957
SPL_ME(SplFileInfo, setInfoClass, arginfo_info_optinalFileClass, ZEND_ACC_PUBLIC)
1958+
SPL_ME(SplFileInfo, __debugInfo, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
19501959
SPL_ME(SplFileInfo, _bad_state_ex, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
19511960
SPL_MA(SplFileInfo, __toString, SplFileInfo, getPathname, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
19521961
PHP_FE_END
@@ -3143,7 +3152,6 @@ PHP_MINIT_FUNCTION(spl_directory)
31433152
spl_filesystem_object_handlers.offset = XtOffsetOf(spl_filesystem_object, std);
31443153
spl_filesystem_object_handlers.clone_obj = spl_filesystem_object_clone;
31453154
spl_filesystem_object_handlers.cast_object = spl_filesystem_object_cast;
3146-
spl_filesystem_object_handlers.get_debug_info = spl_filesystem_object_get_debug_info;
31473155
spl_filesystem_object_handlers.dtor_obj = spl_filesystem_object_destroy_object;
31483156
spl_filesystem_object_handlers.free_obj = spl_filesystem_object_free_storage;
31493157
spl_ce_SplFileInfo->serialize = zend_class_serialize_deny;

ext/spl/spl_dllist.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -492,15 +492,14 @@ static int spl_dllist_object_count_elements(zval *object, zend_long *count) /* {
492492
}
493493
/* }}} */
494494

495-
static HashTable* spl_dllist_object_get_debug_info(zval *obj, int *is_temp) /* {{{{ */
495+
static inline HashTable* spl_dllist_object_get_debug_info(zval *obj) /* {{{{ */
496496
{
497497
spl_dllist_object *intern = Z_SPLDLLIST_P(obj);
498498
spl_ptr_llist_element *current = intern->llist->head, *next;
499499
zval tmp, dllist_array;
500500
zend_string *pnstr;
501501
int i = 0;
502502
HashTable *debug_info;
503-
*is_temp = 1;
504503

505504
if (!intern->std.properties) {
506505
rebuild_object_properties(&intern->std);
@@ -1344,6 +1343,16 @@ SPL_METHOD(SplDoublyLinkedList, add)
13441343
}
13451344
} /* }}} */
13461345

1346+
/* {{{ proto void SplDoublyLinkedList::__debugInfo() */
1347+
SPL_METHOD(SplDoublyLinkedList, __debugInfo)
1348+
{
1349+
if (zend_parse_parameters_none() == FAILURE) {
1350+
return;
1351+
}
1352+
1353+
RETURN_ARR(spl_dllist_object_get_debug_info(getThis()));
1354+
} /* }}} */
1355+
13471356
/* {{{ iterator handler table */
13481357
static const zend_object_iterator_funcs spl_dllist_it_funcs = {
13491358
spl_dllist_it_dtor,
@@ -1425,6 +1434,7 @@ static const zend_function_entry spl_funcs_SplDoublyLinkedList[] = {
14251434
SPL_ME(SplDoublyLinkedList, isEmpty, arginfo_dllist_void, ZEND_ACC_PUBLIC)
14261435
SPL_ME(SplDoublyLinkedList, setIteratorMode, arginfo_dllist_setiteratormode, ZEND_ACC_PUBLIC)
14271436
SPL_ME(SplDoublyLinkedList, getIteratorMode, arginfo_dllist_void, ZEND_ACC_PUBLIC)
1437+
SPL_ME(SplDoublyLinkedList, __debugInfo, arginfo_dllist_void, ZEND_ACC_PUBLIC)
14281438
/* Countable */
14291439
SPL_ME(SplDoublyLinkedList, count, arginfo_dllist_void, ZEND_ACC_PUBLIC)
14301440
/* ArrayAccess */
@@ -1459,7 +1469,6 @@ PHP_MINIT_FUNCTION(spl_dllist) /* {{{ */
14591469
spl_handler_SplDoublyLinkedList.offset = XtOffsetOf(spl_dllist_object, std);
14601470
spl_handler_SplDoublyLinkedList.clone_obj = spl_dllist_object_clone;
14611471
spl_handler_SplDoublyLinkedList.count_elements = spl_dllist_object_count_elements;
1462-
spl_handler_SplDoublyLinkedList.get_debug_info = spl_dllist_object_get_debug_info;
14631472
spl_handler_SplDoublyLinkedList.get_gc = spl_dllist_object_get_gc;
14641473
spl_handler_SplDoublyLinkedList.dtor_obj = zend_objects_destroy_object;
14651474
spl_handler_SplDoublyLinkedList.free_obj = spl_dllist_object_free_storage;

ext/spl/spl_heap.c

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -501,15 +501,13 @@ static int spl_heap_object_count_elements(zval *object, zend_long *count) /* {{{
501501
}
502502
/* }}} */
503503

504-
static HashTable* spl_heap_object_get_debug_info_helper(zend_class_entry *ce, zval *obj, int *is_temp) { /* {{{ */
504+
static inline HashTable* spl_heap_object_get_debug_info(zend_class_entry *ce, zval *obj) { /* {{{ */
505505
spl_heap_object *intern = Z_SPLHEAP_P(obj);
506506
zval tmp, heap_array;
507507
zend_string *pnstr;
508508
HashTable *debug_info;
509509
int i;
510510

511-
*is_temp = 1;
512-
513511
if (!intern->std.properties) {
514512
rebuild_object_properties(&intern->std);
515513
}
@@ -571,18 +569,6 @@ static HashTable *spl_pqueue_object_get_gc(zval *obj, zval **gc_data, int *gc_da
571569
}
572570
/* }}} */
573571

574-
static HashTable* spl_heap_object_get_debug_info(zval *obj, int *is_temp) /* {{{ */
575-
{
576-
return spl_heap_object_get_debug_info_helper(spl_ce_SplHeap, obj, is_temp);
577-
}
578-
/* }}} */
579-
580-
static HashTable* spl_pqueue_object_get_debug_info(zval *obj, int *is_temp) /* {{{ */
581-
{
582-
return spl_heap_object_get_debug_info_helper(spl_ce_SplPriorityQueue, obj, is_temp);
583-
}
584-
/* }}} */
585-
586572
/* {{{ proto int SplHeap::count()
587573
Return the number of elements in the heap. */
588574
SPL_METHOD(SplHeap, count)
@@ -1065,6 +1051,26 @@ SPL_METHOD(SplPriorityQueue, current)
10651051
}
10661052
/* }}} */
10671053

1054+
/* {{{ proto void SplHeap::__debugInfo() */
1055+
SPL_METHOD(SplHeap, __debugInfo)
1056+
{
1057+
if (zend_parse_parameters_none() == FAILURE) {
1058+
return;
1059+
}
1060+
1061+
RETURN_ARR(spl_heap_object_get_debug_info(spl_ce_SplHeap, getThis()));
1062+
} /* }}} */
1063+
1064+
/* {{{ proto void SplPriorityQueue::__debugInfo() */
1065+
SPL_METHOD(SplPriorityQueue, __debugInfo)
1066+
{
1067+
if (zend_parse_parameters_none() == FAILURE) {
1068+
return;
1069+
}
1070+
1071+
RETURN_ARR(spl_heap_object_get_debug_info(spl_ce_SplPriorityQueue, getThis()));
1072+
} /* }}} */
1073+
10681074
/* iterator handler table */
10691075
static const zend_object_iterator_funcs spl_heap_it_funcs = {
10701076
spl_heap_it_dtor,
@@ -1183,6 +1189,7 @@ static const zend_function_entry spl_funcs_SplPriorityQueue[] = {
11831189
SPL_ME(SplHeap, valid, arginfo_splheap_void, ZEND_ACC_PUBLIC)
11841190
SPL_ME(SplHeap, recoverFromCorruption, arginfo_splheap_void, ZEND_ACC_PUBLIC)
11851191
SPL_ME(SplHeap, isCorrupted, arginfo_splheap_void, ZEND_ACC_PUBLIC)
1192+
SPL_ME(SplPriorityQueue, __debugInfo, arginfo_splheap_void, ZEND_ACC_PUBLIC)
11861193
PHP_FE_END
11871194
};
11881195

@@ -1199,6 +1206,7 @@ static const zend_function_entry spl_funcs_SplHeap[] = {
11991206
SPL_ME(SplHeap, valid, arginfo_splheap_void, ZEND_ACC_PUBLIC)
12001207
SPL_ME(SplHeap, recoverFromCorruption, arginfo_splheap_void, ZEND_ACC_PUBLIC)
12011208
SPL_ME(SplHeap, isCorrupted, arginfo_splheap_void, ZEND_ACC_PUBLIC)
1209+
SPL_ME(SplHeap, __debugInfo, arginfo_splheap_void, ZEND_ACC_PUBLIC)
12021210
ZEND_FENTRY(compare, NULL, NULL, ZEND_ACC_PROTECTED|ZEND_ACC_ABSTRACT)
12031211
PHP_FE_END
12041212
};
@@ -1212,7 +1220,6 @@ PHP_MINIT_FUNCTION(spl_heap) /* {{{ */
12121220
spl_handler_SplHeap.offset = XtOffsetOf(spl_heap_object, std);
12131221
spl_handler_SplHeap.clone_obj = spl_heap_object_clone;
12141222
spl_handler_SplHeap.count_elements = spl_heap_object_count_elements;
1215-
spl_handler_SplHeap.get_debug_info = spl_heap_object_get_debug_info;
12161223
spl_handler_SplHeap.get_gc = spl_heap_object_get_gc;
12171224
spl_handler_SplHeap.dtor_obj = zend_objects_destroy_object;
12181225
spl_handler_SplHeap.free_obj = spl_heap_object_free_storage;
@@ -1234,7 +1241,6 @@ PHP_MINIT_FUNCTION(spl_heap) /* {{{ */
12341241
spl_handler_SplPriorityQueue.offset = XtOffsetOf(spl_heap_object, std);
12351242
spl_handler_SplPriorityQueue.clone_obj = spl_heap_object_clone;
12361243
spl_handler_SplPriorityQueue.count_elements = spl_heap_object_count_elements;
1237-
spl_handler_SplPriorityQueue.get_debug_info = spl_pqueue_object_get_debug_info;
12381244
spl_handler_SplPriorityQueue.get_gc = spl_pqueue_object_get_gc;
12391245
spl_handler_SplPriorityQueue.dtor_obj = zend_objects_destroy_object;
12401246
spl_handler_SplPriorityQueue.free_obj = spl_heap_object_free_storage;

ext/spl/spl_observer.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ static zend_object *spl_object_storage_clone(zval *zobject)
279279
}
280280
/* }}} */
281281

282-
static HashTable* spl_object_storage_debug_info(zval *obj, int *is_temp) /* {{{ */
282+
static inline HashTable* spl_object_storage_debug_info(zval *obj) /* {{{ */
283283
{
284284
spl_SplObjectStorage *intern = Z_SPLOBJSTORAGE_P(obj);
285285
spl_SplObjectStorageElement *element;
@@ -289,8 +289,6 @@ static HashTable* spl_object_storage_debug_info(zval *obj, int *is_temp) /* {{{
289289
zend_string *zname;
290290
HashTable *debug_info;
291291

292-
*is_temp = 1;
293-
294292
props = Z_OBJPROP_P(obj);
295293

296294
debug_info = zend_new_array(zend_hash_num_elements(props) + 1);
@@ -945,6 +943,17 @@ SPL_METHOD(SplObjectStorage, __unserialize)
945943
object_properties_load(&intern->std, Z_ARRVAL_P(members_zv));
946944
}
947945

946+
/* {{{ proto array SplObjectStorage::__debugInfo() */
947+
SPL_METHOD(SplObjectStorage, __debugInfo)
948+
{
949+
if (zend_parse_parameters_none() == FAILURE) {
950+
return;
951+
}
952+
953+
RETURN_ARR(spl_object_storage_debug_info(getThis()));
954+
}
955+
/* }}} */
956+
948957
ZEND_BEGIN_ARG_INFO(arginfo_Object, 0)
949958
ZEND_ARG_INFO(0, object)
950959
ZEND_END_ARG_INFO();
@@ -983,6 +992,7 @@ static const zend_function_entry spl_funcs_SplObjectStorage[] = {
983992
SPL_ME(SplObjectStorage, getInfo, arginfo_splobject_void,0)
984993
SPL_ME(SplObjectStorage, setInfo, arginfo_setInfo, 0)
985994
SPL_ME(SplObjectStorage, getHash, arginfo_getHash, 0)
995+
SPL_ME(SplObjectStorage, __debugInfo, arginfo_splobject_void,0)
986996
/* Countable */
987997
SPL_ME(SplObjectStorage, count, arginfo_splobject_void,0)
988998
/* Iterator */
@@ -1301,9 +1311,10 @@ static const zend_function_entry spl_funcs_MultipleIterator[] = {
13011311
SPL_ME(MultipleIterator, getFlags, arginfo_splobject_void, 0)
13021312
SPL_ME(MultipleIterator, setFlags, arginfo_MultipleIterator_setflags, 0)
13031313
SPL_ME(MultipleIterator, attachIterator, arginfo_MultipleIterator_attachIterator, 0)
1304-
SPL_MA(MultipleIterator, detachIterator, SplObjectStorage, detach, arginfo_MultipleIterator_detachIterator, 0)
1305-
SPL_MA(MultipleIterator, containsIterator, SplObjectStorage, contains, arginfo_MultipleIterator_containsIterator, 0)
1306-
SPL_MA(MultipleIterator, countIterators, SplObjectStorage, count, arginfo_splobject_void, 0)
1314+
SPL_MA(MultipleIterator, detachIterator, SplObjectStorage, detach, arginfo_MultipleIterator_detachIterator, 0)
1315+
SPL_MA(MultipleIterator, containsIterator, SplObjectStorage, contains, arginfo_MultipleIterator_containsIterator, 0)
1316+
SPL_MA(MultipleIterator, countIterators, SplObjectStorage, count, arginfo_splobject_void, 0)
1317+
SPL_MA(MultipleIterator, __debugInfo, SplObjectStorage, __debugInfo, arginfo_splobject_void, 0)
13071318
/* Iterator */
13081319
SPL_ME(MultipleIterator, rewind, arginfo_splobject_void, 0)
13091320
SPL_ME(MultipleIterator, valid, arginfo_splobject_void, 0)
@@ -1323,7 +1334,6 @@ PHP_MINIT_FUNCTION(spl_observer)
13231334
memcpy(&spl_handler_SplObjectStorage, &std_object_handlers, sizeof(zend_object_handlers));
13241335

13251336
spl_handler_SplObjectStorage.offset = XtOffsetOf(spl_SplObjectStorage, std);
1326-
spl_handler_SplObjectStorage.get_debug_info = spl_object_storage_debug_info;
13271337
spl_handler_SplObjectStorage.compare_objects = spl_object_storage_compare_objects;
13281338
spl_handler_SplObjectStorage.clone_obj = spl_object_storage_clone;
13291339
spl_handler_SplObjectStorage.get_gc = spl_object_storage_get_gc;

0 commit comments

Comments
 (0)