Make sure we also NULL out next/prev of the removed element on
pop/shift. This only matter is that element is still being referenced
by an iterator.
. Fixed bug #79115 (ReflectionClass::isCloneable call reflected class
__destruct). (Nikita)
+- SPL:
+ . Fixed bug #79151 (heap use after free caused by
+ spl_dllist_it_helper_move_forward). (Nikita)
+
23 Jan 2020, PHP 7.3.14
- Core
llist->count--;
ZVAL_COPY(ret, &tail->data);
+ tail->prev = NULL;
if (llist->dtor) {
llist->dtor(tail);
}
llist->count--;
ZVAL_COPY(ret, &head->data);
+ head->next = NULL;
if (llist->dtor) {
llist->dtor(head);
}
--- /dev/null
+--TEST--
+Bug #79151: heap use after free caused by spl_dllist_it_helper_move_forward
+--FILE--
+<?php
+
+$a = new SplDoublyLinkedList();
+$a->setIteratorMode(SplDoublyLinkedList::IT_MODE_LIFO | SplDoublyLinkedList::IT_MODE_DELETE);
+$a->push(1);
+$a->rewind();
+$a->unshift(2);
+var_dump($a->pop());
+var_dump($a->next());
+
+$a = new SplDoublyLinkedList();
+$a->setIteratorMode(SplDoublyLinkedList::IT_MODE_FIFO | SplDoublyLinkedList::IT_MODE_DELETE);
+$a->unshift(1);
+$a->rewind();
+$a->push(2);
+var_dump($a->shift());
+var_dump($a->next());
+
+?>
+--EXPECT--
+int(1)
+NULL
+int(1)
+NULL