Skip to content

DoubleEndedIterator implementation wrong #316

@Xenira

Description

@Xenira

It seems the double ended iterator is not behaving as expected.

It is important to note that both back and forth work on the same range, and do not cross: iteration is over when they meet in the middle.
https://doc.rust-lang.org/std/iter/trait.DoubleEndedIterator.html

There should be two pointers one pointing to the position at the beginning and one at the end.

The code moves the one pointer instead. Next back should move the later and keep the pointer used in next untouched.

impl<'a> DoubleEndedIterator for Iter<'a> {
fn next_back(&mut self) -> Option<Self::Item> {
let key_type = unsafe {
zend_hash_get_current_key_type_ex(
self.ht as *const ZendHashTable as *mut ZendHashTable,
&mut self.pos as *mut HashPosition,
)
};
if key_type == -1 {
return None;
}
let key = Zval::new();
unsafe {
zend_hash_get_current_key_zval_ex(
self.ht as *const ZendHashTable as *mut ZendHashTable,
&key as *const Zval as *mut Zval,
&mut self.pos as *mut HashPosition,
);
}
let value = unsafe {
&*zend_hash_get_current_data_ex(
self.ht as *const ZendHashTable as *mut ZendHashTable,
&mut self.pos as *mut HashPosition,
)
};
let key = match ArrayKey::from_zval(&key) {
Some(key) => key,
None => ArrayKey::Long(self.current_num),
};
unsafe {
zend_hash_move_backwards_ex(
self.ht as *const ZendHashTable as *mut ZendHashTable,
&mut self.pos as *mut HashPosition,
)
};
self.current_num -= 1;

If i have [1, 2, 3, 4, 5] - next() should return 1 and next_back() 5

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions