File tree 3 files changed +34
-1
lines changed
3 files changed +34
-1
lines changed Original file line number Diff line number Diff line change @@ -68,6 +68,8 @@ PHP NEWS
68
68
69
69
- SPL:
70
70
. Fixed bug GH-16337 (Use-after-free in SplHeap). (nielsdos)
71
+ . Fixed bug GH-16464 (Use-after-free in SplDoublyLinkedList::offsetSet()).
72
+ (ilutov)
71
73
72
74
- Standard:
73
75
. 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)
737
737
if (element != NULL ) {
738
738
/* the element is replaced, delref the old one as in
739
739
* SplDoublyLinkedList::pop() */
740
- zval_ptr_dtor (& element -> data );
740
+ zval garbage ;
741
+ ZVAL_COPY_VALUE (& garbage , & element -> data );
741
742
ZVAL_COPY (& element -> data , value );
743
+ zval_ptr_dtor (& garbage );
742
744
} else {
743
745
zval_ptr_dtor (value );
744
746
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