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 @@ -68,6 +68,8 @@ PHP NEWS
6868
6969- SPL:
7070 . Fixed bug GH-16337 (Use-after-free in SplHeap). (nielsdos)
71+ . Fixed bug GH-16464 (Use-after-free in SplDoublyLinkedList::offsetSet()).
72+ (ilutov)
7173
7274- Standard:
7375 . Fixed bug GH-16293 (Failed assertion when throwing in assert() callback with
Original file line number Diff line number Diff line change @@ -737,8 +737,10 @@ PHP_METHOD(SplDoublyLinkedList, offsetSet)
737737 if (element != NULL ) {
738738 /* the element is replaced, delref the old one as in
739739 * SplDoublyLinkedList::pop() */
740- zval_ptr_dtor (& element -> data );
740+ zval garbage ;
741+ ZVAL_COPY_VALUE (& garbage , & element -> data );
741742 ZVAL_COPY (& element -> data , value );
743+ zval_ptr_dtor (& garbage );
742744 } else {
743745 zval_ptr_dtor (value );
744746 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