Index: tables/apr_hash.c
===================================================================
--- tables/apr_hash.c	(revision 813588)
+++ tables/apr_hash.c	(working copy)
@@ -67,12 +67,15 @@
 /*
  * The size of the array is always a power of two. We use the maximum
  * index rather than the size so that we can use bitwise-AND for
- * modular arithmetic.
- * The count of hash entries may be greater depending on the chosen
- * collision rate.
+ * modular arithmetic. The count of hash entries may be greater
+ * depending on the chosen collision rate.
+ *
+ * We allocate the bucket array in a sub-pool, "array_pool". This allows us
+ * to reclaim the old bucket array after an expansion.
  */
 struct apr_hash_t {
     apr_pool_t          *pool;
+    apr_pool_t          *array_pool;
     apr_hash_entry_t   **array;
     apr_hash_index_t     iterator;  /* For apr_hash_first(NULL, ...) */
     unsigned int         count, max;
@@ -89,7 +92,7 @@
 
 static apr_hash_entry_t **alloc_array(apr_hash_t *ht, unsigned int max)
 {
-   return apr_pcalloc(ht->pool, sizeof(*ht->array) * (max + 1));
+   return apr_pcalloc(ht->array_pool, sizeof(*ht->array) * (max + 1));
 }
 
 APR_DECLARE(apr_hash_t *) apr_hash_make(apr_pool_t *pool)
@@ -97,6 +100,7 @@
     apr_hash_t *ht;
     ht = apr_palloc(pool, sizeof(apr_hash_t));
     ht->pool = pool;
+    apr_pool_create(&ht->array_pool, pool); /* XXX: error checking */
     ht->free = NULL;
     ht->count = 0;
     ht->max = INITIAL_MAX;
@@ -163,10 +167,14 @@
 
 static void expand_array(apr_hash_t *ht)
 {
+    apr_pool_t *old_array_pool;
     apr_hash_index_t *hi;
     apr_hash_entry_t **new_array;
     unsigned int new_max;
 
+    old_array_pool = ht->array_pool;
+    apr_pool_create(&ht->array_pool, ht->pool); /* XXX: error checking */
+
     new_max = ht->max * 2 + 1;
     new_array = alloc_array(ht, new_max);
     for (hi = apr_hash_first(NULL, ht); hi; hi = apr_hash_next(hi)) {
@@ -176,6 +184,8 @@
     }
     ht->array = new_array;
     ht->max = new_max;
+
+    apr_pool_destroy(old_array_pool);
 }
 
 APR_DECLARE_NONSTD(unsigned int) apr_hashfunc_default(const char *char_key,
@@ -293,17 +303,16 @@
     unsigned int i, j;
 
     ht = apr_palloc(pool, sizeof(apr_hash_t) +
-                    sizeof(*ht->array) * (orig->max + 1) +
                     sizeof(apr_hash_entry_t) * orig->count);
     ht->pool = pool;
+    apr_pool_create(&ht->array_pool, ht->pool); /* XXX: error checking */
     ht->free = NULL;
     ht->count = orig->count;
     ht->max = orig->max;
     ht->hash_func = orig->hash_func;
-    ht->array = (apr_hash_entry_t **)((char *)ht + sizeof(apr_hash_t));
+    ht->array = alloc_array(ht, ht->max);
 
-    new_vals = (apr_hash_entry_t *)((char *)(ht) + sizeof(apr_hash_t) +
-                                    sizeof(*ht->array) * (orig->max + 1));
+    new_vals = (apr_hash_entry_t *)((char *)(ht) + sizeof(apr_hash_t));
     j = 0;
     for (i = 0; i <= ht->max; i++) {
         apr_hash_entry_t **new_entry = &(ht->array[i]);
@@ -417,6 +426,7 @@
 
     res = apr_palloc(p, sizeof(apr_hash_t));
     res->pool = p;
+    apr_pool_create(&res->array_pool, p); /* XXX: error checking */
     res->free = NULL;
     res->hash_func = base->hash_func;
     res->count = base->count;
