Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions HDF5Examples/C/H5G/h5ex_g_compact.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,17 @@ main(void)
H5G_info_t ginfo;
hsize_t size;

/*
* Set file access property list to use the earliest file format.
* This will force the library to create original format groups.
*/
fapl = H5Pcreate(H5P_FILE_ACCESS);
status = H5Pset_libver_bounds(fapl, H5F_LIBVER_EARLIEST, H5F_LIBVER_LATEST);

/*
* Create file 1. This file will use original format groups.
*/
file = H5Fcreate(FILENAME1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
file = H5Fcreate(FILENAME1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl);
group = H5Gcreate(file, GROUP, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);

/*
Expand Down Expand Up @@ -72,16 +79,16 @@ main(void)
status = H5Fclose(file);

/*
* Set file access property list to allow the latest file format.
* This will allow the library to create new compact format groups.
* Now use the default file access property list to allow the latest file
* format. This will allow the library to create new compact format groups.
* Since HDF5 2.0, the default is to use the 1.8 file format as the low
* bound, which includes compact groups.
*/
fapl = H5Pcreate(H5P_FILE_ACCESS);
status = H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST);

/*
* Create file 2 using the new file access property list.
* Create file 2 using the default access property list.
*/
file = H5Fcreate(FILENAME2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl);
file = H5Fcreate(FILENAME2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
group = H5Gcreate(file, GROUP, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);

/*
Expand Down
8 changes: 5 additions & 3 deletions c++/test/tfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ test_file_create()
H5File *file1 = NULL;
try {
// Create file FILE1
file1 = new H5File(FILE1, H5F_ACC_EXCL);
file1 = new H5File(FILE1, H5F_ACC_TRUNC);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the change in file access mode here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test is creating a new file. H5F_ACC_EXCL causes it to fail if the file already exists, which is what was happening. It was failing silently before, but with the 1.8 format it causes issues due to a fapl mismatch - see #5954

Copy link
Collaborator

@jhendersonHDF jhendersonHDF Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Fine either way, though previously the issues with this test involved the fact that it left a file open unintentionally and also forgot to delete it, so I wonder if that isn't the case here as well.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is at least partly due to it simply using HDremove() to remove the test files, which obviously doesn't work with the family file driver. Something that should be fixed for sure, but not within the scope of this PR


// Try to create the same file with H5F_ACC_TRUNC. This should fail
// because file1 is the same file and is currently open.
Expand Down Expand Up @@ -847,8 +847,10 @@ test_file_info()
H5F_fspace_strategy_t out_strategy = H5F_FSPACE_STRATEGY_FSM_AGGR;

try {
// Create a file using default properties.
H5File tempfile(FILE7, H5F_ACC_TRUNC);
// Create a file using the earliest format.
FileAccPropList fapl;
fapl.setLibverBounds(H5F_LIBVER_EARLIEST, H5F_LIBVER_LATEST);
H5File tempfile(FILE7, H5F_ACC_TRUNC, FileCreatPropList::DEFAULT, fapl);

// Get the file's version information.
H5F_info2_t finfo;
Expand Down
2 changes: 1 addition & 1 deletion c++/test/tlinks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -666,7 +666,7 @@ test_visit(hid_t fapl_id, bool new_format)
delete file;

// Reopen the file and group in the file.
file = new H5File(filename, H5F_ACC_RDWR);
file = new H5File(filename, H5F_ACC_RDWR, FileCreatPropList::DEFAULT, fapl);
group = new Group(file->openGroup("Data"));

// Open the group
Expand Down
6 changes: 3 additions & 3 deletions fortran/test/tH5F.F90
Original file line number Diff line number Diff line change
Expand Up @@ -1145,7 +1145,7 @@ SUBROUTINE file_space(filename, cleanup, total_error)

CALL h5fget_freespace_f(fid, free_space, error)
CALL check("h5fget_freespace_f",error,total_error)
IF(error .EQ.0 .AND. free_space .NE. 1248) THEN
IF(error .EQ.0 .AND. free_space .NE. 1853) THEN
total_error = total_error + 1
WRITE(*,*) "1: Wrong amount of free space reported, ", free_space
ENDIF
Expand All @@ -1161,7 +1161,7 @@ SUBROUTINE file_space(filename, cleanup, total_error)
! Check the free space now
CALL h5fget_freespace_f(fid, free_space, error)
CALL check("h5fget_freespace_f",error,total_error)
IF(error .EQ.0 .AND. free_space .NE. 216) THEN
IF(error .EQ.0 .AND. free_space .NE. 1706) THEN
total_error = total_error + 1
WRITE(*,*) "2: Wrong amount of free space reported, ", free_space
ENDIF
Expand All @@ -1173,7 +1173,7 @@ SUBROUTINE file_space(filename, cleanup, total_error)
! Check the free space now
CALL h5fget_freespace_f(fid, free_space, error)
CALL check("h5fget_freespace_f",error,total_error)
IF(error .EQ.0 .AND. free_space .NE. 1248) THEN
IF(error .EQ.0 .AND. free_space .NE. 1853) THEN
total_error = total_error + 1
WRITE(*,*) "3: Wrong amount of free space reported, ", free_space
ENDIF
Expand Down
47 changes: 31 additions & 16 deletions hl/test/test_file_image.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,12 @@
static int
test_file_image(size_t open_images, size_t nflags, const unsigned *flags)
{
hid_t *file_id = NULL, *dset_id = NULL, file_space, plist; /* HDF5 ids */
hsize_t dims1[RANK] = {2, 3}; /* original dimension of datasets */
hid_t *file_id = NULL; /* Array of file IDs */
hid_t *dset_id = NULL; /* Array of dataset IDs */
hid_t file_space_id = H5I_INVALID_HID; /* Dataspace ID */
hid_t dcpl_id = H5I_INVALID_HID; /* DCPL ID */
hid_t fapl_id = H5I_INVALID_HID; /* FAPL ID */
hsize_t dims1[RANK] = {2, 3}; /* original dimension of datasets */
hsize_t max_dims[RANK] = {H5S_UNLIMITED, H5S_UNLIMITED};
int data1[6] = {1, 2, 3, 4, 5, 6}; /* original contents of dataset */
int data2[6] = {7, 8, 9, 10, 11, 12}; /* "wrong" contents of dataset */
Expand Down Expand Up @@ -99,6 +103,13 @@ test_file_image(size_t open_images, size_t nflags, const unsigned *flags)
if (NULL == (dset_id = (hid_t *)malloc(sizeof(hid_t) * open_images)))
FAIL_PUTS_ERROR("malloc() failed");

/* Create FAPL and set earliest format */
/* TODO: run this test with all different formats */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO still relevant here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. It will require different hacking of the superblock for each format version which is why I didn't have time to do it for this release. I can file an issue for it.

if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0)
FAIL_PUTS_ERROR("H5Pcreate() failed");
if (H5Pset_libver_bounds(fapl_id, H5F_LIBVER_EARLIEST, H5F_LIBVER_LATEST) < 0)
FAIL_PUTS_ERROR("H5Pset_libver_bounds() failed");

