summaryrefslogtreecommitdiffstats
path: root/src/H5Ocopy.c
diff options
context:
space:
mode:
authorNeil Fortner <nfortne2@hdfgroup.org>2010-04-08 18:29:59 (GMT)
committerNeil Fortner <nfortne2@hdfgroup.org>2010-04-08 18:29:59 (GMT)
commit7270b677a517d2ad4531dd07603b51f54282289d (patch)
treefe720c509644231689dc4063538f390ff31d7c65 /src/H5Ocopy.c
parente2d0e5f67edd2858e11a336a337154278305741d (diff)
downloadhdf5-7270b677a517d2ad4531dd07603b51f54282289d.zip
hdf5-7270b677a517d2ad4531dd07603b51f54282289d.tar.gz
hdf5-7270b677a517d2ad4531dd07603b51f54282289d.tar.bz2
[svn-r18535] Purpose: Fix bug 1815
Description: Attempting to copy an object with NULL references (all bytes zero) with the H5O_COPY_EXPAND_REFERENCE_FLAG flag set would cause a failure or an assertion (depending on whether it was in debug mode). Changed copy routine to detect NULL references (object and region) and avoid attempting to expand the reference in this case. Tested: jam, linew, amani (h5committest)
Diffstat (limited to 'src/H5Ocopy.c')
-rw-r--r--src/H5Ocopy.c79
1 files changed, 48 insertions, 31 deletions
diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c
index f9bf533..8896795 100644
--- a/src/H5Ocopy.c
+++ b/src/H5Ocopy.c
@@ -354,15 +354,19 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
oh_dst->max_compact = oh_src->max_compact;
oh_dst->min_dense = oh_src->min_dense;
- /* Initialize size of chunk array. The destination always has only one
- * chunk.
+ /* Initialize size of chunk array. Start off with zero chunks so this field
+ * is consistent with the current state of the chunk array. This is
+ * important if an error occurs.
*/
- oh_dst->alloc_nchunks = oh_dst->nchunks = 1;
+ oh_dst->alloc_nchunks = oh_dst->nchunks = 0;
- /* Allocate memory for the chunk array */
- if(NULL == (oh_dst->chunk = H5FL_SEQ_MALLOC(H5O_chunk_t, oh_dst->alloc_nchunks)))
+ /* Allocate memory for the chunk array - always start with 1 chunk */
+ if(NULL == (oh_dst->chunk = H5FL_SEQ_MALLOC(H5O_chunk_t, 1)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ /* Update number of allocated chunks. There are still no chunks used. */
+ oh_dst->alloc_nchunks = 1;
+
/* Allocate memory for "deleted" array. This array marks the message in
* the source that shouldn't be copied to the destination.
*/
@@ -579,6 +583,9 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
oh_dst->chunk[0].size = (size_t)dst_oh_size;
oh_dst->chunk[0].gap = dst_oh_gap;
+ /* Update size of chunk array. The destination now has one chunk. */
+ oh_dst->nchunks = 1;
+
/* Set up raw pointers and copy messages that didn't need special
* treatment. This has to happen after the destination header has been
* allocated.
@@ -1124,8 +1131,13 @@ H5O_copy_expand_ref(H5F_t *file_src, void *_src_ref, hid_t dxpl_id,
dst_oloc.addr = HADDR_UNDEF;
/* Attempt to copy object from source to destination file */
- if(H5O_copy_obj_by_ref(&src_oloc, dxpl_id, &dst_oloc, &dst_root_loc, cpy_info) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
+ if(src_oloc.addr != (haddr_t)0) {
+ if(H5O_copy_obj_by_ref(&src_oloc, dxpl_id, &dst_oloc, &dst_root_loc, cpy_info) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
+ } /* end if */
+ else
+ /* Set parameters so the reference is written as all 0's */
+ HDmemset(&dst_oloc.addr, 0, sizeof(dst_oloc.addr));
/* Set the object reference info for the destination file */
p = (uint8_t *)(&dst_ref[i]);
@@ -1136,7 +1148,7 @@ H5O_copy_expand_ref(H5F_t *file_src, void *_src_ref, hid_t dxpl_id,
else if(H5R_DATASET_REGION == ref_type) {
hdset_reg_ref_t *src_ref = (hdset_reg_ref_t *)_src_ref;
hdset_reg_ref_t *dst_ref = (hdset_reg_ref_t *)_dst_ref;
- uint8_t *buf; /* Buffer to store serialized selection in */
+ uint8_t *buf = NULL; /* Buffer to store serialized selection in */
H5HG_t hobjid; /* Heap object ID */
size_t buf_size; /* Length of object in heap */
@@ -1147,30 +1159,35 @@ H5O_copy_expand_ref(H5F_t *file_src, void *_src_ref, hid_t dxpl_id,
H5F_addr_decode(src_oloc.file, (const uint8_t **)&p, &(hobjid.addr));
INT32DECODE(p, hobjid.idx);
- /* Get the dataset region from the heap (allocate inside routine) */
- if((buf = (uint8_t *)H5HG_read(src_oloc.file, dxpl_id, &hobjid, NULL, &buf_size)) == NULL)
- HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, FAIL, "Unable to read dataset region information")
-
- /* Get the object oid for the dataset */
- p = (uint8_t *)buf;
- H5F_addr_decode(src_oloc.file, (const uint8_t **)&p, &(src_oloc.addr));
- dst_oloc.addr = HADDR_UNDEF;
-
- /* copy the object pointed by the ref to the destination */
- if(H5O_copy_obj_by_ref(&src_oloc, dxpl_id, &dst_oloc, &dst_root_loc, cpy_info) < 0) {
- H5MM_xfree(buf);
- HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
- } /* end if */
-
- /* Serialize object ID */
- p = (uint8_t *)buf;
- H5F_addr_encode(dst_oloc.file, &p, dst_oloc.addr);
-
- /* Save the serialized buffer to the destination */
- if(H5HG_insert(dst_oloc.file, dxpl_id, buf_size, buf, &hobjid) < 0) {
- H5MM_xfree(buf);
- HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "Unable to write dataset region information")
+ if(hobjid.addr != (haddr_t)0) {
+ /* Get the dataset region from the heap (allocate inside routine) */
+ if((buf = (uint8_t *)H5HG_read(src_oloc.file, dxpl_id, &hobjid, NULL, &buf_size)) == NULL)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, FAIL, "Unable to read dataset region information")
+
+ /* Get the object oid for the dataset */
+ p = (uint8_t *)buf;
+ H5F_addr_decode(src_oloc.file, (const uint8_t **)&p, &(src_oloc.addr));
+ dst_oloc.addr = HADDR_UNDEF;
+
+ /* copy the object pointed by the ref to the destination */
+ if(H5O_copy_obj_by_ref(&src_oloc, dxpl_id, &dst_oloc, &dst_root_loc, cpy_info) < 0) {
+ H5MM_xfree(buf);
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
+ } /* end if */
+
+ /* Serialize object ID */
+ p = (uint8_t *)buf;
+ H5F_addr_encode(dst_oloc.file, &p, dst_oloc.addr);
+
+ /* Save the serialized buffer to the destination */
+ if(H5HG_insert(dst_oloc.file, dxpl_id, buf_size, buf, &hobjid) < 0) {
+ H5MM_xfree(buf);
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "Unable to write dataset region information")
+ } /* end if */
} /* end if */
+ else
+ /* Set parameters so the reference is written as all 0's */
+ HDmemset(&hobjid, 0, sizeof(hobjid));
/* Set the dataset region reference info for the destination file */
p = (uint8_t *)(&dst_ref[i]);