diff options
-rw-r--r-- | release_docs/RELEASE.txt | 3 | ||||
-rw-r--r-- | src/H5D.c | 19 | ||||
-rw-r--r-- | src/H5T.c | 64 | ||||
-rw-r--r-- | src/H5Tprivate.h | 1 | ||||
-rw-r--r-- | test/Makefile.in | 2 | ||||
-rw-r--r-- | test/tmisc.c | 111 |
6 files changed, 188 insertions, 12 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 9a6d09f..be279a8 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -35,6 +35,9 @@ Bug Fixes since HDF5-1.4.0 Library ------- + * Fixed bug (#499) which allowed an "empty" compound or enumerated datatype + (one with no members) to be used to create a dataset or committed to a + file. QAK - 2002/06/11 * Fixed bug (#777) which allowed a compound datatype to be inserted into itself. QAK - 2002/06/10 * Fixed bug (#789) where creating 1-D dataset region reference caused the @@ -1559,20 +1559,25 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type, if(NULL == (new_dset = H5D_new(dcpl_id))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - /* Get new dataset's property list object */ - if (NULL == (new_plist = H5I_object(new_dset->dcpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "can't get dataset creation property list"); + /* Check if the datatype is "sensible" for use in a dataset */ + if(H5T_is_sensible(type)!=TRUE) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "datatype is not sensible"); - if(H5P_get(new_plist, H5D_CRT_CHUNK_DIM_NAME, &chunk_ndims) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve layout"); - /* Copy datatype for dataset */ - new_dset->type = H5T_copy(type, H5T_COPY_ALL); + if((new_dset->type = H5T_copy(type, H5T_COPY_ALL))==NULL) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy datatype"); /* Mark any VL datatypes as being on disk now */ if (H5T_vlen_mark(new_dset->type, f, H5T_VLEN_DISK)<0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid VL location"); + /* Get new dataset's property list object */ + if (NULL == (new_plist = H5I_object(new_dset->dcpl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "can't get dataset creation property list"); + + if(H5P_get(new_plist, H5D_CRT_CHUNK_DIM_NAME, &chunk_ndims) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve layout"); + if(H5P_get(new_plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve external file list"); @@ -5851,14 +5851,15 @@ H5T_commit (H5G_entry_t *loc, const char *name, H5T_t *type) FUNC_ENTER_NOAPI(H5T_commit, FAIL); + assert (loc); + assert (name && *name); + assert (type); + /* * Check arguments. We cannot commit an immutable type because H5Tclose() * normally fails on such types (try H5Tclose(H5T_NATIVE_INT)) but closing * a named type should always succeed. */ - assert (loc); - assert (name && *name); - assert (type); if (H5T_STATE_NAMED==type->state || H5T_STATE_OPEN==type->state) { HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "data type is already committed"); @@ -5868,6 +5869,10 @@ H5T_commit (H5G_entry_t *loc, const char *name, H5T_t *type) "data type is immutable"); } + /* Check for a "sensible" datatype to store on disk */ + if(H5T_is_sensible(type)!=TRUE) + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "datatype is not sensible"); + /* Find the insertion file */ if (NULL==(file=H5G_insertion_file(loc, name))) { HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, @@ -8089,6 +8094,59 @@ H5Tget_array_dims(hid_t type_id, hsize_t dims[], int perm[]) /*------------------------------------------------------------------------- + * Function: H5T_is_sensible + * + * Purpose: Determines if a data type is sensible to store on disk + * (i.e. not partially initialized) + * + * Return: Success: TRUE, FALSE + * + * Failure: Negative + * + * Programmer: Quincey Koziol + * Tuesday, June 11, 2002 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +htri_t +H5T_is_sensible(const H5T_t *dt) +{ + htri_t ret_value = FAIL; + + FUNC_ENTER_NOAPI(H5T_is_sensible, FAIL); + + assert(dt); + + switch(dt->type) { + case H5T_COMPOUND: + /* Only allow compound datatypes with at least one member to be stored on disk */ + if(dt->u.compnd.nmembs > 0) + ret_value=TRUE; + else + ret_value=FALSE; + break; + + case H5T_ENUM: + /* Only allow enum datatypes with at least one member to be stored on disk */ + if(dt->u.enumer.nmembs > 0) + ret_value=TRUE; + else + ret_value=FALSE; + break; + + default: + /* Assume all other datatype are sensible to store on disk */ + ret_value=TRUE; + break; + } /* end switch */ + + FUNC_LEAVE(ret_value); +} + + +/*------------------------------------------------------------------------- * Function: H5T_print_stats * * Purpose: Print statistics about a conversion path. Statistics are diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h index 23cd9a3..2381b5d 100644 --- a/src/H5Tprivate.h +++ b/src/H5Tprivate.h @@ -133,6 +133,7 @@ __DLL__ herr_t H5T_enum_valueof(H5T_t *dt, const char *name, void *value/*out*/); __DLL__ herr_t H5T_vlen_reclaim(void *elem, hid_t type_id, hsize_t ndim, hssize_t *point, void *_op_data); __DLL__ htri_t H5T_vlen_mark(H5T_t *dt, H5F_t *f, H5T_vlen_loc_t loc); +__DLL__ htri_t H5T_is_sensible(const H5T_t *dt); /* Reference specific functions */ __DLL__ H5R_type_t H5T_get_ref_type(const H5T_t *dt); diff --git a/test/Makefile.in b/test/Makefile.in index a066969..e1e0d73 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -48,7 +48,7 @@ MOSTLYCLEAN=cmpd_dset.h5 dataset.h5 extend.h5 istore.h5 tfile1.h5 tfile2.h5 \ mount_[0-9].h5 testmeta.h5 ttime.h5 trefer[12].h5 tvltypes.h5 \ tvlstr.h5 flush.h5 enum1.h5 titerate.h5 ttsafe.h5 tarray1.h5 \ tgenprop.h5 tmisc.h5 tmisc2a.h5 tmisc2b.h5 tmisc3.h5 tmisc4a.h5 \ - tmisc4b.h5 tmisc5.h5 tmisc6.h5 set_extent_read.h5 \ + tmisc4b.h5 tmisc5.h5 tmisc6.h5 tmisc7.h5 set_extent_read.h5 \ set_extent_create.h5 CLEAN=$(TIMINGS) diff --git a/test/tmisc.c b/test/tmisc.c index 6b3caac..0d2ffcd 100644 --- a/test/tmisc.c +++ b/test/tmisc.c @@ -112,6 +112,13 @@ typedef struct #define MISC6_DSETNAME2 "dset2" #define MISC6_NUMATTR 16 +/* Definitions for misc. test #7 */ +#define MISC7_FILE "tmisc7.h5" +#define MISC7_DSETNAME1 "Dataset1" +#define MISC7_DSETNAME2 "Dataset2" +#define MISC7_TYPENAME1 "Datatype1" +#define MISC7_TYPENAME2 "Datatype2" + /**************************************************************** ** ** test_misc1(): test unlinking a dataset from a group and immediately @@ -905,6 +912,106 @@ test_misc6(void) /**************************************************************** ** +** test_misc7(): Test that datatypes are sensible to store on +** disk. (i.e. not partially initialized) +** +****************************************************************/ +static void +test_misc7(void) +{ + hid_t fid, did, tid, sid; + int enum_value=1; + herr_t ret; + + /* Output message about test being performed */ + MESSAGE(5, ("Testing sensible datatype on disk code \n")); + + /* Attempt to commit a non-sensible datatype */ + + /* Create the file */ + fid=H5Fcreate(MISC7_FILE,H5F_ACC_TRUNC,H5P_DEFAULT,H5P_DEFAULT); + CHECK(fid,FAIL,"H5Fcreate"); + + /* Create the dataspace */ + sid=H5Screate(H5S_SCALAR); + CHECK(sid,FAIL,"H5Screate"); + + /* Create the compound datatype to commit*/ + tid=H5Tcreate(H5T_COMPOUND,32); + CHECK(tid,FAIL,"H5Tcreate"); + + /* Attempt to commit an empty compound datatype */ + ret=H5Tcommit(fid,MISC7_TYPENAME1,tid); + VERIFY(ret,FAIL,"H5Tcommit"); + + /* Attempt to use empty compound datatype to create dataset */ + did=H5Dcreate(fid,MISC7_DSETNAME1,tid,sid,H5P_DEFAULT); + VERIFY(ret,FAIL,"H5Dcreate"); + + /* Add a field to the compound datatype */ + ret=H5Tinsert(tid,"a",0,H5T_NATIVE_INT); + CHECK(ret,FAIL,"H5Tinsert"); + + /* Attempt to commit the compound datatype now - should work */ + ret=H5Tcommit(fid,MISC7_TYPENAME1,tid); + CHECK(ret,FAIL,"H5Tcommit"); + + /* Attempt to use compound datatype to create dataset now - should work */ + did=H5Dcreate(fid,MISC7_DSETNAME1,tid,sid,H5P_DEFAULT); + CHECK(did,FAIL,"H5Dcreate"); + + /* Close dataset */ + ret=H5Dclose(did); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close compound datatype */ + ret=H5Tclose(tid); + CHECK(ret, FAIL, "H5Tclose"); + + /* Create the enum datatype to commit*/ + tid=H5Tenum_create(H5T_NATIVE_INT); + CHECK(tid,FAIL,"H5Tenum_create"); + + /* Attempt to commit an empty enum datatype */ + ret=H5Tcommit(fid,MISC7_TYPENAME2,tid); + VERIFY(ret,FAIL,"H5Tcommit"); + + /* Attempt to use empty enum datatype to create dataset */ + did=H5Dcreate(fid,MISC7_DSETNAME2,tid,sid,H5P_DEFAULT); + VERIFY(did,FAIL,"H5Dcreate"); + + /* Add a member to the enum datatype */ + ret=H5Tenum_insert(tid,"a",&enum_value); + CHECK(ret,FAIL,"H5Tenum_insert"); + + /* Attempt to commit the enum datatype now - should work */ + ret=H5Tcommit(fid,MISC7_TYPENAME2,tid); + CHECK(ret,FAIL,"H5Tcommit"); + + /* Attempt to use enum datatype to create dataset now - should work */ + did=H5Dcreate(fid,MISC7_DSETNAME2,tid,sid,H5P_DEFAULT); + CHECK(did,FAIL,"H5Dcreate"); + + /* Close dataset */ + ret=H5Dclose(did); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close enum datatype */ + ret=H5Tclose(tid); + CHECK(ret, FAIL, "H5Tclose"); + + /* Close dataspace */ + ret=H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close file */ + ret=H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + +} /* end test_misc7() */ + +/**************************************************************** +** ** test_misc(): Main misc. test routine. ** ****************************************************************/ @@ -919,7 +1026,8 @@ test_misc(void) test_misc3(); /* Test reading from chunked dataset with non-zero fill value */ test_misc4(); /* Test retrieving the fileno for various objects with H5Gget_objinfo() */ test_misc5(); /* Test several level deep nested compound & VL datatypes */ - test_misc6(); /* Test object header continuation code */ + test_misc6(); /* Test object header continuation code */ + test_misc7(); /* Test for sensible datatypes stored on disk */ } /* test_misc() */ @@ -949,4 +1057,5 @@ cleanup_misc(void) remove(MISC4_FILE_2); remove(MISC5_FILE); remove(MISC6_FILE); + remove(MISC7_FILE); } |