From: Etienne Kneuss <colder@php.net> Date: Sun, 20 Jan 2008 13:26:03 +0000 (+0000) Subject: MFH: Fix mem errors X-Git-Tag: RELEASE_1_3_1~335 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5c5d5dd0f6b4d9f0976babcb67edf5cd90b07b1a;p=php MFH: Fix mem errors --- 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===