[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)
This commit is contained in:
Quincey Koziol 2000-10-17 15:46:57 -05:00
parent bfd52032e3
commit 2011215517
3 changed files with 105 additions and 3 deletions

View File

@ -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

View File

@ -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) {

View File

@ -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"
@ -535,6 +536,100 @@ test_reference_region(void)
free(drbuf);
} /* test_reference_region() */
/****************************************************************
**
** 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);
}