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.
This commit is contained in:
Nikita Popov 2020-01-23 14:19:20 +01:00
parent dd3c664f8f
commit db9776c53c
3 changed files with 33 additions and 0 deletions

4
NEWS
View File

@ -25,6 +25,10 @@ PHP NEWS
. 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

View File

@ -257,6 +257,7 @@ static void spl_ptr_llist_pop(spl_ptr_llist *llist, zval *ret) /* {{{ */
llist->count--;
ZVAL_COPY(ret, &tail->data);
tail->prev = NULL;
if (llist->dtor) {
llist->dtor(tail);
}
@ -310,6 +311,7 @@ static void spl_ptr_llist_shift(spl_ptr_llist *llist, zval *ret) /* {{{ */
llist->count--;
ZVAL_COPY(ret, &head->data);
head->next = NULL;
if (llist->dtor) {
llist->dtor(head);
}

View File

@ -0,0 +1,27 @@
--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