summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEtienne Kneuss <colder@php.net>2008-01-20 13:26:03 +0000
committerEtienne Kneuss <colder@php.net>2008-01-20 13:26:03 +0000
commit5c5d5dd0f6b4d9f0976babcb67edf5cd90b07b1a (patch)
tree4a0bd9bdedb2f6fc645cf79c8945399f684982c2
parenta3c09d611caac49bd0b1322dc74c0b2fb94f0318 (diff)
downloadphp-git-5c5d5dd0f6b4d9f0976babcb67edf5cd90b07b1a.tar.gz
MFH: Fix mem errors
-rw-r--r--ext/spl/spl_dllist.c60
-rw-r--r--ext/spl/tests/dllist_006.phpt4
2 files changed, 37 insertions, 27 deletions
diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c
index d7da333d60..18297867b0 100644
--- a/ext/spl/spl_dllist.c
+++ b/ext/spl/spl_dllist.c
@@ -39,18 +39,12 @@ PHPAPI zend_class_entry *spl_ce_SplDoublyLinkedList;
PHPAPI zend_class_entry *spl_ce_SplQueue;
PHPAPI zend_class_entry *spl_ce_SplStack;
-#define SPL_LLIST_DELREF(elem, dtor) if(!--(elem)->rc) { \
- if(dtor) { \
- dtor(elem); \
- } \
+#define SPL_LLIST_DELREF(elem) if(!--(elem)->rc) { \
efree(elem); \
elem = NULL; \
}
-#define SPL_LLIST_CHECK_DELREF(elem, dtor) if((elem) && !--(elem)->rc) { \
- if(dtor) { \
- dtor(elem); \
- } \
+#define SPL_LLIST_CHECK_DELREF(elem) if((elem) && !--(elem)->rc) { \
efree(elem); \
elem = NULL; \
}
@@ -113,7 +107,11 @@ struct _spl_dllist_it {
/* {{{ spl_ptr_llist */
static void spl_ptr_llist_zval_dtor(spl_ptr_llist_element *elem) { /* {{{ */
- zval_ptr_dtor((zval **)&elem->data);
+ if (elem->data) {
+ zval_ptr_dtor((zval **)&elem->data);
+ elem->data = NULL;
+ }
+
}
/* }}} */
@@ -148,7 +146,10 @@ static void spl_ptr_llist_destroy(spl_ptr_llist *llist) /* {{{ */
while (current) {
next = current->next;
- SPL_LLIST_DELREF(current, dtor);
+ if(current && dtor) {
+ dtor(current);
+ }
+ SPL_LLIST_DELREF(current);
current = next;
}
@@ -225,7 +226,6 @@ static void *spl_ptr_llist_pop(spl_ptr_llist *llist) /* {{{ */
{
void *data;
spl_ptr_llist_element *tail = llist->tail;
- spl_ptr_llist_dtor_func dtor = NULL;
if (tail == NULL) {
return NULL;
@@ -240,8 +240,9 @@ static void *spl_ptr_llist_pop(spl_ptr_llist *llist) /* {{{ */
llist->tail = tail->prev;
llist->count--;
data = tail->data;
+ tail->data = NULL;
- SPL_LLIST_DELREF(tail, dtor);
+ SPL_LLIST_DELREF(tail);
return data;
}
@@ -275,7 +276,6 @@ static void *spl_ptr_llist_shift(spl_ptr_llist *llist) /* {{{ */
{
void *data;
spl_ptr_llist_element *head = llist->head;
- spl_ptr_llist_dtor_func dtor = NULL;
if (head == NULL) {
return NULL;
@@ -290,8 +290,9 @@ static void *spl_ptr_llist_shift(spl_ptr_llist *llist) /* {{{ */
llist->head = head->next;
llist->count--;
data = head->data;
+ head->data = NULL;
- SPL_LLIST_DELREF(head, dtor);
+ SPL_LLIST_DELREF(head);
return data;
}
@@ -664,8 +665,7 @@ static long spl_dllist_offset_convert(zval *offset TSRMLS_DC) /* {{{ */
return Z_LVAL_P(offset);
}
}
- zend_throw_exception(spl_ce_OutOfRangeException, "Invalid offset", 0 TSRMLS_CC);
- return 0;
+ return -1;
}
/* }}} */
@@ -704,7 +704,7 @@ SPL_METHOD(SplDoublyLinkedList, offsetGet)
index = spl_dllist_offset_convert(zindex TSRMLS_CC);
if (index < 0 || index >= intern->llist->count) {
- zend_throw_exception(spl_ce_OutOfRangeException, "Offset out of range", 0 TSRMLS_CC);
+ zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid or out of range", 0 TSRMLS_CC);
return;
}
@@ -744,7 +744,7 @@ SPL_METHOD(SplDoublyLinkedList, offsetSet)
index = spl_dllist_offset_convert(zindex TSRMLS_CC);
if (index < 0 || index >= intern->llist->count) {
- zend_throw_exception(spl_ce_OutOfRangeException, "Offset out of range", 0 TSRMLS_CC);
+ zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid or out of range", 0 TSRMLS_CC);
return;
}
@@ -804,7 +804,11 @@ SPL_METHOD(SplDoublyLinkedList, offsetUnset)
}
/* finally, delete the element */
llist->count--;
- SPL_LLIST_DELREF(element, llist->dtor);
+
+ if(llist->dtor) {
+ llist->dtor(element);
+ }
+ SPL_LLIST_DELREF(element);
} else {
zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid", 0 TSRMLS_CC);
return;
@@ -815,7 +819,7 @@ static void spl_dllist_it_dtor(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
{
spl_dllist_it *iterator = (spl_dllist_it *)iter;
- SPL_LLIST_CHECK_DELREF(iterator->traverse_pointer, iterator->object->llist->dtor);
+ SPL_LLIST_CHECK_DELREF(iterator->traverse_pointer);
zend_user_it_invalidate_current(iter TSRMLS_CC);
zval_ptr_dtor((zval**)&iterator->intern.it.data);
@@ -838,7 +842,7 @@ static void spl_dllist_it_get_current_data(zend_object_iterator *iter, zval ***d
spl_dllist_it *iterator = (spl_dllist_it *)iter;
spl_ptr_llist_element *element = iterator->traverse_pointer;
- if (element == NULL) {
+ if (element == NULL || element->data == NULL) {
*data = NULL;
} else {
*data = (zval **)&element->data;
@@ -869,17 +873,23 @@ static void spl_dllist_it_move_forward(zend_object_iterator *iter TSRMLS_DC) /*
iterator->traverse_pointer = old->prev;
iterator->traverse_position--;
if (iterator->flags & SPL_DLLIST_IT_DELETE) {
- spl_ptr_llist_pop(object->llist);
+ zval *prev = (zval *)spl_ptr_llist_pop(object->llist);
+ if (prev) {
+ zval_ptr_dtor((zval **)&prev);
+ }
}
} else {
iterator->traverse_pointer = old->next;
iterator->traverse_position++;
if (iterator->flags & SPL_DLLIST_IT_DELETE) {
- spl_ptr_llist_shift(object->llist);
+ zval *prev = (zval *)spl_ptr_llist_shift(object->llist);
+ if (prev) {
+ zval_ptr_dtor((zval **)&prev);
+ }
}
}
- SPL_LLIST_DELREF(old, object->llist->dtor);
+ SPL_LLIST_DELREF(old);
SPL_LLIST_CHECK_ADDREF(iterator->traverse_pointer);
}
}
@@ -891,7 +901,7 @@ static void spl_dllist_it_rewind(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
spl_dllist_object *object = iterator->object;
spl_ptr_llist *llist = object->llist;
- SPL_LLIST_CHECK_DELREF(iterator->traverse_pointer, llist->dtor);
+ SPL_LLIST_CHECK_DELREF(iterator->traverse_pointer);
if (iterator->flags & SPL_DLLIST_IT_LIFO) {
iterator->traverse_position = llist->count-1;
iterator->traverse_pointer = llist->tail;
diff --git a/ext/spl/tests/dllist_006.phpt b/ext/spl/tests/dllist_006.phpt
index 72169e0dbb..a776ed67e6 100644
--- a/ext/spl/tests/dllist_006.phpt
+++ b/ext/spl/tests/dllist_006.phpt
@@ -58,7 +58,7 @@ Unsetting..
int(3)
int(4)
int(2)
-Exception: Invalid offset
+Exception: Offset invalid or out of range
int(1)
-Exception: Offset out of range
+Exception: Offset invalid or out of range
===DONE===