]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Check for overflow when expanding
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 28 Mar 2018 15:28:56 +0000 (16:28 +0100)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 28 Mar 2018 15:34:34 +0000 (16:34 +0100)
Provide errors
Check for realloc failure
More type fixes
Formatting

src/lib/util/heap.c

index c5967f732dc7bc3453c42e90a00e27c74fedcd30..b2367b5db89202be45f13617e77e441765c378d5 100644 (file)
@@ -50,12 +50,12 @@ struct fr_heap_t {
  *     2i+2.  These macros wrap the logic, so the code is more
  *     descriptive.
  */
-#define HEAP_PARENT(x) ( ( (x) - 1 ) / 2 )
-#define HEAP_LEFT(x) ( 2*(x) + 1 )
-/* #define HEAP_RIGHT(x) ( 2*(x) + 2 ) */
-#define        HEAP_SWAP(a, b) { void *_tmp = a; a = b; b = _tmp; }
+#define HEAP_PARENT(_x)        (((_x) - 1 ) / 2)
+#define HEAP_LEFT(_x)  (2 * (_x) + 1)
+/* #define HEAP_RIGHT(_x) (2 * (_x) + 2 ) */
+#define        HEAP_SWAP(_a, _b) { void *_tmp = _a; _a = _b; _b = _tmp; }
 
-static int fr_heap_bubble(fr_heap_t *hp, size_t child);
+static int fr_heap_bubble(fr_heap_t *hp, int32_t child);
 
 fr_heap_t *_fr_heap_create(fr_heap_cmp_t cmp, char const *type, size_t offset)
 {
@@ -108,22 +108,31 @@ int fr_heap_insert(fr_heap_t *hp, void *data)
 {
        size_t child = hp->num_elements;
 
-       /*
-        *      heap_id is a 32-bit signed integer.  If the heap will
-        *      grow to contain more than 2B elements, disallow
-        *      integer overflow.  Tho TBH, that should really never
-        *      happen.
-        */
-       if (hp->size >= INT32_MAX) {
-               return 0;
-       }
-
        /*
         *      Heap is full.  Double it's size.
         */
        if (child == hp->size) {
-               hp->size *= 2;
-               hp->p = talloc_realloc(hp, hp->p, void *, hp->size);
+               void    **n;
+               size_t  n_size = hp->size * 2;
+
+               /*
+                *      heap_id is a 32-bit signed integer.  If the heap will
+                *      grow to contain more than 2B elements, disallow
+                *      integer overflow.  Tho TBH, that should really never
+                *      happen.
+                */
+               if (n_size >= INT32_MAX) {
+                       fr_strerror_printf("Heap is full");
+                       return 0;
+               }
+
+               n = talloc_realloc(hp, hp->p, void *, n_size);
+               if (!n) {
+                       fr_strerror_printf("Failed expanding heap");
+                       return 0;
+               }
+               hp->size = n_size;
+               hp->p = n;
        }
 
        hp->p[child] = data;
@@ -133,13 +142,13 @@ int fr_heap_insert(fr_heap_t *hp, void *data)
 }
 
 
-static int fr_heap_bubble(fr_heap_t *hp, size_t child)
+static int fr_heap_bubble(fr_heap_t *hp, int32_t child)
 {
        /*
         *      Bubble up the element.
         */
        while (child > 0) {
-               size_t parent = HEAP_PARENT(child);
+               int32_t parent = HEAP_PARENT(child);
 
                /*
                 *      Parent is smaller than the child.  We're done.
@@ -164,7 +173,7 @@ static int fr_heap_bubble(fr_heap_t *hp, size_t child)
  */
 int fr_heap_extract(fr_heap_t *hp, void *data)
 {
-       int parent, child, max;
+       int32_t parent, child, max;
 
        if (!hp || (hp->num_elements == 0)) return 0;
 
@@ -280,8 +289,8 @@ static bool fr_heap_check(fr_heap_t *hp, void *data)
 }
 
 typedef struct heap_thing {
-       int data;
-       int32_t heap_id;                /* for the heap */
+       int     data;
+       int32_t heap;           /* for the heap */
 } heap_thing;
 
 
@@ -338,7 +347,7 @@ int main(int argc, char **argv)
 #endif
 
        if (skip) {
-               int entry;
+               int32_t entry;
 
                printf("%d elements to remove\n", ARRAY_SIZE / skip);