mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-01-30 15:32:37 +08:00
[svn-r8953]
Purpose: Bug fix Description: When a simple dataspace is created, its extent should be set before using it, or it will silently function as a NULL dataspace. Solution: Added checks on user-supplied dataspaces. Now dataspaces without extents set will throw errors; users must explicitly set a dataspace to be NULL. Platforms tested: sleipnir, windows
This commit is contained in:
parent
7a07c6cc13
commit
5a19f181b3
@ -224,6 +224,10 @@ H5A_create(const H5G_entry_t *ent, const char *name, const H5T_t *type,
|
||||
assert(type);
|
||||
assert(space);
|
||||
|
||||
/* Check if the dataspace has an extent set (or is NULL) */
|
||||
if( !(H5S_has_extent(space)) )
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspace extent has not been set")
|
||||
|
||||
/* Build the attribute information */
|
||||
if((attr = H5MM_calloc(sizeof(H5A_t)))==NULL)
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for attribute info")
|
||||
|
@ -2135,6 +2135,10 @@ H5D_create(H5G_entry_t *loc, const char *name, hid_t type_id, const H5S_t *space
|
||||
if(H5T_detect_class(type, H5T_VLEN))
|
||||
has_vl_type=TRUE;
|
||||
|
||||
/* Check if the dataspace has an extent set (or is NULL) */
|
||||
if( !(H5S_has_extent(space)) )
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "dataspace extent has not been set.")
|
||||
|
||||
/* Initialize the dataset object */
|
||||
if(NULL == (new_dset = H5D_new(dcpl_id,TRUE,has_vl_type)))
|
||||
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
|
||||
@ -3559,6 +3563,8 @@ H5Diterate(void *buf, hid_t type_id, hid_t space_id, H5D_operator_t op,
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid datatype")
|
||||
if (NULL == (space = H5I_object_verify(space_id, H5I_DATASPACE)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataspace")
|
||||
if( !(H5S_has_extent(space)) )
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspace does not have extent set")
|
||||
|
||||
ret_value=H5S_select_iterate(buf,type_id,space,op,operator_data);
|
||||
|
||||
|
16
src/H5Dio.c
16
src/H5Dio.c
@ -224,6 +224,10 @@ H5D_fill(const void *fill, const H5T_t *fill_type, void *buf, const H5T_t *buf_t
|
||||
assert(buf_type);
|
||||
assert(space);
|
||||
|
||||
/* Make sure the dataspace has an extent set (or is NULL) */
|
||||
if( !(H5S_has_extent(space)) )
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspace extent has not been set")
|
||||
|
||||
/* Get the memory and file datatype sizes */
|
||||
src_type_size = H5T_get_size(fill_type);
|
||||
dst_type_size = H5T_get_size(buf_type);
|
||||
@ -683,6 +687,12 @@ H5D_read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
|
||||
if (nelmts!=(hsize_t)H5S_GET_SELECT_NPOINTS(file_space))
|
||||
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "src and dest data spaces have different sizes")
|
||||
|
||||
/* Make sure that both selections have their extents set */
|
||||
if( !(H5S_has_extent(file_space)) )
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file dataspace does not have extent set")
|
||||
if( !(H5S_has_extent(mem_space)) )
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "memory dataspace does not have extent set")
|
||||
|
||||
/* Retrieve dataset properties */
|
||||
/* <none needed in the general case> */
|
||||
|
||||
@ -933,6 +943,12 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
|
||||
if (nelmts!=(hsize_t)H5S_GET_SELECT_NPOINTS(file_space))
|
||||
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "src and dest data spaces have different sizes")
|
||||
|
||||
/* Make sure that both selections have their extents set */
|
||||
if( !(H5S_has_extent(file_space)) )
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file dataspace does not have extent set")
|
||||
if( !(H5S_has_extent(mem_space)) )
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "memory dataspace does not have extent set")
|
||||
|
||||
/* Retrieve dataset properties */
|
||||
/* <none needed currently> */
|
||||
|
||||
|
32
src/H5S.c
32
src/H5S.c
@ -2167,6 +2167,38 @@ done:
|
||||
FUNC_LEAVE_NOAPI(ret_value);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5S_has_extent
|
||||
*
|
||||
* Purpose: Determines if a simple dataspace's extent has been set (e.g.,
|
||||
* by H5Sset_extent_simple() ). Helps avoid write errors.
|
||||
*
|
||||
* Return: TRUE if dataspace has extent set
|
||||
* FALSE if dataspace's extent is uninitialized
|
||||
*
|
||||
* Programmer: James Laird
|
||||
*
|
||||
* Date: July 23, 2004
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
hbool_t
|
||||
H5S_has_extent(const H5S_t *ds)
|
||||
{
|
||||
htri_t ret_value;
|
||||
FUNC_ENTER_NOAPI(H5S_has_extent, FAIL)
|
||||
|
||||
assert(ds);
|
||||
|
||||
if(ds->extent.rank==0 && ds->extent.nelem == 0 && ds->extent.type != H5S_NULL)
|
||||
ret_value = FALSE;
|
||||
else
|
||||
ret_value = TRUE;
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5S_set_extent_real
|
||||
|
@ -216,6 +216,7 @@ H5_DLL hsize_t H5S_get_npoints_max(const H5S_t *ds);
|
||||
H5_DLL int H5S_get_simple_extent_ndims(const H5S_t *ds);
|
||||
H5_DLL int H5S_get_simple_extent_dims(const H5S_t *ds, hsize_t dims[]/*out*/,
|
||||
hsize_t max_dims[]/*out*/);
|
||||
H5_DLL hbool_t H5S_has_extent(const H5S_t *ds);
|
||||
H5_DLL herr_t H5S_modify(struct H5G_entry_t *ent, const H5S_t *space,
|
||||
hbool_t update_time, hid_t dxpl_id);
|
||||
H5_DLL herr_t H5S_append(H5F_t *f, hid_t dxpl_id, struct H5O_t *oh, const H5S_t *ds);
|
||||
|
94
test/th5s.c
94
test/th5s.c
@ -30,6 +30,10 @@
|
||||
#define TESTFILE "th5s.h5"
|
||||
#define DATAFILE "th5s1.h5"
|
||||
#define NULLFILE "th5s2.h5"
|
||||
#define BASICFILE "th5s3.h5"
|
||||
#define BASICDATASET "basic_dataset"
|
||||
#define BASICDATASET2 "basic_dataset2"
|
||||
#define BASICATTR "basic_attribute"
|
||||
#define NULLDATASET "null_dataset"
|
||||
#define NULLATTR "null_attribute"
|
||||
|
||||
@ -86,6 +90,7 @@ test_h5s_basic(void)
|
||||
hid_t fid1; /* HDF5 File IDs */
|
||||
hid_t sid1, sid2; /* Dataspace ID */
|
||||
hid_t dset1; /* Dataset ID */
|
||||
hid_t aid1; /* Attribute ID */
|
||||
int rank; /* Logical rank of dataspace */
|
||||
hsize_t dims1[] = {SPACE1_DIM1, SPACE1_DIM2, SPACE1_DIM3};
|
||||
hsize_t dims2[] = {SPACE2_DIM1, SPACE2_DIM2, SPACE2_DIM3,
|
||||
@ -205,6 +210,90 @@ test_h5s_basic(void)
|
||||
|
||||
ret = H5Sclose(sid1);
|
||||
CHECK_I(ret, "H5Sclose");
|
||||
|
||||
/*
|
||||
* Try writing simple dataspaces without setting their extents
|
||||
*/
|
||||
/* Create the file */
|
||||
fid1 = H5Fcreate(BASICFILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
|
||||
CHECK(fid1, FAIL, "H5Fcreate");
|
||||
|
||||
dims1[0]=SPACE1_DIM1;
|
||||
|
||||
sid1 = H5Screate(H5S_SIMPLE);
|
||||
CHECK(sid1, FAIL, "H5Screate");
|
||||
sid2 = H5Screate_simple(1, dims1, dims1);
|
||||
CHECK(sid2, FAIL, "H5Screate");
|
||||
|
||||
/* This dataset's space has no extent; it should not be created */
|
||||
H5E_BEGIN_TRY {
|
||||
dset1 = H5Dcreate(fid1, BASICDATASET, H5T_NATIVE_INT, sid1, H5P_DEFAULT);
|
||||
} H5E_END_TRY
|
||||
VERIFY(dset1, FAIL, "H5Dcreate");
|
||||
|
||||
dset1 = H5Dcreate(fid1, BASICDATASET2, H5T_NATIVE_INT, sid2, H5P_DEFAULT);
|
||||
CHECK(dset1, FAIL, "H5Dcreate");
|
||||
|
||||
/* Try some writes with the bad dataspace (sid1) */
|
||||
H5E_BEGIN_TRY {
|
||||
ret = H5Dwrite(dset1, H5T_NATIVE_INT, sid1, H5S_ALL, H5P_DEFAULT, &n);
|
||||
} H5E_END_TRY
|
||||
VERIFY(ret, FAIL, "H5Dwrite");
|
||||
|
||||
H5E_BEGIN_TRY {
|
||||
ret = H5Dwrite(dset1, H5T_NATIVE_INT, H5S_ALL, sid1, H5P_DEFAULT, &n);
|
||||
} H5E_END_TRY
|
||||
VERIFY(ret, FAIL, "H5Dwrite");
|
||||
|
||||
H5E_BEGIN_TRY {
|
||||
ret = H5Dwrite(dset1, H5T_NATIVE_INT, sid1, sid1, H5P_DEFAULT, &n);
|
||||
} H5E_END_TRY
|
||||
VERIFY(ret, FAIL, "H5Dwrite");
|
||||
|
||||
/* Try to iterate using the bad dataspace */
|
||||
H5E_BEGIN_TRY {
|
||||
ret = H5Diterate(&n, H5T_NATIVE_INT, sid1, NULL, NULL);
|
||||
} H5E_END_TRY
|
||||
VERIFY(ret, FAIL, "H5Diterate");
|
||||
|
||||
/* Try to fill using the bad dataspace */
|
||||
H5E_BEGIN_TRY {
|
||||
ret = H5Dfill(NULL, H5T_NATIVE_INT, &n, H5T_NATIVE_INT, sid1);
|
||||
} H5E_END_TRY
|
||||
VERIFY(ret, FAIL, "H5Dfill");
|
||||
|
||||
/* Now use the bad dataspace as the space for an attribute */
|
||||
H5E_BEGIN_TRY {
|
||||
aid1 = H5Acreate(dset1, BASICATTR,
|
||||
H5T_NATIVE_INT, sid1, H5P_DEFAULT);
|
||||
} H5E_END_TRY
|
||||
VERIFY(aid1, FAIL, "H5Acreate");
|
||||
|
||||
/* Make sure that dataspace reads using the bad dataspace fail */
|
||||
H5E_BEGIN_TRY {
|
||||
ret = H5Dread(dset1, H5T_NATIVE_INT, sid1, H5S_ALL, H5P_DEFAULT, &n);
|
||||
} H5E_END_TRY
|
||||
VERIFY(ret, FAIL, "H5Dread");
|
||||
|
||||
H5E_BEGIN_TRY {
|
||||
ret = H5Dread(dset1, H5T_NATIVE_INT, H5S_ALL, sid1, H5P_DEFAULT, &n);
|
||||
} H5E_END_TRY
|
||||
VERIFY(ret, FAIL, "H5Dread");
|
||||
|
||||
H5E_BEGIN_TRY {
|
||||
ret = H5Dread(dset1, H5T_NATIVE_INT, sid1, sid1, H5P_DEFAULT, &n);
|
||||
} H5E_END_TRY
|
||||
VERIFY(ret, FAIL, "H5Dread");
|
||||
|
||||
/* Clean up */
|
||||
ret = H5Dclose(dset1);
|
||||
CHECK(ret, FAIL, "H5Dclose");
|
||||
ret = H5Sclose(sid1);
|
||||
CHECK(ret, FAIL, "H5Sclose");
|
||||
ret = H5Sclose(sid2);
|
||||
CHECK(ret, FAIL, "H5Sclose");
|
||||
ret = H5Fclose(fid1);
|
||||
CHECK(ret, FAIL, "H5Fclose");
|
||||
} /* test_h5s_basic() */
|
||||
|
||||
/****************************************************************
|
||||
@ -345,7 +434,7 @@ test_h5s_null(void)
|
||||
/* Close the dataspace */
|
||||
ret = H5Sclose(sid);
|
||||
CHECK(ret, FAIL, "H5Sclose");
|
||||
|
||||
|
||||
/* Close the file */
|
||||
ret = H5Fclose(fid);
|
||||
CHECK(ret, FAIL, "H5Fclose");
|
||||
@ -435,7 +524,6 @@ test_h5s_null(void)
|
||||
static void
|
||||
test_h5s_encode(void)
|
||||
{
|
||||
hid_t fid1; /* HDF5 File IDs */
|
||||
hid_t sid1, sid2, sid3; /* Dataspace ID */
|
||||
hid_t decoded_sid1, decoded_sid2, decoded_sid3;
|
||||
int rank; /* Logical rank of dataspace */
|
||||
@ -443,7 +531,6 @@ test_h5s_encode(void)
|
||||
size_t sbuf_size=0, null_size=0, scalar_size=0;
|
||||
unsigned char *sbuf=NULL, *null_sbuf=NULL, *scalar_buf=NULL;
|
||||
hsize_t tdims[4]; /* Dimension array to test with */
|
||||
hsize_t tmax[4];
|
||||
hssize_t n; /* Number of dataspace elements */
|
||||
hssize_t start[] = {0, 0, 0};
|
||||
hsize_t stride[] = {2, 5, 3};
|
||||
@ -993,4 +1080,5 @@ void
|
||||
cleanup_h5s(void)
|
||||
{
|
||||
remove(DATAFILE);
|
||||
remove(BASICFILE);
|
||||
}
|
||||
|
@ -178,6 +178,7 @@ test_vltypes_vlen_atomic(void)
|
||||
hid_t fid1; /* HDF5 File IDs */
|
||||
hid_t dataset; /* Dataset ID */
|
||||
hid_t sid1; /* Dataspace ID */
|
||||
hid_t sid2; /* ID of bad dataspace (no extent set) */
|
||||
hid_t tid1; /* Datatype ID */
|
||||
hid_t dcpl_pid; /* Dataset creation property list ID */
|
||||
hid_t xfer_pid; /* Dataset transfer property list ID */
|
||||
@ -395,6 +396,10 @@ test_vltypes_vlen_atomic(void)
|
||||
tid1 = H5Dget_type(dataset);
|
||||
CHECK(tid1, FAIL, "H5Dget_type");
|
||||
|
||||
/* Create a "bad" dataspace with no extent set */
|
||||
sid2 = H5Screate(H5S_SIMPLE);
|
||||
CHECK(sid2, FAIL, "H5Screate");
|
||||
|
||||
/* Change to the custom memory allocation routines for reading VL data */
|
||||
xfer_pid=H5Pcreate(H5P_DATASET_XFER);
|
||||
CHECK(xfer_pid, FAIL, "H5Pcreate");
|
||||
@ -406,6 +411,12 @@ test_vltypes_vlen_atomic(void)
|
||||
ret=H5Dvlen_get_buf_size(dataset,tid1,sid1,&size);
|
||||
CHECK(ret, FAIL, "H5Dvlen_get_buf_size");
|
||||
|
||||
/* Try to call H5Dvlen_get_buf with bad dataspace */
|
||||
H5E_BEGIN_TRY {
|
||||
ret=H5Dvlen_get_buf_size(dataset,tid1,sid2,&size);
|
||||
} H5E_END_TRY
|
||||
VERIFY(ret, FAIL, "H5Dvlen_get_buf_size");
|
||||
|
||||
/* 10 elements allocated = 1 + 2 + 3 + 4 elements for each array position */
|
||||
VERIFY(size,((SPACE1_DIM1*(SPACE1_DIM1+1))/2)*sizeof(unsigned int),"H5Dvlen_get_buf_size");
|
||||
|
||||
@ -431,6 +442,13 @@ test_vltypes_vlen_atomic(void)
|
||||
} /* end for */
|
||||
} /* end for */
|
||||
|
||||
/* Try to reclaim read data using "bad" dataspace with no extent
|
||||
* Should fail */
|
||||
H5E_BEGIN_TRY {
|
||||
ret=H5Dvlen_reclaim(tid1,sid2,xfer_pid,rdata);
|
||||
} H5E_END_TRY
|
||||
VERIFY(ret, FAIL, "H5Dvlen_reclaim");
|
||||
|
||||
/* Reclaim the read VL data */
|
||||
ret=H5Dvlen_reclaim(tid1,sid1,xfer_pid,rdata);
|
||||
CHECK(ret, FAIL, "H5Dvlen_reclaim");
|
||||
|
Loading…
Reference in New Issue
Block a user