Blob Blame History Raw
diff -buNr gdbm-1.8.0.orig/falloc.c gdbm-1.8.0/falloc.c
--- gdbm-1.8.0.orig/falloc.c	Tue May 18 20:16:06 1999
+++ gdbm-1.8.0/falloc.c	Thu Apr 25 18:20:45 2002
@@ -180,6 +180,13 @@
   avail_block *new_blk;
   int index;
 
+  if (dbf->header->avail.count == dbf->header->avail.size)
+    {
+      /* We're kind of stuck here, so we re-split the header in order to
+         avoid crashing.  Sigh. */
+      push_avail_block(dbf);
+    }
+
   /* Set up variables. */
   new_el.av_adr = dbf->header->avail.next_block;
   new_el.av_size = ( ( (dbf->header->avail.size * sizeof (avail_elem)) >> 1)
@@ -196,12 +203,24 @@
   if (num_bytes != new_el.av_size) _gdbm_fatal (dbf, "read error");
 
   /* Add the elements from the new block to the header. */
-  for (index = 0; index < new_blk->count; index++)
+  index = 0;
+  while (index < new_blk->count)
+    {
+      while(index < new_blk->count
+            && dbf->header->avail.count < dbf->header->avail.size)
     {
       /* With luck, this will merge a lot of blocks! */
       _gdbm_put_av_elem(new_blk->av_table[index],
 			dbf->header->avail.av_table,
-			&dbf->header->avail.count, dbf->coalesce_blocks);
+			     &dbf->header->avail.count, TRUE);
+	   index++;
+	}
+      if (dbf->header->avail.count == dbf->header->avail.size)
+        {
+          /* We're kind of stuck here, so we re-split the header in order to
+             avoid crashing.  Sigh. */
+          push_avail_block(dbf);
+	}
     }
 
   /* Fix next_block, as well. */
@@ -210,9 +229,17 @@
   /* We changed the header. */
   dbf->header_changed = TRUE;
 
-  /* Free the previous avail block. */
+  /* Free the previous avail block.   It is possible that the header table
+     is now FULL, which will cause us to overflow it! */
+  if (dbf->header->avail.count == dbf->header->avail.size)
+    {
+      /* We're kind of stuck here, so we re-split the header in order to
+         avoid crashing.  Sigh. */
+      push_avail_block(dbf);
+    }
+
   _gdbm_put_av_elem (new_el, dbf->header->avail.av_table,
-		     &dbf->header->avail.count, dbf->coalesce_blocks);
+		     &dbf->header->avail.count, TRUE);
   free (new_blk);
 }