HL_TESTING2("get file images");

/* create several file images */
Expand All @@ -117,24 +128,24 @@ test_file_image(size_t open_images, size_t nflags, const unsigned *flags)
snprintf(filename[i], filenamelength, "image_file%d.h5", (int)i);

/* create file */
if ((file_id[i] = H5Fcreate(filename[i], H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
if ((file_id[i] = H5Fcreate(filename[i], H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id)) < 0)
FAIL_PUTS_ERROR("H5Fcreate() failed");

/* define dataspace for the dataset */
if ((file_space = H5Screate_simple(RANK, dims1, max_dims)) < 0)
if ((file_space_id = H5Screate_simple(RANK, dims1, max_dims)) < 0)
FAIL_PUTS_ERROR("H5Screate_simple() failed");

/* create dataset property list */
if ((plist = H5Pcreate(H5P_DATASET_CREATE)) < 0)
if ((dcpl_id = H5Pcreate(H5P_DATASET_CREATE)) < 0)
FAIL_PUTS_ERROR("H5Pcreate() failed");

/* set property list to create chunked dataset */
if (H5Pset_chunk(plist, RANK, dims1) < 0)
if (H5Pset_chunk(dcpl_id, RANK, dims1) < 0)
FAIL_PUTS_ERROR("H5Pset_chunk() failed");

/* create and write an integer type dataset named "dset" */
if ((dset_id[i] = H5Dcreate2(file_id[i], DSET_NAME, H5T_NATIVE_INT, file_space, H5P_DEFAULT, plist,
H5P_DEFAULT)) < 0)
if ((dset_id[i] = H5Dcreate2(file_id[i], DSET_NAME, H5T_NATIVE_INT, file_space_id, H5P_DEFAULT,
dcpl_id, H5P_DEFAULT)) < 0)
FAIL_PUTS_ERROR("H5Dcreate() failed");

/* dataset in open image 1 is written with "wrong" data */
Expand All @@ -153,11 +164,11 @@ test_file_image(size_t open_images, size_t nflags, const unsigned *flags)
FAIL_PUTS_ERROR("H5Fflush() failed");

/* close dataset property list */
if (H5Pclose(plist) < 0)
if (H5Pclose(dcpl_id) < 0)
FAIL_PUTS_ERROR("H5Pclose() failed");

/* close dataspace */
if (H5Sclose(file_space) < 0)
if (H5Sclose(file_space_id) < 0)
FAIL_PUTS_ERROR("H5Sclose() failed");

/* close dataset */
Expand Down Expand Up @@ -277,11 +288,11 @@ test_file_image(size_t open_images, size_t nflags, const unsigned *flags)
FAIL_PUTS_ERROR("H5Dopen() failed");

/* get dataspace for the dataset */
if ((file_space = H5Dget_space(dset_id[i])) < 0)
if ((file_space_id = H5Dget_space(dset_id[i])) < 0)
FAIL_PUTS_ERROR("H5Dget_space() failed");

/* get dimensions for the dataset */
if (H5Sget_simple_extent_dims(file_space, dims3, NULL) < 0)
if (H5Sget_simple_extent_dims(file_space_id, dims3, NULL) < 0)
FAIL_PUTS_ERROR("H5Sget_simple_extent_dims() failed");

/* read dataset */
Expand Down Expand Up @@ -312,7 +323,7 @@ test_file_image(size_t open_images, size_t nflags, const unsigned *flags)
} /* end else */

/* close dataspace */
if (H5Sclose(file_space) < 0)
if (H5Sclose(file_space_id) < 0)
FAIL_PUTS_ERROR("H5Sclose() failed");
} /* end for */

Expand Down Expand Up @@ -455,11 +466,11 @@ test_file_image(size_t open_images, size_t nflags, const unsigned *flags)
FAIL_PUTS_ERROR("H5Dopen() failed");

/* get dataspace for the dataset */
if ((file_space = H5Dget_space(dset_id[i])) < 0)
if ((file_space_id = H5Dget_space(dset_id[i])) < 0)
FAIL_PUTS_ERROR("H5Dget_space() failed");

/* get dimensions for the dataset */
if (H5Sget_simple_extent_dims(file_space, dims3, NULL) < 0)
if (H5Sget_simple_extent_dims(file_space_id, dims3, NULL) < 0)
FAIL_PUTS_ERROR("H5Sget_simple_extent_dims() failed");

/* read dataset */
Expand All @@ -479,7 +490,7 @@ test_file_image(size_t open_images, size_t nflags, const unsigned *flags)
FAIL_PUTS_ERROR("comparison of image values with original data failed");

/* close dataspace */
if (H5Sclose(file_space) < 0)
if (H5Sclose(file_space_id) < 0)
FAIL_PUTS_ERROR("H5Sclose() failed");

/* close dataset */
Expand Down Expand Up @@ -513,6 +524,10 @@ test_file_image(size_t open_images, size_t nflags, const unsigned *flags)

} /* end for */

