summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNeil Fortner <nfortne2@hdfgroup.org>2009-10-28 02:52:05 (GMT)
committerNeil Fortner <nfortne2@hdfgroup.org>2009-10-28 02:52:05 (GMT)
commit529eb825c235a8184e62f43dacb780f9657f62f8 (patch)
tree0b776ef4e3e9d138fbe5af4199523a9e9bb7e62d /src
parent8552aed7bb7b4a154c37affde9ef879f7345b454 (diff)
downloadhdf5-529eb825c235a8184e62f43dacb780f9657f62f8.zip
hdf5-529eb825c235a8184e62f43dacb780f9657f62f8.tar.gz
hdf5-529eb825c235a8184e62f43dacb780f9657f62f8.tar.bz2
[svn-r17764] Purpose: Fix bug 1483
Description: H5HG_load made improper assumptions about the ordering of object indices, namely that they are in order. Not only is this not guaranteed by the file format spec, but this condition can be violated if id's "wrap around" which can happen when overwriting VL data. H5HG_load has been fixed to handle any order of indices. Also fixed some other bugs involving allocation of global heaps in memory. Tested: jam, linew, amani (h5committest)
Diffstat (limited to 'src')
-rw-r--r--src/H5HG.c12
-rw-r--r--src/H5HGcache.c26
2 files changed, 24 insertions, 14 deletions
diff --git a/src/H5HG.c b/src/H5HG.c
index bb5e664..520f2eb 100644
--- a/src/H5HG.c
+++ b/src/H5HG.c
@@ -310,7 +310,7 @@ H5HG_alloc (H5F_t *f, H5HG_heap_t *heap, size_t size, unsigned * heap_flags_ptr)
* Find an ID for the new object. ID zero is reserved for the free space
* object.
*/
- if(heap->nused<H5HG_MAXIDX)
+ if(heap->nused<=H5HG_MAXIDX)
idx=heap->nused++;
else {
for (idx=1; idx<heap->nused; idx++)
@@ -326,17 +326,21 @@ H5HG_alloc (H5F_t *f, H5HG_heap_t *heap, size_t size, unsigned * heap_flags_ptr)
H5HG_obj_t *new_obj; /* New array of object descriptions */
/* Determine the new number of objects to index */
- new_alloc=MAX(heap->nalloc*2,(idx+1));
- assert(new_alloc<=(H5HG_MAXIDX+1));
+ /* nalloc is *not* guaranteed to be a power of 2! - NAF 10/26/09 */
+ new_alloc = MIN(MAX(heap->nalloc * 2, (idx + 1)), (H5HG_MAXIDX + 1));
+ HDassert(idx < new_alloc);
/* Reallocate array of objects */
if (NULL==(new_obj = H5FL_SEQ_REALLOC (H5HG_obj_t, heap->obj, new_alloc)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "memory allocation failed")
+ /* Clear newly allocated space */
+ HDmemset(&new_obj[heap->nalloc], 0, (new_alloc - heap->nalloc) * sizeof(heap->obj[0]));
+
/* Update heap information */
heap->nalloc=new_alloc;
heap->obj=new_obj;
- assert(heap->nalloc>heap->nused);
+ HDassert(heap->nalloc>heap->nused);
} /* end if */
/* Initialize the new object */
diff --git a/src/H5HGcache.c b/src/H5HGcache.c
index f3d0f3a..ee318aa 100644
--- a/src/H5HGcache.c
+++ b/src/H5HGcache.c
@@ -171,11 +171,12 @@ H5HG_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * udata1,
/* Decode each object */
p = heap->chunk + H5HG_SIZEOF_HDR(f);
nalloc = H5HG_NOBJS(f, heap->size);
- if(NULL == (heap->obj = H5FL_SEQ_MALLOC(H5HG_obj_t, nalloc)))
+
+ /* Calloc the obj array because the file format spec makes no guarantee
+ * about the order of the objects, and unused slots must be set to zero.
+ */
+ if(NULL == (heap->obj = H5FL_SEQ_CALLOC(H5HG_obj_t, nalloc)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- heap->obj[0].nrefs = 0;
- heap->obj[0].size = 0;
- heap->obj[0].begin = NULL;
heap->nalloc = nalloc;
while(p < (heap->chunk + heap->size)) {
@@ -202,14 +203,19 @@ H5HG_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * udata1,
/* Determine the new number of objects to index */
new_alloc = MAX(heap->nalloc * 2, (idx + 1));
+ HDassert(idx < new_alloc);
/* Reallocate array of objects */
if(NULL == (new_obj = H5FL_SEQ_REALLOC(H5HG_obj_t, heap->obj, new_alloc)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ /* Clear newly allocated space */
+ HDmemset(&new_obj[heap->nalloc], 0, (new_alloc - heap->nalloc) * sizeof(heap->obj[0]));
+
/* Update heap information */
heap->nalloc = new_alloc;
heap->obj = new_obj;
+ HDassert(heap->nalloc>heap->nused);
} /* end if */
UINT16DECODE(p, heap->obj[idx].nrefs);
@@ -220,16 +226,16 @@ H5HG_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * udata1,
/*
* The total storage size includes the size of the object header
* and is zero padded so the next object header is properly
- * aligned. The last bit of space is the free space object whose
- * size is never padded and already includes the object header.
+ * aligned. The entire obj array was calloc'ed, so no need to zero
+ * the space here. The last bit of space is the free space object
+ * whose size is never padded and already includes the object
+ * header.
*/
if(idx > 0) {
need = H5HG_SIZEOF_OBJHDR(f) + H5HG_ALIGN(heap->obj[idx].size);
- /* Check for "gap" in index numbers (caused by deletions) and fill in heap object values */
- if(idx > (max_idx + 1))
- HDmemset(&heap->obj[max_idx + 1], 0, sizeof(H5HG_obj_t) * (idx - (max_idx + 1)));
- max_idx = idx;
+ if(idx > max_idx)
+ max_idx = idx;
} /* end if */
else
need = heap->obj[idx].size;