From 0d2c4d0a59eedafb967a4921628319ac347ba634 Mon Sep 17 00:00:00 2001 From: Neil Fortner Date: Tue, 8 Nov 2022 08:45:34 -0600 Subject: Fix problem with variable length attributes being accessed through multiple file handles (merge to 1.8) (#2235) * Fix problem with variable length attributes being accessed through multiple file handle (merge to 1.8) * Fix problem with variable length attributes being accessed through multiple file handles (#2181) (#2207) * Fix bug in merge of vlen attr fix (#2181) from 1.12 * Committing clang-format changes * Add fix that was mistakenly left out of previous commit Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> --- release_docs/RELEASE.txt | 10 ++++++ src/H5Aint.c | 4 +++ test/tattr.c | 91 ++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 99 insertions(+), 6 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 3903513..db8d0d2 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -347,6 +347,16 @@ Bug Fixes since HDF5-1.8.22 Library ------- + - Fixed an issue with variable length attributes + + Previously, if a variable length attribute was held open while its file + was opened through another handle, the same attribute was opened through + the second file handle, and the second file and attribute handles were + closed, attempting to write to the attribute through the first handle + would cause an error. + + (NAF - 2022/10/24) + - Fixed an issue with attribute type conversion with compound datatypes Previously, when performing type conversion for attribute I/O with a diff --git a/src/H5Aint.c b/src/H5Aint.c index 74c48d6..694b17c 100644 --- a/src/H5Aint.c +++ b/src/H5Aint.c @@ -496,6 +496,10 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id) HDassert(mem_type); HDassert(buf); + /* Patch the top level file pointer in attr->shared->dt->shared->u.vlen.f if needed */ + if (H5T_patch_vlen_file(attr->shared->dt, attr->oloc.file) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "can't patch VL datatype file pointer") + /* Get # of elements for attribute's dataspace */ if ((snelmts = H5S_GET_EXTENT_NPOINTS(attr->shared->ds)) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "dataspace is invalid") diff --git a/test/tattr.c b/test/tattr.c index 73fab20..b215a07 100644 --- a/test/tattr.c +++ b/test/tattr.c @@ -10632,6 +10632,81 @@ test_attr_bug9(hid_t fcpl, hid_t fapl) /**************************************************************** ** +** test_attr_bug10(): Test basic H5A (attribute) code. +** Attempts to trigger a bug which would result in a +** segfault. Create a vlen attribute through a file +** handle, then open the same file through a different +** handle, open the same attribute through the second file +** handle, then close the second file and attribute +** handles, then write to the attribute through the first +** handle. +** +****************************************************************/ +static void +test_attr_bug10(hid_t fcpl, hid_t fapl) +{ + hid_t fid1, fid2; /* File IDs */ + hid_t aid1, aid2; /* Attribute IDs */ + hid_t sid; /* Dataspace ID */ + hid_t tid; /* Datatype ID */ + hsize_t dims[1] = {1}; /* Attribute dimensions */ + const char *wbuf[1] = {"foo"}; /* Write buffer */ + herr_t ret; /* Generic return status */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing that vlen attributes can be written to after a second file handle is closed\n")); + + /* Create dataspace */ + sid = H5Screate_simple(1, dims, NULL); + CHECK(sid, FAIL, "H5Screate_simple"); + + /* Create VL string datatype */ + tid = H5Tcopy(H5T_C_S1); + CHECK(tid, FAIL, "H5Tcreate"); + ret = H5Tset_size(tid, H5T_VARIABLE); + CHECK(ret, FAIL, "H5Tset_size"); + + /* Create file */ + fid1 = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl); + CHECK(fid1, FAIL, "H5Fcreate"); + + /* Create attribute on root group */ + aid1 = H5Acreate2(fid1, "attr", tid, sid, H5P_DEFAULT, H5P_DEFAULT); + CHECK(aid1, FAIL, "H5Acreate2"); + + /* Open the same file again */ + fid2 = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl); + CHECK(fid2, FAIL, "H5Fcreate"); + + /* Open the same attribute through the second file handle */ + aid2 = H5Aopen(fid2, "attr", H5P_DEFAULT); + CHECK(aid2, FAIL, "H5Aopen"); + + /* Close the second attribute and file handles */ + ret = H5Aclose(aid2); + CHECK(ret, FAIL, "H5Aclose"); + ret = H5Fclose(fid2); + CHECK(ret, FAIL, "H5Fclose"); + + /* Write to the attribute through the first handle */ + ret = H5Awrite(aid1, tid, wbuf); + + /* Close IDs */ + ret = H5Aclose(aid1); + CHECK(ret, FAIL, "H5Aclose"); + + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + ret = H5Tclose(tid); + CHECK(ret, FAIL, "H5Tclose"); + + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); +} /* test_attr_bug10() */ + +/**************************************************************** +** ** test_attr(): Main H5A (attribute) testing routine. ** ****************************************************************/ @@ -10799,9 +10874,11 @@ test_attr(void) my_fapl); /* Test creating and deleting large attributes in ohdr chunk 0 */ test_attr_bug8(my_fcpl, my_fapl); /* Test attribute expanding object header with undecoded messages */ - test_attr_bug9(my_fcpl, my_fapl); /* Test large attributes converting to dense storage */ - } /* end for */ - } /* end if */ + test_attr_bug9(my_fcpl, my_fapl); /* Test large attributes converting to dense storage */ + test_attr_bug10(my_fcpl, my_fapl); /* Test writing an attribute after opening and closing + through a different file handle */ + } /* end for */ + } /* end if */ else { /* General attribute tests */ test_attr_big(fcpl, my_fapl); /* Test storing big attribute */ @@ -10830,9 +10907,11 @@ test_attr(void) * to the attributes being larger than 64K */ test_attr_bug8(fcpl, my_fapl); /* Test attribute expanding object header with undecoded messages */ - test_attr_bug9(fcpl, my_fapl); /* Test large attributes converting to dense storage */ - } /* end else */ - } /* end for */ + test_attr_bug9(fcpl, my_fapl); /* Test large attributes converting to dense storage */ + test_attr_bug10(fcpl, my_fapl); /* Test writing an attribute after opening and closing + through a different file handle */ + } /* end else */ + } /* end for */ /* Close FCPLs */ ret = H5Pclose(fcpl); -- cgit v0.12