/* close file access property list */
if (H5Pclose(fapl_id) < 0)
FAIL_PUTS_ERROR("H5Pclose() failed");

/* release temporary working buffers */
for (i = 0; i < open_images; i++)
free(filename[i]);
Expand Down
2 changes: 1 addition & 1 deletion java/test/TestH5Fbasic.java
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ public void testH5Fget_mdc_size()
catch (Throwable err) {
fail("H5.H5Fget_mdc_size: " + err);
}
assertTrue("H5.H5Fget_mdc_size #:" + nentries, nentries == 4);
assertTrue("H5.H5Fget_mdc_size #:" + nentries, nentries == 2);
}

// TODO: test more cases of different cache sizes.
Expand Down
2 changes: 1 addition & 1 deletion java/test/TestH5Fparams.java
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ public void testH5Fget_info()

try {
H5F_info2_t finfo = H5.H5Fget_info(fid);
assertEquals(finfo.super_version, 0);
assertEquals(finfo.super_version, 2);
assertEquals(finfo.free_version, 0);
assertEquals(finfo.sohm_version, 0);
}
Expand Down
8 changes: 4 additions & 4 deletions java/test/TestH5P.java
Original file line number Diff line number Diff line change
Expand Up @@ -1038,7 +1038,7 @@ public void testH5P_userblock()

