summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--release_docs/RELEASE.txt10
-rw-r--r--src/H5Aint.c4
-rw-r--r--test/tattr.c91
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);