summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott MacVicar <scottmac@php.net>2009-06-17 13:27:09 +0000
committerScott MacVicar <scottmac@php.net>2009-06-17 13:27:09 +0000
commit3e58e86d01e4a4fc55c2cf48cc50b5dfa2a7a68a (patch)
tree7b40e6d1e83148eec5a651ad6fe7197b5b032898
parent73cd7e83eeef8bc38da65de21390f316fc2cb6a8 (diff)
downloadphp-git-3e58e86d01e4a4fc55c2cf48cc50b5dfa2a7a68a.tar.gz
MFH Add SplDoublyLinkedList::prev() and fix a memory leak when the iterator pointer isn't at the end
-rw-r--r--ext/spl/spl_dllist.c12
-rw-r--r--ext/spl/tests/dllist_010.phpt33
-rw-r--r--ext/spl/tests/dllist_011.phpt13
-rw-r--r--ext/spl/tests/dllist_memleak.phpt24
4 files changed, 82 insertions, 0 deletions
diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c
index 3109bc51eb..5f82529ca2 100644
--- a/ext/spl/spl_dllist.c
+++ b/ext/spl/spl_dllist.c
@@ -348,6 +348,7 @@ static void spl_dllist_object_free_storage(void *object TSRMLS_DC) /* {{{ */
}
spl_ptr_llist_destroy(intern->llist TSRMLS_CC);
+ SPL_LLIST_CHECK_DELREF(intern->traverse_pointer);
zval_ptr_dtor(&intern->retval);
efree(object);
@@ -1036,6 +1037,16 @@ SPL_METHOD(SplDoublyLinkedList, key)
}
/* }}} */
+/* {{{ proto void SplDoublyLinkedList::prev() U
+ Move to next entry */
+SPL_METHOD(SplDoublyLinkedList, prev)
+{
+ spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ spl_dllist_it_helper_move_forward(&intern->traverse_pointer, &intern->traverse_position, intern->llist, intern->flags ^ SPL_DLLIST_IT_LIFO TSRMLS_CC);
+}
+/* }}} */
+
/* {{{ proto void SplDoublyLinkedList::next() U
Move to next entry */
SPL_METHOD(SplDoublyLinkedList, next)
@@ -1164,6 +1175,7 @@ static const zend_function_entry spl_funcs_SplDoublyLinkedList[] = {
SPL_ME(SplDoublyLinkedList, current, NULL, ZEND_ACC_PUBLIC)
SPL_ME(SplDoublyLinkedList, key, NULL, ZEND_ACC_PUBLIC)
SPL_ME(SplDoublyLinkedList, next, NULL, ZEND_ACC_PUBLIC)
+ SPL_ME(SplDoublyLinkedList, prev, NULL, ZEND_ACC_PUBLIC)
SPL_ME(SplDoublyLinkedList, valid, NULL, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL}
};
diff --git a/ext/spl/tests/dllist_010.phpt b/ext/spl/tests/dllist_010.phpt
new file mode 100644
index 0000000000..7e389559e2
--- /dev/null
+++ b/ext/spl/tests/dllist_010.phpt
@@ -0,0 +1,33 @@
+--TEST--
+SPL: DoublyLinkedList: prev
+--FILE--
+<?php
+$dll = new SplDoublyLinkedList();
+$dll->push(1);
+$dll->push(2);
+$dll->push(3);
+$dll->push(4);
+
+
+$dll->rewind();
+$dll->prev();
+var_dump($dll->current());
+$dll->rewind();
+var_dump($dll->current());
+$dll->next();
+var_dump($dll->current());
+$dll->next();
+$dll->next();
+var_dump($dll->current());
+$dll->prev();
+var_dump($dll->current());
+
+?>
+===DONE===
+--EXPECT--
+NULL
+int(1)
+int(2)
+int(4)
+int(3)
+===DONE===
diff --git a/ext/spl/tests/dllist_011.phpt b/ext/spl/tests/dllist_011.phpt
new file mode 100644
index 0000000000..b9be872555
--- /dev/null
+++ b/ext/spl/tests/dllist_011.phpt
@@ -0,0 +1,13 @@
+--TEST--
+SPL: DoublyLinkedList: prev
+--FILE--
+<?php
+$dll = new SplDoublyLinkedList();
+$dll->rewind();
+$dll->prev();
+var_dump($dll->current());
+?>
+===DONE===
+--EXPECT--
+NULL
+===DONE===
diff --git a/ext/spl/tests/dllist_memleak.phpt b/ext/spl/tests/dllist_memleak.phpt
new file mode 100644
index 0000000000..9bae68bf2e
--- /dev/null
+++ b/ext/spl/tests/dllist_memleak.phpt
@@ -0,0 +1,24 @@
+--TEST--
+SPL: DoublyLinkedList: memory leak when iterator pointer isn't at the last element
+--FILE--
+<?php
+$dll = new SplDoublyLinkedList();
+$dll->push(1);
+$dll->push(2);
+$dll->push(3);
+$dll->push(4);
+
+
+$dll->rewind();
+echo $dll->current()."\n";
+$dll->next();
+$dll->next();
+echo $dll->current()."\n";
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+1
+3
+===DONE===