/* Get the file's version information */
H5F_info2_t finfo = H5.H5Fget_info(H5fid);
assertTrue("super block version: " + finfo.super_version, finfo.super_version == 0);
assertTrue("super block version: " + finfo.super_version, finfo.super_version == 2);
assertTrue("free-space manager version: " + finfo.free_version, finfo.free_version == 0);
assertTrue("shared object header version: " + finfo.sohm_version, finfo.sohm_version == 0);
H5.H5Pget_userblock(fcpl_id, size);
Expand Down Expand Up @@ -1074,7 +1074,7 @@ public void testH5P_sizes()

/* Get the file's version information */
H5F_info2_t finfo = H5.H5Fget_info(H5fid);
assertTrue("super block version: " + finfo.super_version, finfo.super_version == 0);
assertTrue("super block version: " + finfo.super_version, finfo.super_version == 2);
assertTrue("free-space manager version: " + finfo.free_version, finfo.free_version == 0);
assertTrue("shared object header version: " + finfo.sohm_version, finfo.sohm_version == 0);
H5.H5Pget_sizes(fcpl_id, size);
Expand Down Expand Up @@ -1111,7 +1111,7 @@ public void testH5P_sym_k()

/* Get the file's version information */
H5F_info2_t finfo = H5.H5Fget_info(H5fid);
assertTrue("super block version: " + finfo.super_version, finfo.super_version == 0);
assertTrue("super block version: " + finfo.super_version, finfo.super_version == 2);
assertTrue("free-space manager version: " + finfo.free_version, finfo.free_version == 0);
assertTrue("shared object header version: " + finfo.sohm_version, finfo.sohm_version == 0);
H5.H5Pget_sym_k(fcpl_id, size);
Expand Down Expand Up @@ -1148,7 +1148,7 @@ public void testH5P_istore_k()

/* Get the file's version information */
H5F_info2_t finfo = H5.H5Fget_info(H5fid);
assertTrue("super block version: " + finfo.super_version, finfo.super_version == 1);
assertTrue("super block version: " + finfo.super_version, finfo.super_version == 2);
assertTrue("free-space manager version: " + finfo.free_version, finfo.free_version == 0);
assertTrue("shared object header version: " + finfo.sohm_version, finfo.sohm_version == 0);
H5.H5Pget_istore_k(fcpl_id, size);
Expand Down
2 changes: 1 addition & 1 deletion java/test/TestH5Pfapl.java
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ public void testH5Pget_libver_bounds()
}
assertTrue("testH5Pget_libver_bounds", ret_val >= 0);
// Check the Earliest Version if the library
assertEquals(HDF5Constants.H5F_LIBVER_EARLIEST, libver[0]);
assertEquals(HDF5Constants.H5F_LIBVER_V18, libver[0]);
// Check the Latest Version if the library
assertEquals(HDF5Constants.H5F_LIBVER_LATEST, libver[1]);
}
Expand Down
16 changes: 16 additions & 0 deletions release_docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ For releases prior to version 2.0.0, please see the release.txt file and for mor

# ⚠️ Breaking Changes

### Updated default file format to 1.8

By default, HDF5 will now use the 1.8 file format (`H5F_LIBVER_V18`). This provides improved performance and space efficiency, particularly with groups and links. However, HDF5 library versions 1.6 and earlier will not be able to read files created with the default settings. The previous behavior can be restored using `H5Pset_libver_bounds(fapl_id, H5F_LIBVER_EARLIEST, H5F_LIBVER_LATEST)`.

### Renamed the option: `HDF5_ENABLE_Z_LIB_SUPPORT`

The option has been renamed to `HDF5_ENABLE_ZLIB_SUPPORT` to be consistent with the naming of other options. Also, the option defaults to OFF. This requires the user to explicitly enable zlib support when configuring the library.
Expand All @@ -59,6 +63,10 @@ For releases prior to version 2.0.0, please see the release.txt file and for mor

CMake is now the build system available in HDF5 code. Version 3.26 or later is required. See the AutotoolsToCMakeOptions.md file for highlights of the CMake HDF5 install layout and CMake options to use in place of former Autotools options.

### Fixed problems with family driver and user block

