From 2011215517e50ae231f89c9d24ce826d76315e00 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 17 Oct 2000 15:46:57 -0500 Subject: [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) --- RELEASE | 6 ++-- src/H5R.c | 4 +++ test/trefer.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 105 insertions(+), 3 deletions(-) diff --git a/RELEASE b/RELEASE index d505fd2..339f531 100644 --- a/RELEASE +++ b/RELEASE @@ -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 diff --git a/src/H5R.c b/src/H5R.c index b9240bd..ec821ab 100644 --- a/src/H5R.c +++ b/src/H5R.c @@ -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); } -- cgit v0.12