Skip to content

Commit 6750387

Browse files
committed
Fix GH-18322: SplObjectStorage debug handler mismanages memory
This hack was once necessary before there was a proper get_gc handler, but now it breaks the engine constraints. Closes GH-18323.
1 parent 8849a53 commit 6750387

File tree

3 files changed

+33
-4
lines changed

3 files changed

+33
-4
lines changed

NEWS

+4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ PHP NEWS
2727
(nielsdos)
2828
. Fix potential leaks when writing to BIO fails. (nielsdos)
2929

30+
- SPL:
31+
. Fixed bug GH-18322 (SplObjectStorage debug handler mismanages memory).
32+
(nielsdos)
33+
3034
- Standard:
3135
. Fixed bug GH-18145 (php8ts crashes in php_clear_stat_cache()).
3236
(Jakub Zelenka)

ext/spl/spl_observer.c

+2-4
Original file line numberDiff line numberDiff line change
@@ -340,12 +340,10 @@ static inline HashTable* spl_object_storage_debug_info(zend_object *obj) /* {{{
340340

341341
ZEND_HASH_FOREACH_PTR(&intern->storage, element) {
342342
array_init(&tmp);
343-
/* Incrementing the refcount of obj and inf would confuse the garbage collector.
344-
* Prefer to null the destructor */
345-
Z_ARRVAL_P(&tmp)->pDestructor = NULL;
346343
zval obj;
347-
ZVAL_OBJ(&obj, element->obj);
344+
ZVAL_OBJ_COPY(&obj, element->obj);
348345
add_assoc_zval_ex(&tmp, "obj", sizeof("obj") - 1, &obj);
346+
Z_TRY_ADDREF(element->inf);
349347
add_assoc_zval_ex(&tmp, "inf", sizeof("inf") - 1, &element->inf);
350348
zend_hash_next_index_insert(Z_ARRVAL(storage), &tmp);
351349
} ZEND_HASH_FOREACH_END();

ext/spl/tests/gh18322.phpt

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
GH-18322 (SplObjectStorage debug handler mismanages memory)
3+
--FILE--
4+
<?php
5+
6+
$stor = new SplObjectStorage();
7+
$obj = new stdClass;
8+
$stor[$obj] = 1;
9+
10+
$tmp = $stor->__debugInfo();
11+
$tmp2 = $tmp[array_key_first($tmp)];
12+
unset($tmp); // Drop $tmp2 RC to 1
13+
$tmp2[0]['obj'] = new stdClass;
14+
var_dump($tmp2);
15+
16+
?>
17+
--EXPECT--
18+
array(1) {
19+
[0]=>
20+
array(2) {
21+
["obj"]=>
22+
object(stdClass)#3 (0) {
23+
}
24+
["inf"]=>
25+
int(1)
26+
}
27+
}

0 commit comments

Comments
 (0)