diff options
author | mattjala <124107509+mattjala@users.noreply.github.com> | 2023-11-22 13:55:25 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-22 13:55:25 (GMT) |
commit | af4c6c4f1579802f00fa5ef24c35ce4086d78591 (patch) | |
tree | 6d8e64407f9285479caae7f60e343787691a0d00 /test/dtypes.c | |
parent | 3ea21ccb3e84dae935c32faff5d10ce9672a3265 (diff) | |
download | hdf5-af4c6c4f1579802f00fa5ef24c35ce4086d78591.zip hdf5-af4c6c4f1579802f00fa5ef24c35ce4086d78591.tar.gz hdf5-af4c6c4f1579802f00fa5ef24c35ce4086d78591.tar.bz2 |
Fix segfault on user compound dtype conversion callback (#3842)
* Fix segfault on user compound conversion
* Check if lib conversion func is in use
Diffstat (limited to 'test/dtypes.c')
-rw-r--r-- | test/dtypes.c | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/test/dtypes.c b/test/dtypes.c index a8def07..cbc031b 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -100,6 +100,15 @@ typedef enum dtype_t { OTHER } dtype_t; /* This doesn't seem to be used anywhere... -BMR */ +typedef struct src_cmpd_t { + uint32_t a; + float b; +} src_cmpd_t; + +typedef struct dst_cmpd_t { + float b; +} dst_cmpd_t; + typedef enum { E1_RED, E1_GREEN, E1_BLUE, E1_ORANGE, E1_YELLOW } color_t; /* Constant for size of conversion buffer for int <-> float exception test */ @@ -160,6 +169,28 @@ reset_hdf5(void) #endif } +/* Conversion function to test user compound conversion functions */ +static herr_t +user_compound_convert(hid_t H5_ATTR_UNUSED src_id, hid_t H5_ATTR_UNUSED dst_id, H5T_cdata_t *cdata, + size_t nelmts, size_t H5_ATTR_UNUSED buf_stride, size_t H5_ATTR_UNUSED bkg_stride, + void *buf, void H5_ATTR_UNUSED *bkg, hid_t H5_ATTR_UNUSED dxpl) +{ + herr_t retval = EXIT_SUCCESS; + switch (cdata->command) { + case H5T_CONV_INIT: + break; + case H5T_CONV_CONV: + for (size_t i = 0; i < nelmts; ++i) + ((dst_cmpd_t *)buf)[i].b = ((src_cmpd_t *)buf)[i].b; + break; + case H5T_CONV_FREE: + break; + default: + break; + } + return retval; +} + /*------------------------------------------------------------------------- * Function: test_classes * @@ -3789,6 +3820,99 @@ error: } /* end test_compound_18() */ /*------------------------------------------------------------------------- + * Function: test_user_compound_conversion + * + * Purpose: Tests that library correctly handles a user-defined + * conversion function between two compound types. + * + * Return: Success: 0 + * Failure: number of errors + * + *------------------------------------------------------------------------- + */ +static int +test_user_compound_conversion(void) +{ + hid_t file_id = H5I_INVALID_HID; + hid_t dset_id = H5I_INVALID_HID; + hid_t src = H5I_INVALID_HID, dst = H5I_INVALID_HID; + hid_t space_id = H5I_INVALID_HID; + struct src_cmpd_t buf[] = {{1, 1.0}}; + + hsize_t dim = 1; + char filename[1024]; + + TESTING("compound conversion via user conversion callback"); + + /* Create the source compound datatype */ + if ((src = H5Tcreate(H5T_COMPOUND, sizeof(struct src_cmpd_t))) < 0) + TEST_ERROR; + + if (H5Tinsert(src, "a", HOFFSET(struct src_cmpd_t, a), H5T_NATIVE_UINT32) < 0) + TEST_ERROR; + + if (H5Tinsert(src, "b", HOFFSET(struct src_cmpd_t, b), H5T_NATIVE_FLOAT) < 0) + TEST_ERROR; + + /* Create the destination compound datatype */ + if ((dst = H5Tcreate(H5T_COMPOUND, sizeof(struct dst_cmpd_t))) < 0) + TEST_ERROR; + + if (H5Tinsert(dst, "b", HOFFSET(struct dst_cmpd_t, b), H5T_IEEE_F32LE) < 0) + TEST_ERROR; + + if (H5Tregister(H5T_PERS_SOFT, "src_cmpd_t->dst_cmpd_t", src, dst, &user_compound_convert) < 0) + TEST_ERROR; + + /* Create File */ + h5_fixname(FILENAME[0], H5P_DEFAULT, filename, sizeof filename); + if ((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR; + + /* Create a dataspace to use */ + if ((space_id = H5Screate_simple(1, &dim, NULL)) < 0) + TEST_ERROR; + + /* Create a dataset with the destination compound datatype */ + if ((dset_id = H5Dcreate2(file_id, "dataset", dst, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR; + + if (H5Dwrite(dset_id, src, space_id, H5S_ALL, H5P_DEFAULT, buf) < 0) + TEST_ERROR; + + /* Close IDs */ + if (H5Tunregister(H5T_PERS_SOFT, "src_cmpd_t->dst_cmpd_t", src, dst, &user_compound_convert) < 0) + TEST_ERROR; + if (H5Tclose(src) < 0) + TEST_ERROR; + if (H5Tclose(dst) < 0) + TEST_ERROR; + if (H5Sclose(space_id) < 0) + TEST_ERROR; + if (H5Dclose(dset_id) < 0) + TEST_ERROR; + if (H5Fclose(file_id) < 0) + TEST_ERROR; + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY + { + H5Tunregister(H5T_PERS_SOFT, "src_cmpd_t->dst_cmpd_t", src, dst, &user_compound_convert); + H5Tclose(src); + H5Tclose(dst); + H5Sclose(space_id); + H5Dclose(dset_id); + H5Fclose(file_id); + } + H5E_END_TRY; + + return 1; +} /* end test_user_compound_conversion() */ + +/*------------------------------------------------------------------------- * Function: test_query * * Purpose: Tests query functions of compound and enumeration types. @@ -8786,6 +8910,7 @@ main(void) nerrors += test_compound_16(); nerrors += test_compound_17(); nerrors += test_compound_18(); + nerrors += test_user_compound_conversion(); nerrors += test_conv_enum_1(); nerrors += test_conv_enum_2(); nerrors += test_conv_bitfield(); |