diff options
-rw-r--r-- | MANIFEST | 2 | ||||
-rw-r--r-- | src/H5A.c | 2 | ||||
-rw-r--r-- | src/H5Olayout.c | 5 | ||||
-rw-r--r-- | src/H5Oprivate.h | 4 | ||||
-rw-r--r-- | src/H5Osdspace.c | 31 | ||||
-rw-r--r-- | src/H5P.c | 2 | ||||
-rw-r--r-- | src/H5R.c | 1 | ||||
-rw-r--r-- | src/H5S.c | 38 | ||||
-rw-r--r-- | src/H5Spublic.h | 14 | ||||
-rw-r--r-- | src/H5Sselect.c | 2 | ||||
-rw-r--r-- | src/H5V.c | 2 | ||||
-rw-r--r-- | test/flush2.c | 1 | ||||
-rw-r--r-- | test/th5s.c | 31 | ||||
-rw-r--r-- | test/th5s.h5 | bin | 0 -> 1665 bytes | |||
-rw-r--r-- | tools/h5tools.c | 16 |
15 files changed, 98 insertions, 53 deletions
@@ -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 @@ -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); } /*-------------------------------------------------------------------------- @@ -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"); } @@ -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) @@ -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) || @@ -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 <hdf5.h> #include <math.h> #include <stdio.h> +#include <stdlib.h> #include <H5config.h> #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 Binary files differnew file mode 100644 index 0000000..452b3d4 --- /dev/null +++ b/test/th5s.h5 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; k<ndims; k++) nelmts *= dims[k]; if (nelmts>1) 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 */ /* |