diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2000-10-17 20:46:57 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2000-10-17 20:46:57 (GMT) |
commit | 2011215517e50ae231f89c9d24ce826d76315e00 (patch) | |
tree | 1a1f842218cb64d9cf21eaee26437c64676ad213 | |
parent | bfd52032e36f265c3a2829595a29f480903e9b30 (diff) | |
download | hdf5-2011215517e50ae231f89c9d24ce826d76315e00.zip hdf5-2011215517e50ae231f89c9d24ce826d76315e00.tar.gz hdf5-2011215517e50ae231f89c9d24ce826d76315e00.tar.bz2 |
[svn-r2689] Purpose:
Bug fix.
Description:
Previously, it has been possible to dereference deleted objects in a file.
Obviously, this is incorrect and could cause all sorts of problems if the
object being dereferenced had been partially over-written with other
information. - This is documented in Bug #493.
Solution:
Check the link count for objects being dereferenced and don't allow any
objects with link counts of zero to be dereferenced.
This fixes bug #493.
Platforms tested:
FreeBSD 4.1.1 (hawkwind)
-rw-r--r-- | RELEASE | 6 | ||||
-rw-r--r-- | src/H5R.c | 4 | ||||
-rw-r--r-- | test/trefer.c | 98 |
3 files changed, 105 insertions, 3 deletions
@@ -46,6 +46,8 @@ New features all VFL drivers except the mpio & core drivers. Setting the sieve buffer size is controlled with new API functions: H5Pset_sieve_buf_size() and retrieved with H5Pget_sieve_buf_size(). + * Added new Virtual File Driver, Stream VFD, to send/receive entire + HDF5 files via socket connections. Bug fixes since HDF5-1.2.0 ========================== @@ -86,8 +88,8 @@ Library * Added bounded garbage collection for the free lists when they run out of memory and also added H5set_free_list_limits API call to allow users to put an upper limit on the amount of memory used for free lists. - * Added new Virtual File Driver, Stream VFD, to send/receive entire - HDF5 files via socket connections. + * Checked for non-existent or deleted objects when dereferencing one with + object or region references and disallow dereference. Configuration @@ -409,6 +409,10 @@ H5R_dereference(H5F_t *file, H5R_type_t ref_type, void *_ref) "internal error (unknown reference type)"); } /* end switch */ + /* Check to make certain that this object hasn't been deleted since the reference was created */ + if(H5O_link(&ent,0)<=0) + HRETURN_ERROR(H5E_REFERENCE, H5E_LINKCOUNT, FAIL, "dereferencing deleted object"); + /* Open the dataset object */ oid_type=H5G_get_type(&ent); switch(oid_type) { diff --git a/test/trefer.c b/test/trefer.c index 6715bd6..24f4bdf 100644 --- a/test/trefer.c +++ b/test/trefer.c @@ -30,6 +30,7 @@ static char RcsId[] = "$Revision$"; #define FILE1 "trefer1.h5" #define FILE2 "trefer2.h5" +#define FILE3 "trefer3.h5" /* 1-D dataset with fixed dimensions */ #define SPACE1_NAME "Space1" @@ -537,6 +538,100 @@ test_reference_region(void) /**************************************************************** ** +** test_reference_obj_deleted(): Test H5R (reference) object reference code. +** Tests for correct failures for deleted and non-existent objects +** +****************************************************************/ +static void +test_reference_obj_deleted(void) +{ + hid_t fid1; /* HDF5 File IDs */ + hid_t dataset, /* Dataset ID */ + dset2; /* Dereferenced dataset ID */ + hid_t sid1; /* Dataspace ID */ + hobj_ref_t oref; /* Object Reference to test */ + herr_t ret; /* Generic return value */ + + /* Create file */ + fid1 = H5Fcreate(FILE3, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid1, FAIL, "H5Fcreate"); + + /* Create scalar dataspace for datasets */ + sid1 = H5Screate_simple(0, NULL, NULL); + CHECK(sid1, FAIL, "H5Screate_simple"); + + /* Create a dataset to reference (deleted later) */ + dataset=H5Dcreate(fid1,"Dataset1",H5T_NATIVE_INT,sid1,H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create a dataset */ + dataset=H5Dcreate(fid1,"Dataset2",H5T_STD_REF_OBJ,sid1,H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate"); + + /* Create reference to dataset */ + ret = H5Rcreate(&oref,fid1,"/Dataset1",H5R_OBJECT,-1); + CHECK(ret, FAIL, "H5Rcreate"); + ret = H5Rget_object_type(dataset,&oref); + VERIFY(ret, H5G_DATASET, "H5Rget_object_type"); + + /* Write selection to disk */ + ret=H5Dwrite(dataset,H5T_STD_REF_OBJ,H5S_ALL,H5S_ALL,H5P_DEFAULT,&oref); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Delete referenced dataset */ + ret = H5Gunlink(fid1,"/Dataset1"); + CHECK(ret, FAIL, "H5Gunlink"); + + /* Close disk dataspace */ + ret = H5Sclose(sid1); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + /* Re-open the file */ + fid1 = H5Fopen(FILE3, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK(fid1, FAIL, "H5Fopen"); + + /* Open the dataset */ + dataset=H5Dopen(fid1,"/Dataset2"); + CHECK(ret, FAIL, "H5Dcreate"); + + /* Read selection from disk */ + memset(&oref,0,sizeof(hobj_ref_t)); + ret=H5Dread(dataset,H5T_STD_REF_OBJ,H5S_ALL,H5S_ALL,H5P_DEFAULT,&oref); + CHECK(ret, FAIL, "H5Dread"); + + /* Open deleted dataset object */ + dset2 = H5Rdereference(dataset,H5R_OBJECT,&oref); + VERIFY(dset2, FAIL, "H5Rdereference"); + + /* Open nonsense reference */ + memset(&oref,0,sizeof(hobj_ref_t)); + dset2 = H5Rdereference(dataset,H5R_OBJECT,&oref); + VERIFY(dset2, FAIL, "H5Rdereference"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + +} /* test_reference_obj_deleted() */ + +/**************************************************************** +** ** test_reference(): Main H5R reference testing routine. ** ****************************************************************/ @@ -546,9 +641,9 @@ test_reference(void) /* Output message about test being performed */ MESSAGE(5, ("Testing References\n")); - /* These next tests use the same file */ test_reference_obj(); /* Test basic H5R object reference code */ test_reference_region(); /* Test basic H5R dataset region reference code */ + test_reference_obj_deleted(); /* Test H5R object reference code for deleted objects */ } /* test_reference() */ @@ -572,5 +667,6 @@ cleanup_reference(void) { remove(FILE1); remove(FILE2); + remove(FILE3); } |