From f7545efc76fdb4e3fb7e93b93f0e404a3a651081 Mon Sep 17 00:00:00 2001 From: Robb Matzke Date: Mon, 26 Oct 1998 14:55:54 -0500 Subject: [svn-r795] Changes since 19981026 ---------------------- ./MANIFEST ./test/th5s.h5 [NEW] ./test/th5s.c Added a test to make sure that creating a data space with too large a rank fails. Added a test to make sure that reading a file that has a dataset with a space with too large a rank fails. Actually, this one is a little weird: the code that reads the data space message assumes the space is scalar if the message cannot be read. Fortunately the layout message fails also, preventing the dataset from being opened. However, since the data type message is still visible h5ls will report that the object is a named data type. ./test/space_overflow.c [NEW] This is the little program that makes the th5s.h5 file. ./src/H5A.c ./src/H5R.c ./src/H5Sselect.c Updated trace info. ./src/H5Olayout.c ./src/H5Osdspace.c Added code to fail if the dimensionality is too large when decoding a layout or simple data space message. ./src/H5Oprivate.h Redefined H5O_LAYOUT_NDIMS in terms of H5S_MAX_RANK. ./src/H5P.c ./src/H5S.c Check for ndims>H5S_MAX_RANK in API function calls, added assert to internal functions. ./src/H5V.c Changed a `<' to an `<=' in an assert. ./test/flush2.c Includes stdlib.h for getenv(). ./tools/h5tools.c Able to handle up to H5S_MAX_RANK dimensions during output. --- MANIFEST | 2 ++ src/H5A.c | 2 +- src/H5Olayout.c | 5 +++++ src/H5Oprivate.h | 4 ++-- src/H5Osdspace.c | 31 ++++++++++++++++--------------- src/H5P.c | 2 +- src/H5R.c | 1 + src/H5S.c | 38 ++++++++++++++++++++++---------------- src/H5Spublic.h | 14 +++++++++----- src/H5Sselect.c | 2 +- src/H5V.c | 2 +- test/flush2.c | 1 + test/th5s.c | 31 ++++++++++++++++++++++++++++--- test/th5s.h5 | Bin 0 -> 1665 bytes tools/h5tools.c | 16 ++++++++-------- 15 files changed, 98 insertions(+), 53 deletions(-) create mode 100644 test/th5s.h5 diff --git a/MANIFEST b/MANIFEST index 2accca6..7e19354 100644 --- a/MANIFEST +++ b/MANIFEST @@ -307,11 +307,13 @@ ./test/overhead.c ./test/ragged.c ./test/shtype.c +./test/space_overflow.c _DO_NOT_DISTRIBUTE_ ./test/testhdf5.c ./test/testhdf5.h ./test/tattr.c ./test/tfile.c ./test/th5s.c +./test/th5s.h5 ./test/theap.c ./test/tmeta.c ./test/tohdr.c diff --git a/src/H5A.c b/src/H5A.c index ebbe5e7..d1ba5c8 100644 --- a/src/H5A.c +++ b/src/H5A.c @@ -1011,7 +1011,7 @@ H5Aget_name(hid_t attr_id, size_t buf_size, char *buf) hssize_t ret_value = FAIL; FUNC_ENTER(H5Aget_name, FAIL); - H5TRACE3("z","izs",attr_id,buf_size,buf); + H5TRACE3("Hs","izs",attr_id,buf_size,buf); /* check arguments */ if (H5I_ATTR != H5I_get_type(attr_id) || diff --git a/src/H5Olayout.c b/src/H5Olayout.c index f6ca222..ee37f3b 100644 --- a/src/H5Olayout.c +++ b/src/H5Olayout.c @@ -91,6 +91,11 @@ H5O_layout_decode(H5F_t *f, const uint8 *p, H5O_shared_t __unused__ *sh) /* Dimensionality */ mesg->ndims = *p++; + if (mesg->ndims>H5O_LAYOUT_NDIMS) { + H5MM_xfree(mesg); + HRETURN_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, + "dimensionality is too large"); + } /* Layout class */ mesg->type = *p++; diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index adc9396..7dff3c9 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -168,10 +168,10 @@ typedef struct H5O_efl_t { } H5O_efl_t; /* - * Data Layout Message + * Data Layout Message. */ #define H5O_LAYOUT_ID 0x0008 -#define H5O_LAYOUT_NDIMS 32 +#define H5O_LAYOUT_NDIMS (H5S_MAX_RANK+1) extern const H5O_class_t H5O_LAYOUT[1]; typedef struct H5O_layout_t { diff --git a/src/H5Osdspace.c b/src/H5Osdspace.c index d7727ef..adec06c 100644 --- a/src/H5Osdspace.c +++ b/src/H5Osdspace.c @@ -84,6 +84,7 @@ static void * H5O_sdspace_decode(H5F_t *f, const uint8 *p, H5O_shared_t __unused__ *sh) { H5S_simple_t *sdim = NULL;/* New simple dimensionality structure */ + void *ret_value = NULL; intn u; /* local counting variable */ uintn flags, version; @@ -98,18 +99,22 @@ H5O_sdspace_decode(H5F_t *f, const uint8 *p, H5O_shared_t __unused__ *sh) if ((sdim = H5MM_calloc(sizeof(H5S_simple_t))) != NULL) { version = *p++; if (version!=H5O_SDSPACE_VERSION) { - HRETURN_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, - "wrong version number in data space message"); + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, + "wrong version number in data space message"); } sdim->rank = *p++; + if (sdim->rank>H5S_MAX_RANK) { + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, + "simple data space dimensionality is too large"); + } flags = *p++; p += 5; /*reserved*/ if (sdim->rank > 0) { if (NULL==(sdim->size=H5MM_malloc(sizeof(sdim->size[0])* sdim->rank))) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, - "memory allocation failed"); + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed"); } for (u = 0; u < sdim->rank; u++) { H5F_decode_length (f, p, sdim->size[u]); @@ -117,8 +122,8 @@ H5O_sdspace_decode(H5F_t *f, const uint8 *p, H5O_shared_t __unused__ *sh) if (flags & H5S_VALID_MAX) { if (NULL==(sdim->max=H5MM_malloc(sizeof(sdim->max[0])* sdim->rank))) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, - "memory allocation failed"); + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed"); } for (u = 0; u < sdim->rank; u++) { H5F_decode_length (f, p, sdim->max[u]); @@ -128,8 +133,8 @@ H5O_sdspace_decode(H5F_t *f, const uint8 *p, H5O_shared_t __unused__ *sh) if (flags & H5S_VALID_PERM) { if (NULL==(sdim->perm=H5MM_malloc(sizeof(sdim->perm[0])* sdim->rank))) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, - "memory allocation failed"); + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed"); } for (u = 0; u < sdim->rank; u++) UINT32DECODE(p, sdim->perm[u]); @@ -137,15 +142,11 @@ H5O_sdspace_decode(H5F_t *f, const uint8 *p, H5O_shared_t __unused__ *sh) #endif } } + ret_value = (void*)sdim; /*success*/ -#ifdef LATER done: -#endif /* LATER */ - if (sdim == NULL) { /* Error condition cleanup */ - - } - /* Normal function cleanup */ - FUNC_LEAVE(sdim); + if (!ret_value) H5MM_xfree(sdim); + FUNC_LEAVE(ret_value); } /*-------------------------------------------------------------------------- diff --git a/src/H5P.c b/src/H5P.c index d9ee64f..7bb9211 100644 --- a/src/H5P.c +++ b/src/H5P.c @@ -1070,7 +1070,7 @@ H5Pset_chunk(hid_t plist_id, int ndims, const hsize_t dim[/*ndims*/]) HRETURN_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "chunk dimensionality must be positive"); } - if ((size_t)ndims > NELMTS(plist->chunk_size)) { + if (ndims > H5S_MAX_RANK) { HRETURN_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "chunk dimensionality is too large"); } diff --git a/src/H5R.c b/src/H5R.c index 5cf152b..23733b8 100644 --- a/src/H5R.c +++ b/src/H5R.c @@ -401,6 +401,7 @@ H5Rget_region(hid_t dset, H5R_type_t rtype, void *ref) hid_t ret_value = FAIL; FUNC_ENTER(H5Rget_region, FAIL); + H5TRACE3("i","iRtx",dset,rtype,ref); /* Check args */ if(ref==NULL) diff --git a/src/H5S.c b/src/H5S.c index 09bde19..1b9e369 100644 --- a/src/H5S.c +++ b/src/H5S.c @@ -940,7 +940,7 @@ H5S_get_simple_extent_ndims(const H5S_t *ds) */ int H5Sget_simple_extent_dims(hid_t space_id, hsize_t dims[]/*out*/, - hsize_t maxdims[]/*out*/) + hsize_t maxdims[]/*out*/) { H5S_t *ds = NULL; intn ret_value = 0; @@ -1047,7 +1047,7 @@ H5S_modify(H5G_entry_t *ent, const H5S_t *ds) switch (ds->extent.type) { case H5S_SCALAR: case H5S_SIMPLE: - if (H5O_modify(ent, H5O_SDSPACE, 0, 0, &(ds->extent.u.simple)) < 0) { + if (H5O_modify(ent, H5O_SDSPACE, 0, 0, &(ds->extent.u.simple))<0) { HRETURN_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't update simple data space message"); } @@ -1261,25 +1261,27 @@ H5Sis_simple(hid_t space_id) hid_t space_id; IN: Dataspace object to query intn rank; IN: # of dimensions for the dataspace const size_t *dims; IN: Size of each dimension for the dataspace - const size_t *max; IN: Maximum size of each dimension for the dataspace + const size_t *max; IN: Maximum size of each dimension for the + dataspace RETURNS SUCCEED/FAIL DESCRIPTION - This function sets the number and size of each dimension in the - dataspace. Setting RANK to a value of zero converts the dataspace to a - scalar dataspace. Dimensions are specified from slowest to fastest changing - in the DIMS array (i.e. 'C' order). Setting the size of a dimension in the - MAX array to zero indicates that the dimension is of unlimited size and - should be allowed to expand. If MAX is NULL, the dimensions in the DIMS - array are used as the maximum dimensions. Currently, only the first - dimension in the array (the slowest) may be unlimited in size. + This function sets the number and size of each dimension in the + dataspace. Setting RANK to a value of zero converts the dataspace to a + scalar dataspace. Dimensions are specified from slowest to fastest + changing in the DIMS array (i.e. 'C' order). Setting the size of a + dimension in the MAX array to zero indicates that the dimension is of + unlimited size and should be allowed to expand. If MAX is NULL, the + dimensions in the DIMS array are used as the maximum dimensions. + Currently, only the first dimension in the array (the slowest) may be + unlimited in size. --------------------------------------------------------------------------*/ herr_t H5Sset_extent_simple(hid_t space_id, int rank, const hsize_t dims[/*rank*/], const hsize_t max[/*rank*/]) { - H5S_t *space = NULL; /* dataspace to modify */ - intn u; /* local counting variable */ + H5S_t *space = NULL; /* dataspace to modify */ + intn u; /* local counting variable */ FUNC_ENTER(H5Sset_extent_simple, FAIL); H5TRACE4("e","iIs*[a1]h*[a1]h",space_id,rank,dims,max); @@ -1291,8 +1293,8 @@ H5Sset_extent_simple(hid_t space_id, int rank, const hsize_t dims[/*rank*/], if (rank > 0 && dims == NULL) { HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no dimensions specified"); } - if (rank<0) { - HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid rank"); + if (rank<0 || rank>H5S_MAX_RANK) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid rank"); } #ifdef OLD_WAY if (dims) { @@ -1353,7 +1355,7 @@ H5S_set_extent_simple (H5S_t *space, int rank, const hsize_t *dims, FUNC_ENTER(H5S_set_extent_simple, FAIL); /* Check args */ - assert(rank>=0); + assert(rank>=0 && rank<=H5S_MAX_RANK); assert(0==rank || dims); /* If there was a previous offset for the selection, release it */ @@ -1606,6 +1608,10 @@ H5Screate_simple(int rank, const hsize_t dims[/*rank*/], HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "dimensionality cannot be negative"); } + if (rank>H5S_MAX_RANK) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + "dimensionality is too large"); + } if (!dims && dims!=0) { HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no dimensions specified"); diff --git a/src/H5Spublic.h b/src/H5Spublic.h index 3b6f636..bdf339a 100644 --- a/src/H5Spublic.h +++ b/src/H5Spublic.h @@ -25,7 +25,6 @@ #define H5S_UNLIMITED ((hsize_t)(hssize_t)(-1)) /* Define user-level maximum number of dimensions */ -/* This is not used internally to the library, see H5O_LAYOUT_NDIMS for the internal constant */ #define H5S_MAX_RANK 31 /* Different types of dataspaces */ @@ -39,9 +38,13 @@ typedef enum H5S_class_t { /* Different ways of combining selections */ typedef enum H5S_seloper_t { H5S_SELECT_NOOP = -1, /* error */ - H5S_SELECT_SET = 0, /* Select "set" operation */ - H5S_SELECT_OR, /* Binary "or" operation (add new selection to existing selection) */ - H5S_SELECT_INVALID /* Invalid upper bound on selection operations */ + H5S_SELECT_SET = 0, /* Select "set" operation */ + H5S_SELECT_OR, /* Binary "or" operation (add new selection + * to existing selection) + */ + H5S_SELECT_INVALID /* Invalid upper bound on selection + * operations + */ } H5S_seloper_t; #ifdef __cplusplus @@ -58,7 +61,8 @@ hid_t H5Scopy (hid_t space_id); herr_t H5Sclose (hid_t space_id); hsize_t H5Sget_simple_extent_npoints (hid_t space_id); int H5Sget_simple_extent_ndims (hid_t space_id); -int H5Sget_simple_extent_dims (hid_t space_id, hsize_t dims[], hsize_t maxdims[]); +int H5Sget_simple_extent_dims (hid_t space_id, hsize_t dims[], + hsize_t maxdims[]); hbool_t H5Sis_simple (hid_t space_id); herr_t H5Sset_space (hid_t space_id, int rank, const hsize_t *dims); hssize_t H5Sget_select_npoints (hid_t spaceid); diff --git a/src/H5Sselect.c b/src/H5Sselect.c index 7bc4d19..f50cd03 100644 --- a/src/H5Sselect.c +++ b/src/H5Sselect.c @@ -726,7 +726,7 @@ H5Sget_select_npoints(hid_t spaceid) hssize_t ret_value=FAIL; /* return value */ FUNC_ENTER (H5Sget_select_npoints, 0); - H5TRACE1("h","i",spaceid); + H5TRACE1("Hs","i",spaceid); /* Check args */ if (H5I_DATASPACE != H5I_get_type(spaceid) || diff --git a/src/H5V.c b/src/H5V.c index b05b46c..b5703b1 100644 --- a/src/H5V.c +++ b/src/H5V.c @@ -159,7 +159,7 @@ H5V_hyper_stride(intn n, const hsize_t *size, FUNC_ENTER(H5V_hyper_stride, (HDabort(), 0)); - assert(n >= 0 && n < H5V_HYPER_NDIMS); + assert(n >= 0 && n <= H5V_HYPER_NDIMS); assert(size); assert(total_size); assert(stride); diff --git a/test/flush2.c b/test/flush2.c index a799619..6e24075 100644 --- a/test/flush2.c +++ b/test/flush2.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #ifndef HAVE_ATTRIBUTE diff --git a/test/th5s.c b/test/th5s.c index abb16cd..b53e9aa 100644 --- a/test/th5s.c +++ b/test/th5s.c @@ -85,10 +85,14 @@ test_h5s_basic(void) { hid_t fid1; /* HDF5 File IDs */ hid_t sid1, sid2; /* Dataspace ID */ + hid_t dset1; /* Dataset ID */ unsigned rank; /* Logical rank of dataspace */ hsize_t dims1[] = {SPACE1_DIM1, SPACE1_DIM2, SPACE1_DIM3}; - hsize_t dims2[] = {SPACE2_DIM1, SPACE2_DIM2, SPACE2_DIM3, SPACE2_DIM4}; - hsize_t max2[] = {SPACE2_MAX1, SPACE2_MAX2, SPACE2_MAX3, SPACE2_MAX4}; + hsize_t dims2[] = {SPACE2_DIM1, SPACE2_DIM2, SPACE2_DIM3, + SPACE2_DIM4}; + hsize_t dims3[H5S_MAX_RANK+1]; + hsize_t max2[] = {SPACE2_MAX1, SPACE2_MAX2, SPACE2_MAX3, + SPACE2_MAX4}; hsize_t tdims[4]; /* Dimension array to test with */ hsize_t tmax[4]; size_t n; /* Number of dataspace elements */ @@ -106,7 +110,8 @@ test_h5s_basic(void) n = H5Sget_simple_extent_npoints(sid1); CHECK(n, UFAIL, "H5Sget_simple_extent_npoints"); - VERIFY(n, SPACE1_DIM1 * SPACE1_DIM2 * SPACE1_DIM3, "H5Sget_simple_extent_npoints"); + VERIFY(n, SPACE1_DIM1 * SPACE1_DIM2 * SPACE1_DIM3, + "H5Sget_simple_extent_npoints"); rank = H5Sget_simple_extent_ndims(sid1); CHECK(rank, UFAIL, "H5Sget_simple_extent_ndims"); @@ -145,6 +150,26 @@ test_h5s_basic(void) /* Close first file */ ret = H5Fclose(fid1); CHECK(ret, FAIL, "H5Fclose"); + + /* + * Check to be sure we can't create a simple data space that has too many + * dimensions. + */ + H5E_BEGIN_TRY { + sid1 = H5Screate_simple(H5S_MAX_RANK+1, dims3, NULL); + } H5E_END_TRY; + VERIFY(sid1, FAIL, "H5Screate_simple"); + + /* + * Try reading a file that has been prepared that has a dataset with a + * higher dimensionality than what the library can handle. + */ + fid1 = H5Fopen("th5s.h5", H5F_ACC_RDONLY, H5P_DEFAULT); + CHECK_I(fid1, "H5Fopen(th5s.h5)"); + dset1 = H5Dopen(fid1, "dset"); + VERIFY(dset1, FAIL, "H5Dopen"); + ret = H5Fclose(fid1); + CHECK_I(ret, "H5Fclose"); } /* test_h5s_basic() */ /**************************************************************** diff --git a/test/th5s.h5 b/test/th5s.h5 new file mode 100644 index 0000000..452b3d4 Binary files /dev/null and b/test/th5s.h5 differ diff --git a/tools/h5tools.c b/tools/h5tools.c index b4411de..ced4e48 100644 --- a/tools/h5tools.c +++ b/tools/h5tools.c @@ -52,7 +52,7 @@ static void h5dump_prefix(char *s/*out*/, const h5dump_t *info, hsize_t elmtno, int ndims, hsize_t min_idx[], hsize_t max_idx[]) { - hsize_t p_prod[8], p_idx[8]; + hsize_t p_prod[H5S_MAX_RANK], p_idx[H5S_MAX_RANK]; hsize_t n, i; char temp[1024]; @@ -112,7 +112,7 @@ h5dump_prefix(char *s/*out*/, const h5dump_t *info, hsize_t elmtno, int ndims, static void h5dump_sprint(char *s/*out*/, const h5dump_t *info, hid_t type, void *vp) { - size_t i, n, offset, size, dims[4], nelmts; + size_t i, n, offset, size, dims[H5S_MAX_RANK], nelmts; unsigned overflow = 0xaaaaaaaa; char temp[8192]; char *name, quote='\0'; @@ -280,7 +280,7 @@ h5dump_sprint(char *s/*out*/, const h5dump_t *info, hid_t type, void *vp) memb = H5Tget_member_type(type, j); size = H5Tget_size(memb); ndims = H5Tget_member_dims(type, j, dims, NULL); - assert(ndims>=0 && ndims<=4); + assert(ndims>=0 && ndims<=H5S_MAX_RANK); for (k=0, nelmts=1; k1) strcat(temp, OPT(info->arr_pre, "[")); @@ -340,8 +340,8 @@ h5dump_simple(FILE *stream, const h5dump_t *info, hid_t dset, hid_t p_type) int need_prefix=1; /*indices need printing */ /* Print info */ - hsize_t p_min_idx[8]; /*min selected index */ - hsize_t p_max_idx[8]; /*max selected index */ + hsize_t p_min_idx[H5S_MAX_RANK];/*min selected index */ + hsize_t p_max_idx[H5S_MAX_RANK];/*max selected index */ size_t p_type_nbytes; /*size of memory type */ hsize_t p_nelmts; /*total selected elmts */ char p_buf[8192]; /*output string */ @@ -350,15 +350,15 @@ h5dump_simple(FILE *stream, const h5dump_t *info, hid_t dset, hid_t p_type) char p_prefix[1024]; /*line prefix string */ /* Stripmine info */ - hsize_t sm_size[8]; /*stripmine size */ + hsize_t sm_size[H5S_MAX_RANK]; /*stripmine size */ hsize_t sm_nbytes; /*bytes per stripmine */ hsize_t sm_nelmts; /*elements per stripmine*/ unsigned char *sm_buf; /*buffer for raw data */ hid_t sm_space; /*stripmine data space */ /* Hyperslab info */ - hssize_t hs_offset[8]; /*starting offset */ - hsize_t hs_size[8]; /*size this pass */ + hssize_t hs_offset[H5S_MAX_RANK];/*starting offset */ + hsize_t hs_size[H5S_MAX_RANK]; /*size this pass */ hsize_t hs_nelmts; /*elements in request */ /* -- cgit v0.12