]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2850. [bug] If isc_heap_insert() failed due to memory shortage
authorTatuya JINMEI 神明達哉 <jinmei@isc.org>
Thu, 4 Feb 2010 23:27:32 +0000 (23:27 +0000)
committerTatuya JINMEI 神明達哉 <jinmei@isc.org>
Thu, 4 Feb 2010 23:27:32 +0000 (23:27 +0000)
the heap would have corrupted entries. [RT #20951]

9.8.0, 9.7.1(?), 9.6.2, 9.5.3
(what about 9.4-ESV?)

CHANGES
lib/isc/heap.c

diff --git a/CHANGES b/CHANGES
index b2bc01c54ae5bc332bba07c03d5ece4ca9a0a0f5..508bbd3d2b17c23f509d81af797cb8f705c9d7d9 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+2850.  [bug]           If isc_heap_insert() failed due to memory shortage
+                       the heap would have corrupted entries. [RT #20951]
+
 2849.  [bug]           Don't treat errors from the xml2 library as fatal.
                        [RT #20945]
 
index 91d78c06d468bcdb6b0a466e2631717dafbe79bd..d25cb501267e36dd26d926676f56f1e1ce6acf89 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: heap.c,v 1.37 2007/10/19 17:15:53 explorer Exp $ */
+/* $Id: heap.c,v 1.37.240.1 2010/02/04 23:27:32 jinmei Exp $ */
 
 /*! \file
  * Heap implementation of priority queues adapted from the following:
@@ -149,10 +149,12 @@ float_up(isc_heap_t *heap, unsigned int i, void *elt) {
             i > 1 && heap->compare(elt, heap->array[p]) ;
             i = p, p = heap_parent(i)) {
                heap->array[i] = heap->array[p];
+               INSIST(heap->array[i] != NULL);
                if (heap->index != NULL)
                        (heap->index)(heap->array[i], i);
        }
        heap->array[i] = elt;
+       INSIST(heap->array[i] != NULL);
        if (heap->index != NULL)
                (heap->index)(heap->array[i], i);
 
@@ -173,11 +175,13 @@ sink_down(isc_heap_t *heap, unsigned int i, void *elt) {
                if (heap->compare(elt, heap->array[j]))
                        break;
                heap->array[i] = heap->array[j];
+               INSIST(heap->array[i] != NULL);
                if (heap->index != NULL)
                        (heap->index)(heap->array[i], i);
                i = j;
        }
        heap->array[i] = elt;
+       INSIST(heap->array[i] != NULL);
        if (heap->index != NULL)
                (heap->index)(heap->array[i], i);
 
@@ -186,15 +190,17 @@ sink_down(isc_heap_t *heap, unsigned int i, void *elt) {
 
 isc_result_t
 isc_heap_insert(isc_heap_t *heap, void *elt) {
-       unsigned int i;
+       unsigned int new_last;
 
        REQUIRE(VALID_HEAP(heap));
 
-       i = ++heap->last;
-       if (heap->last >= heap->size && !resize(heap))
+       new_last = heap->last + 1;
+       RUNTIME_CHECK(new_last > 0); /* overflow check */
+       if (new_last >= heap->size && !resize(heap))
                return (ISC_R_NOMEMORY);
+       heap->last = new_last;
 
-       float_up(heap, i, elt);
+       float_up(heap, new_last, elt);
 
        return (ISC_R_SUCCESS);
 }
@@ -203,10 +209,16 @@ void
 isc_heap_delete(isc_heap_t *heap, unsigned int index) {
        void *elt;
        isc_boolean_t less;
+       void **array;
+       unsigned int size, last;
 
        REQUIRE(VALID_HEAP(heap));
        REQUIRE(index >= 1 && index <= heap->last);
 
+       array = heap->array;
+       size = heap->size;
+       last = heap->last;
+
        if (index == heap->last) {
                heap->array[heap->last] = NULL;
                heap->last--;
@@ -215,8 +227,13 @@ isc_heap_delete(isc_heap_t *heap, unsigned int index) {
                heap->array[heap->last] = NULL;
                heap->last--;
 
+               INSIST(array == heap->array &&
+                      size == heap->size &&
+                      last == heap->last + 1);
+
                less = heap->compare(elt, heap->array[index]);
                heap->array[index] = elt;
+               INSIST(heap->array[index] != NULL);
                if (less)
                        float_up(heap, index, heap->array[index]);
                else