When using a user block with the family driver, the driver would inappropriately subtract the user block size for each member file when calculating member EOAs. This could cause a failure when an address overflowed the calculated eoa. The driver would also add the user block size when returning the EOF. Modified the family driver to not consider the user block, as it is handled by the H5FD layer. The user block now spans the first X bytes of the family array, for example a 4 KiB user block with 3 KiB member size will take up the entire first member and the first 1 KiB of the second. This may cause compatibility issues with preexisting family files with user blocks, though the way it worked before was inconsistent if it worked at all.

# 🚀 New Features & Improvements

## Configuration
Expand Down Expand Up @@ -185,6 +193,10 @@ All other HDF5 library CMake options are prefixed with `HDF5_`

## Library

### Updated default file format to 1.8

By default, HDF5 will now use the 1.8 file format (`H5F_LIBVER_V18`). This provides improved performance and space efficiency, particularly with groups and links. This behavior can be overridden with `H5Pset_libver_bounds()`.

### Added predefined datatypes for bfloat16 data

Predefined datatypes have been added for little- and big-endian bfloat16 (https://en.wikipedia.org/wiki/Bfloat16_floating-point_format) data.
Expand Down Expand Up @@ -557,6 +569,10 @@ Added Fortran wrapper h5fdsubfiling_get_file_mapping_f() for the subfiling file

## Library

### Fixed problems with family driver and user block

When using a user block with the family driver, the driver would inappropriately subtract the user block size for each member file when calculating member EOAs. This could cause a failure when an address overflowed the calculated eoa. The driver would also add the user block size when returning the EOF. Modified the family driver to not consider the user block, as it is handled by the H5FD layer. The user block now spans the first X bytes of the family array, for example a 4 KiB user block with 3 KiB member size will take up the entire first member and the first 1 KiB of the second. This may cause compatibility issues with preexisting family files with user blocks, though the way it worked before was inconsistent if it worked at all.

### Fixed security issue CVE-2025-7067

Fixed a heap buffer overflow in H5FS__sinfo_serialize_node_cb() by discarding file free space sections from the file free space manager when they are found to be invalid. Specifically crafted HDF5 files can result in an attempt to insert duplicate or overlapping file free space sections into a file free space manager, later resulting in a buffer overflow when the same free space section is serialized to the file multiple times.
Expand Down
8 changes: 2 additions & 6 deletions src/H5FDfamily.c
Original file line number Diff line number Diff line change
Expand Up @@ -1016,15 +1016,14 @@ H5FD__family_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t abs_eoa)
} /* end if */

/* Set the EOA marker for the member */
/* (Note compensating for base address addition in internal routine) */
H5_CHECK_OVERFLOW(file->memb_size, hsize_t, haddr_t);
if (addr > (haddr_t)file->memb_size) {
if (H5FD_set_eoa(file->memb[u], type, ((haddr_t)file->memb_size - file->pub.base_addr)) < 0)
if (H5FD_set_eoa(file->memb[u], type, (haddr_t)file->memb_size) < 0)
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to set file eoa");
addr -= file->memb_size;
} /* end if */
else {
if (H5FD_set_eoa(file->memb[u], type, (addr - file->pub.base_addr)) < 0)
if (H5FD_set_eoa(file->memb[u], type, addr) < 0)
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to set file eoa");
addr = 0;
} /* end else */
Expand Down Expand Up @@ -1077,9 +1076,6 @@ H5FD__family_get_eof(const H5FD_t *_file, H5FD_mem_t type)
break;
} /* end for */

/* Adjust for base address for file */
eof += file->pub.base_addr;

/*
* The file size is the number of members before the i'th member plus the
* size of the i'th member.
Expand Down
2 changes: 1 addition & 1 deletion src/H5Pfapl.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@

/* Definition for "low" bound of library format versions */
#define H5F_ACS_LIBVER_LOW_BOUND_SIZE sizeof(H5F_libver_t)
#define H5F_ACS_LIBVER_LOW_BOUND_DEF H5F_LIBVER_EARLIEST
#define H5F_ACS_LIBVER_LOW_BOUND_DEF H5F_LIBVER_V18
#define H5F_ACS_LIBVER_LOW_BOUND_ENC H5P__facc_libver_type_enc
#define H5F_ACS_LIBVER_LOW_BOUND_DEC H5P__facc_libver_type_dec

Expand Down
Loading
Loading