Skip to content

Commit d4d0852

Browse files
alexdowadnikic
authored andcommitted
SplDoublyLinkedList uses iteration flags in iterator struct
The 'flags' field in spl_dllist_it was formerly unused. This means that if one started to iterate over an SplDoublyLinkedList using 'foreach', and then *changed* the iteration mode halfway, the 'foreach' loop would start iterating in the opposite direction. Probably this was not what was intended. Therefore, use the 'flags' field in spl_dllist_it for iteration via 'foreach'. For explicit iteration using methods like '::next()' and '::current()', continue to use the flags in the SplDoublyLinkedList object itself.
1 parent 9999e7f commit d4d0852

File tree

2 files changed

+41
-2
lines changed

2 files changed

+41
-2
lines changed

ext/spl/spl_dllist.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -964,7 +964,7 @@ static void spl_dllist_it_rewind(zend_object_iterator *iter) /* {{{ */
964964
spl_dllist_object *object = Z_SPLDLLIST_P(&iter->data);
965965
spl_ptr_llist *llist = object->llist;
966966

967-
spl_dllist_it_helper_rewind(&iterator->traverse_pointer, &iterator->traverse_position, llist, object->flags);
967+
spl_dllist_it_helper_rewind(&iterator->traverse_pointer, &iterator->traverse_position, llist, iterator->flags);
968968
}
969969
/* }}} */
970970

@@ -1005,7 +1005,7 @@ static void spl_dllist_it_move_forward(zend_object_iterator *iter) /* {{{ */
10051005

10061006
zend_user_it_invalidate_current(iter);
10071007

1008-
spl_dllist_it_helper_move_forward(&iterator->traverse_pointer, &iterator->traverse_position, object->llist, object->flags);
1008+
spl_dllist_it_helper_move_forward(&iterator->traverse_pointer, &iterator->traverse_position, object->llist, iterator->flags);
10091009
}
10101010
/* }}} */
10111011

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
--TEST--
2+
Iteration over SplDoublyLinkedList via 'foreach' does not change direction partway
3+
--FILE--
4+
<?php
5+
6+
$list = new SplDoublyLinkedList();
7+
$list->push(1);
8+
$list->push(2);
9+
$list->push(3);
10+
11+
/* SplDoublyLinkedList would previously check the iteration mode *each time*
12+
it would advance to the next item in a 'foreach' loop
13+
This meant that it could move forward, then backward, then forward if the
14+
iteration mode was changed in the middle of a loop */
15+
16+
$list->setIteratorMode(SplDoublyLinkedList::IT_MODE_FIFO);
17+
foreach ($list as $item) {
18+
$list->setIteratorMode(SplDoublyLinkedList::IT_MODE_LIFO);
19+
echo $item, "\n";
20+
}
21+
22+
echo "***\n";
23+
24+
$list->setIteratorMode(SplDoublyLinkedList::IT_MODE_LIFO);
25+
foreach ($list as $item) {
26+
$list->setIteratorMode(SplDoublyLinkedList::IT_MODE_FIFO);
27+
echo $item, "\n";
28+
}
29+
30+
31+
?>
32+
--EXPECT--
33+
1
34+
2
35+
3
36+
***
37+
3
38+
2
39+
1

0 commit comments

Comments
 (0)