File tree Expand file tree Collapse file tree 3 files changed +34
-1
lines changed Expand file tree Collapse file tree 3 files changed +34
-1
lines changed Original file line number Diff line number Diff line change @@ -82,6 +82,8 @@ PHP NEWS
8282
8383- SPL:
8484 . Fixed bug GH-16337 (Use-after-free in SplHeap). (nielsdos)
85+ . Fixed bug GH-16464 (Use-after-free in SplDoublyLinkedList::offsetSet()).
86+ (ilutov)
8587
8688- Standard:
8789 . Fixed bug GH-16293 (Failed assertion when throwing in assert() callback with
Original file line number Diff line number Diff line change @@ -726,8 +726,10 @@ PHP_METHOD(SplDoublyLinkedList, offsetSet)
726726 if (element != NULL ) {
727727 /* the element is replaced, delref the old one as in
728728 * SplDoublyLinkedList::pop() */
729- zval_ptr_dtor (& element -> data );
729+ zval garbage ;
730+ ZVAL_COPY_VALUE (& garbage , & element -> data );
730731 ZVAL_COPY (& element -> data , value );
732+ zval_ptr_dtor (& garbage );
731733 } else {
732734 zval_ptr_dtor (value );
733735 zend_argument_error (spl_ce_OutOfRangeException , 1 , "is an invalid offset" );
Original file line number Diff line number Diff line change 1+ --TEST--
2+ GH-16464: Use-after-free in SplDoublyLinkedList::offsetSet() when modifying list in destructor of overwritten object
3+ --FILE--
4+ <?php
5+
6+ class C {
7+ public $ a ;
8+
9+ function __destruct () {
10+ global $ list ;
11+ var_dump ($ list ->pop ());
12+ }
13+ }
14+
15+ $ list = new SplDoublyLinkedList ;
16+ $ list ->add (0 , new C );
17+ $ list [0 ] = 42 ;
18+ var_dump ($ list );
19+
20+ ?>
21+ --EXPECTF--
22+ int(42)
23+ object(SplDoublyLinkedList)#%d (2) {
24+ ["flags":"SplDoublyLinkedList":private]=>
25+ int(0)
26+ ["dllist":"SplDoublyLinkedList":private]=>
27+ array(0) {
28+ }
29+ }
You can’t perform that action at this time.
0 commit comments