]> granicus.if.org Git - php/commitdiff
MFH: Fix mem errors
authorEtienne Kneuss <colder@php.net>
Sun, 20 Jan 2008 13:26:03 +0000 (13:26 +0000)
committerEtienne Kneuss <colder@php.net>
Sun, 20 Jan 2008 13:26:03 +0000 (13:26 +0000)
ext/spl/spl_dllist.c
ext/spl/tests/dllist_006.phpt

index d7da333d604537da1d3b245d2b108b033e743784..18297867b03db8a55343c8e6cc8b9b67b2a7047e 100644 (file)
@@ -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;
index 72169e0dbb95f6753f245c8988804991c56ee07c..a776ed67e651bfc24c0e4ba7b815767ba5e56d07 100644 (file)
@@ -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===