From 94094609d91866d2f61a74efa48c0a12e426467f Mon Sep 17 00:00:00 2001 From: Binh-Minh Date: Mon, 27 Apr 2026 03:55:22 -0400 Subject: [PATCH 01/12] Various improvement in documentation and a decoding function - Improves documentation on the type size when creating/accessing a compound datatype with no predefined struct (GH issue #5371) - Provides better description of the min_meta_perc and min_raw_perc arguments in the H5Pset_page_buffer_size() (GH issue #5711) - Adds error checkings to an internal decoding function --- hl/src/H5TBpublic.h | 63 +++++++++++++++++++++++++++++++++----------- src/H5FDonion.c | 2 +- src/H5Fsuper_cache.c | 50 +++++++++++++++++++++++++++++++++++ src/H5Ppublic.h | 11 ++++++++ src/H5VM.c | 2 +- 5 files changed, 110 insertions(+), 18 deletions(-) diff --git a/hl/src/H5TBpublic.h b/hl/src/H5TBpublic.h index 7879712b361..de59f945b48 100644 --- a/hl/src/H5TBpublic.h +++ b/hl/src/H5TBpublic.h @@ -128,8 +128,7 @@ extern "C" { * \param[in] nfields The number of fields * \param[in] nrecords The number of records * \param[in] type_size The size in bytes of the structure - * associated with the table; - * This value is obtained with \c sizeof(). + * associated with the table * \param[in] field_names An array containing the names of * the fields * \param[in] field_offset An array containing the offsets of @@ -147,6 +146,10 @@ extern "C" { * \p dset_name attached to the object specified by the * identifier loc_id. * + * \p type_size can be obtained with \c sizeof() if the data is stored + * stored in a predefined C struct, otherwise, use H5Tget_size() on + * the compound datatype. + * */ H5HL_DLL herr_t H5TBmake_table(const char *table_title, hid_t loc_id, const char *dset_name, hsize_t nfields, hsize_t nrecords, size_t type_size, const char *field_names[], @@ -169,8 +172,7 @@ H5HL_DLL herr_t H5TBmake_table(const char *table_title, hid_t loc_id, const char * \fg_loc_id * \param[in] dset_name The name of the dataset to overwrite * \param[in] nrecords The number of records to append - * \param[in] type_size The size of the structure type, - * as calculated by \c sizeof(). + * \param[in] type_size The size of the structure type * \param[in] field_offset An array containing the offsets of * the fields. These offsets can be * calculated with the #HOFFSET macro @@ -185,6 +187,10 @@ H5HL_DLL herr_t H5TBmake_table(const char *table_title, hid_t loc_id, const char * identifier \p loc_id. The dataset is extended to hold the * new records. * + * \p type_size can be obtained with \c sizeof() if the data is stored + * stored in a predefined C struct, otherwise, use H5Tget_size() on + * the compound datatype. + * */ H5HL_DLL herr_t H5TBappend_records(hid_t loc_id, const char *dset_name, hsize_t nrecords, size_t type_size, const size_t *field_offset, const size_t *dst_sizes, const void *buf); @@ -199,8 +205,7 @@ H5HL_DLL herr_t H5TBappend_records(hid_t loc_id, const char *dset_name, hsize_t * \param[in] dset_name The name of the dataset to overwrite * \param[in] start The zero index record to start writing * \param[in] nrecords The number of records to write - * \param[in] type_size The size of the structure type, as - * calculated by \c sizeof(). + * \param[in] type_size The size of the structure type * \param[in] field_offset An array containing the offsets of * the fields. These offsets can be * calculated with the #HOFFSET macro @@ -214,6 +219,10 @@ H5HL_DLL herr_t H5TBappend_records(hid_t loc_id, const char *dset_name, hsize_t * index position start of the table named \p dset_name attached * to the object specified by the identifier \p loc_id. * + * \p type_size can be obtained with \c sizeof() if the data is stored + * stored in a predefined C struct, otherwise, use H5Tget_size() on + * the compound datatype. + * */ H5HL_DLL herr_t H5TBwrite_records(hid_t loc_id, const char *dset_name, hsize_t start, hsize_t nrecords, size_t type_size, const size_t *field_offset, const size_t *dst_sizes, @@ -230,8 +239,7 @@ H5HL_DLL herr_t H5TBwrite_records(hid_t loc_id, const char *dset_name, hsize_t s * \param[in] field_names The names of the fields to write * \param[in] start The zero index record to start writing * \param[in] nrecords The number of records to write - * \param[in] type_size The size of the structure type, as - * calculated by \c sizeof(). + * \param[in] type_size The size of the structure type * \param[in] field_offset An array containing the offsets of * the fields. These offsets can be * calculated with the #HOFFSET macro @@ -246,6 +254,10 @@ H5HL_DLL herr_t H5TBwrite_records(hid_t loc_id, const char *dset_name, hsize_t s * dataset named \p dset_name attached to the object specified * by the identifier \p loc_id. * + * \p type_size can be obtained with \c sizeof() if the data is stored + * stored in a predefined C struct, otherwise, use H5Tget_size() on + * the compound datatype. + * */ H5HL_DLL herr_t H5TBwrite_fields_name(hid_t loc_id, const char *dset_name, const char *field_names, hsize_t start, hsize_t nrecords, size_t type_size, @@ -265,8 +277,7 @@ H5HL_DLL herr_t H5TBwrite_fields_name(hid_t loc_id, const char *dset_name, const * \param[in] field_index The indexes of the fields to write * \param[in] start The zero based index record to start writing * \param[in] nrecords The number of records to write - * \param[in] type_size The size of the structure type, as - * calculated by \c sizeof(). + * \param[in] type_size The size of the structure type * \param[in] field_offset An array containing the offsets of * the fields. These offsets can be * calculated with the #HOFFSET macro @@ -281,6 +292,10 @@ H5HL_DLL herr_t H5TBwrite_fields_name(hid_t loc_id, const char *dset_name, const * dataset named \p dset_name attached to the object * specified by the identifier \p loc_id. * + * \p type_size can be obtained with \c sizeof() if the data is stored + * stored in a predefined C struct, otherwise, use H5Tget_size() on + * the compound datatype. + * */ H5HL_DLL herr_t H5TBwrite_fields_index(hid_t loc_id, const char *dset_name, hsize_t nfields, const int *field_index, hsize_t start, hsize_t nrecords, @@ -302,8 +317,7 @@ H5HL_DLL herr_t H5TBwrite_fields_index(hid_t loc_id, const char *dset_name, hsiz * * \fg_loc_id * \param[in] dset_name The name of the dataset to read - * \param[in] dst_size The size of the structure type, - * as calculated by \c sizeof() + * \param[in] dst_size The size of the structure type * \param[in] dst_offset An array containing the offsets of * the fields. These offsets can be * calculated with the #HOFFSET macro @@ -318,6 +332,10 @@ H5HL_DLL herr_t H5TBwrite_fields_index(hid_t loc_id, const char *dset_name, hsiz * \p dset_name attached to the object specified by * the identifier \p loc_id. * + * \p type_size can be obtained with \c sizeof() if the predefined C + * structure is available, otherwise, use H5Tget_size() on the + * compound datatype. + * */ H5HL_DLL herr_t H5TBread_table(hid_t loc_id, const char *dset_name, size_t dst_size, const size_t *dst_offset, const size_t *dst_sizes, void *dst_buf); @@ -336,7 +354,6 @@ H5HL_DLL herr_t H5TBread_table(hid_t loc_id, const char *dset_name, size_t dst_s * \param[in] nrecords The number of records to read * \param[in] type_size The size in bytes of the structure associated * with the table - * (This value is obtained with \c sizeof().) * \param[in] field_offset An array containing the offsets of the fields * \param[in] dst_sizes An array containing the size in bytes of * the fields @@ -348,6 +365,10 @@ H5HL_DLL herr_t H5TBread_table(hid_t loc_id, const char *dset_name, size_t dst_s * by \p field_names from a dataset named \p dset_name * attached to the object specified by the identifier \p loc_id. * + * \p type_size can be obtained with \c sizeof() if the predefined C + * structure is available, otherwise, use H5Tget_size() on the + * compound datatype. + * */ H5HL_DLL herr_t H5TBread_fields_name(hid_t loc_id, const char *dset_name, const char *field_names, hsize_t start, hsize_t nrecords, size_t type_size, @@ -371,7 +392,6 @@ H5HL_DLL herr_t H5TBread_fields_name(hid_t loc_id, const char *dset_name, const * \param[in] nrecords The number of records to read * \param[in] type_size The size in bytes of the structure associated * with the table - * (This value is obtained with \c sizeof()) * \param[in] field_offset An array containing the offsets of the fields * \param[in] dst_sizes An array containing the size in bytes of * the fields @@ -383,6 +403,10 @@ H5HL_DLL herr_t H5TBread_fields_name(hid_t loc_id, const char *dset_name, const * by \p field_index from a dataset named \p dset_name attached * to the object specified by the identifier \p loc_id. * + * \p type_size can be obtained with \c sizeof() if the predefined C + * structure is available, otherwise, use H5Tget_size() on the + * compound datatype. + * */ H5HL_DLL herr_t H5TBread_fields_index(hid_t loc_id, const char *dset_name, hsize_t nfields, const int *field_index, hsize_t start, hsize_t nrecords, @@ -400,8 +424,7 @@ H5HL_DLL herr_t H5TBread_fields_index(hid_t loc_id, const char *dset_name, hsize * \param[in] dset_name The name of the dataset to read * \param[in] start The start record to read from * \param[in] nrecords The number of records to read - * \param[in] type_size The size of the structure type, - * as calculated by \c sizeof() + * \param[in] type_size The size of the structure type * \param[in] dst_offset An array containing the offsets of the * fields. These offsets can be calculated * with the #HOFFSET macro @@ -415,6 +438,10 @@ H5HL_DLL herr_t H5TBread_fields_index(hid_t loc_id, const char *dset_name, hsize * named \p dset_name attached to the object specified by the * identifier \p loc_id. * + * \p type_size can be obtained with \c sizeof() if the predefined C + * structure is available, otherwise, use H5Tget_size() on the + * compound datatype. + * */ H5HL_DLL herr_t H5TBread_records(hid_t loc_id, const char *dset_name, hsize_t start, hsize_t nrecords, size_t type_size, const size_t *dst_offset, const size_t *dst_sizes, @@ -528,6 +555,10 @@ H5HL_DLL herr_t H5TBdelete_record(hid_t loc_id, const char *dset_name, hsize_t s * \details H5TBinsert_record() inserts records into the middle of the table * ("pushing down" all the records after it) * + * \p dst_size can be obtained with \c sizeof() if the predefined C + * structure is available, otherwise, use H5Tget_size() on the + * compound datatype. + * */ H5HL_DLL herr_t H5TBinsert_record(hid_t loc_id, const char *dset_name, hsize_t start, hsize_t nrecords, size_t dst_size, const size_t *dst_offset, const size_t *dst_sizes, diff --git a/src/H5FDonion.c b/src/H5FDonion.c index 9a00bf09f32..52aece63fab 100644 --- a/src/H5FDonion.c +++ b/src/H5FDonion.c @@ -1154,7 +1154,7 @@ H5FD__onion_open(const char *filename, unsigned flags, hid_t fapl_id, haddr_t ma * We're getting this buffer from a fixed-size array in a struct, which * will be garbage and not null-terminated if the user isn't careful. * Be careful of this and do strndup first to ensure strdup gets a - * null-termianted string (HDF5 doesn't provide a strnlen call if you + * null-terminated string (HDF5 doesn't provide a strnlen call if you * don't have one). */ if (NULL == diff --git a/src/H5Fsuper_cache.c b/src/H5Fsuper_cache.c index 8a040cbed7c..2591aea663c 100644 --- a/src/H5Fsuper_cache.c +++ b/src/H5Fsuper_cache.c @@ -521,12 +521,36 @@ H5F__cache_superblock_deserialize(const void *_image, size_t len, void *_udata, udata->btree_k[H5B_CHUNK_ID] = chunk_btree_k; /* Remainder of "variable-sized" portion of superblock */ + + /* Check whether the image pointer will be out of bounds */ if (H5_IS_BUFFER_OVERFLOW(image, H5F_sizeof_addr(udata->f) * 4, end)) HGOTO_ERROR(H5E_FILE, H5E_OVERFLOW, NULL, "image pointer is out of bounds"); + + /* Get and verify base address, delay additional verification */ H5F_addr_decode(udata->f, (const uint8_t **)&image, &sblock->base_addr /*out*/); + if (!H5_addr_defined(sblock->base_addr)) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "base address is undefined"); + + /* Get extension address, delay verification until stored eof is avail */ H5F_addr_decode(udata->f, (const uint8_t **)&image, &sblock->ext_addr /*out*/); + + /* Get and verify stored eof */ H5F_addr_decode(udata->f, (const uint8_t **)&image, &udata->stored_eof /*out*/); + if (!H5_addr_defined(udata->stored_eof)) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "stored EOF address is undefined"); + if (udata->stored_eof == 0) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "stored EOF address cannot be 0"); + + /* Get driver address */ H5F_addr_decode(udata->f, (const uint8_t **)&image, &sblock->driver_addr /*out*/); + if (H5_addr_defined(sblock->driver_addr) && sblock->driver_addr >= udata->stored_eof) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "driver info block address exceeds end of file"); + + /* Validate base and extension addresses against stored_eof */ + if (sblock->base_addr >= udata->stored_eof) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "base address exceeds stored EOF"); + if (H5_addr_defined(sblock->ext_addr) && sblock->ext_addr >= udata->stored_eof) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "superblock extension address exceeds stored EOF"); /* Allocate space for the root group symbol table entry */ if (sblock->root_ent) @@ -579,10 +603,36 @@ H5F__cache_superblock_deserialize(const void *_image, size_t len, void *_udata, HGOTO_ERROR(H5E_FILE, H5E_OVERFLOW, NULL, "image pointer is out of bounds"); /* Base, superblock extension, end of file & root group object header addresses */ + + /* Get and verify base address, delay additional verification */ H5F_addr_decode(udata->f, (const uint8_t **)&image, &sblock->base_addr /*out*/); + if (!H5_addr_defined(sblock->base_addr)) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "base address is undefined"); + + /* Get extension address, delay verification until stored eof is avail */ H5F_addr_decode(udata->f, (const uint8_t **)&image, &sblock->ext_addr /*out*/); + + /* Get and verify stored eof */ H5F_addr_decode(udata->f, (const uint8_t **)&image, &udata->stored_eof /*out*/); + if (!H5_addr_defined(udata->stored_eof)) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "stored EOF address is undefined"); + if (udata->stored_eof == 0) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "stored EOF address cannot be 0"); + + /* Get and verify root address */ H5F_addr_decode(udata->f, (const uint8_t **)&image, &sblock->root_addr /*out*/); + if (!H5_addr_defined(sblock->root_addr)) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "root address is undefined"); + if (sblock->root_addr == 0) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "root address cannot be 0"); + if (sblock->root_addr >= udata->stored_eof) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "root group address beyond stored EOF"); + + /* Validate base and extension addresses against stored_eof */ + if (sblock->base_addr >= udata->stored_eof) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "base address exceeds stored EOF"); + if (H5_addr_defined(sblock->ext_addr) && sblock->ext_addr >= udata->stored_eof) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "superblock extension address exceeds stored EOF"); /* checksum verification already done in verify_chksum cb */ diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index dcc3eeb57d7..bc5d5b9ea99 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -5763,6 +5763,17 @@ H5_DLL herr_t H5Pset_mdc_image_config(hid_t plist_id, H5AC_cache_image_config_t * larger than the page buffer size, the subsequent call to H5Fcreate() * using the \p plist_id will fail. * + * The arguments min_meta_perc and min_raw_perc are to prevent one type + * of data from evicting hot pages of the other type, that is, pushing + * them out of the buffer. Setting a minimum percentage for each type + * reserves a portion of the page buffer for that type, ensuring both + * metadata and raw data can maintain a presence in the buffer. + * + * The following constraints apply to min_meta_perc and min_raw_perc: + * - Each must be between 0 and 100 inclusive + * - Their sum must not exceed 100, that is, together they can't reserve + * more than the entire page buffer. + * * \note As of HDF5 1.14.4, this property will be ignored when an existing * file is being opened and the file space strategy stored in the * file isn't paged. This was previously a failure. diff --git a/src/H5VM.c b/src/H5VM.c index 758f706a517..7783b969fc2 100644 --- a/src/H5VM.c +++ b/src/H5VM.c @@ -1308,7 +1308,7 @@ H5VM_opvv(size_t dst_max_nseq, size_t *dst_curr_seq, size_t dst_len_arr[], hsize * Function: H5VM_memcpyvv * * Purpose: Given source and destination buffers in memory (SRC & DST) - * copy sequences of from the source buffer into the destination + * copy sequences from the source buffer into the destination * buffer. Each set of sequences has an array of lengths, an * array of offsets, the maximum number of sequences and the * current sequence to start at in the sequence. From cababa766d7f2976f79d1f231dc08c6935d37d01 Mon Sep 17 00:00:00 2001 From: Binh-Minh Date: Mon, 27 Apr 2026 16:29:58 -0400 Subject: [PATCH 02/12] Corrected the checks, the base address equals the end-of-file is valid. --- src/H5Fsuper_cache.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/H5Fsuper_cache.c b/src/H5Fsuper_cache.c index 2591aea663c..2fb4799bad1 100644 --- a/src/H5Fsuper_cache.c +++ b/src/H5Fsuper_cache.c @@ -547,7 +547,7 @@ H5F__cache_superblock_deserialize(const void *_image, size_t len, void *_udata, HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "driver info block address exceeds end of file"); /* Validate base and extension addresses against stored_eof */ - if (sblock->base_addr >= udata->stored_eof) + if (sblock->base_addr > udata->stored_eof) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "base address exceeds stored EOF"); if (H5_addr_defined(sblock->ext_addr) && sblock->ext_addr >= udata->stored_eof) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "superblock extension address exceeds stored EOF"); @@ -629,7 +629,7 @@ H5F__cache_superblock_deserialize(const void *_image, size_t len, void *_udata, HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "root group address beyond stored EOF"); /* Validate base and extension addresses against stored_eof */ - if (sblock->base_addr >= udata->stored_eof) + if (sblock->base_addr > udata->stored_eof) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "base address exceeds stored EOF"); if (H5_addr_defined(sblock->ext_addr) && sblock->ext_addr >= udata->stored_eof) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "superblock extension address exceeds stored EOF"); From 0f28f26a9408dbb320441bdb5fc7602f339e9515 Mon Sep 17 00:00:00 2001 From: Binh-Minh Date: Tue, 28 Apr 2026 02:28:44 -0400 Subject: [PATCH 03/12] Skip for multi-file and split drivers when validating addresses against stored_eof --- src/H5Fsuper_cache.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/H5Fsuper_cache.c b/src/H5Fsuper_cache.c index 2fb4799bad1..55c4aa81b0b 100644 --- a/src/H5Fsuper_cache.c +++ b/src/H5Fsuper_cache.c @@ -625,14 +625,19 @@ H5F__cache_superblock_deserialize(const void *_image, size_t len, void *_udata, HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "root address is undefined"); if (sblock->root_addr == 0) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "root address cannot be 0"); - if (sblock->root_addr >= udata->stored_eof) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "root group address beyond stored EOF"); - /* Validate base and extension addresses against stored_eof */ - if (sblock->base_addr > udata->stored_eof) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "base address exceeds stored EOF"); - if (H5_addr_defined(sblock->ext_addr) && sblock->ext_addr >= udata->stored_eof) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "superblock extension address exceeds stored EOF"); + /* Validate addresses against stored_eof. + Skip for multi-file and split drivers which use relative/fractional addresses + that are not actual file offsets. */ + if (udata->f->shared->lf->cls->value != H5_VFD_MULTI && + udata->f->shared->lf->cls->value != H5_VFD_SPLIT) { + if (sblock->base_addr > udata->stored_eof) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "base address exceeds stored EOF"); + if (sblock->root_addr >= udata->stored_eof) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "root group address beyond stored EOF"); + if (H5_addr_defined(sblock->ext_addr) && sblock->ext_addr >= udata->stored_eof) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "superblock extension address exceeds stored EOF"); + } /* checksum verification already done in verify_chksum cb */ From 7208005eeeafa2ee1ac1cf64d691f0a7491bac18 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 28 Apr 2026 06:31:03 +0000 Subject: [PATCH 04/12] Committing clang-format changes --- src/H5Fsuper_cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/H5Fsuper_cache.c b/src/H5Fsuper_cache.c index 55c4aa81b0b..38f2d9bccaf 100644 --- a/src/H5Fsuper_cache.c +++ b/src/H5Fsuper_cache.c @@ -627,7 +627,7 @@ H5F__cache_superblock_deserialize(const void *_image, size_t len, void *_udata, HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "root address cannot be 0"); /* Validate addresses against stored_eof. - Skip for multi-file and split drivers which use relative/fractional addresses + Skip for multi-file and split drivers which use relative/fractional addresses that are not actual file offsets. */ if (udata->f->shared->lf->cls->value != H5_VFD_MULTI && udata->f->shared->lf->cls->value != H5_VFD_SPLIT) { From 99cd164e3bf166a5f1c09fca21c35e5f01b9e576 Mon Sep 17 00:00:00 2001 From: Binh-Minh Date: Tue, 28 Apr 2026 03:00:34 -0400 Subject: [PATCH 05/12] Remove incorrect name --- src/H5Fsuper_cache.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/H5Fsuper_cache.c b/src/H5Fsuper_cache.c index 38f2d9bccaf..9043aeb78fb 100644 --- a/src/H5Fsuper_cache.c +++ b/src/H5Fsuper_cache.c @@ -629,8 +629,7 @@ H5F__cache_superblock_deserialize(const void *_image, size_t len, void *_udata, /* Validate addresses against stored_eof. Skip for multi-file and split drivers which use relative/fractional addresses that are not actual file offsets. */ - if (udata->f->shared->lf->cls->value != H5_VFD_MULTI && - udata->f->shared->lf->cls->value != H5_VFD_SPLIT) { + if (udata->f->shared->lf->cls->value != H5_VFD_MULTI) { if (sblock->base_addr > udata->stored_eof) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "base address exceeds stored EOF"); if (sblock->root_addr >= udata->stored_eof) From 6dbf4929edaeba8ab23c9c1bd55cfe269ddf7702 Mon Sep 17 00:00:00 2001 From: Binh-Minh Date: Mon, 18 May 2026 00:54:44 -0400 Subject: [PATCH 06/12] Fix typos --- hl/src/H5TBpublic.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hl/src/H5TBpublic.h b/hl/src/H5TBpublic.h index de59f945b48..e2d9055c91b 100644 --- a/hl/src/H5TBpublic.h +++ b/hl/src/H5TBpublic.h @@ -146,7 +146,7 @@ extern "C" { * \p dset_name attached to the object specified by the * identifier loc_id. * - * \p type_size can be obtained with \c sizeof() if the data is stored + * \p type_size can be obtained with \c sizeof() if the data is * stored in a predefined C struct, otherwise, use H5Tget_size() on * the compound datatype. * @@ -187,7 +187,7 @@ H5HL_DLL herr_t H5TBmake_table(const char *table_title, hid_t loc_id, const char * identifier \p loc_id. The dataset is extended to hold the * new records. * - * \p type_size can be obtained with \c sizeof() if the data is stored + * \p type_size can be obtained with \c sizeof() if the data is * stored in a predefined C struct, otherwise, use H5Tget_size() on * the compound datatype. * @@ -219,7 +219,7 @@ H5HL_DLL herr_t H5TBappend_records(hid_t loc_id, const char *dset_name, hsize_t * index position start of the table named \p dset_name attached * to the object specified by the identifier \p loc_id. * - * \p type_size can be obtained with \c sizeof() if the data is stored + * \p type_size can be obtained with \c sizeof() if the data is * stored in a predefined C struct, otherwise, use H5Tget_size() on * the compound datatype. * @@ -254,7 +254,7 @@ H5HL_DLL herr_t H5TBwrite_records(hid_t loc_id, const char *dset_name, hsize_t s * dataset named \p dset_name attached to the object specified * by the identifier \p loc_id. * - * \p type_size can be obtained with \c sizeof() if the data is stored + * \p type_size can be obtained with \c sizeof() if the data is * stored in a predefined C struct, otherwise, use H5Tget_size() on * the compound datatype. * @@ -292,7 +292,7 @@ H5HL_DLL herr_t H5TBwrite_fields_name(hid_t loc_id, const char *dset_name, const * dataset named \p dset_name attached to the object * specified by the identifier \p loc_id. * - * \p type_size can be obtained with \c sizeof() if the data is stored + * \p type_size can be obtained with \c sizeof() if the data is * stored in a predefined C struct, otherwise, use H5Tget_size() on * the compound datatype. * From 2611dba47e977222f097fc07e9fae6f0bbc4c116 Mon Sep 17 00:00:00 2001 From: Binh-Minh Date: Thu, 21 May 2026 18:50:55 -0400 Subject: [PATCH 07/12] Modified description of type_size arguments --- hl/src/H5TBpublic.h | 57 ++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/hl/src/H5TBpublic.h b/hl/src/H5TBpublic.h index e2d9055c91b..b98edbd57c8 100644 --- a/hl/src/H5TBpublic.h +++ b/hl/src/H5TBpublic.h @@ -146,9 +146,12 @@ extern "C" { * \p dset_name attached to the object specified by the * identifier loc_id. * - * \p type_size can be obtained with \c sizeof() if the data is - * stored in a predefined C struct, otherwise, use H5Tget_size() on - * the compound datatype. + * \p type_size can be obtained with \c sizeof(), if the data is + * stored in a predefined C struct. Otherwise, \p type_size should + * be calculated as the sum of calling H5Tget_size() for each of + * the given field datatypes in \p field_types, plus any padding + * bytes included in the structure, based on the given field offsets + * in \p field_offset. * */ H5HL_DLL herr_t H5TBmake_table(const char *table_title, hid_t loc_id, const char *dset_name, hsize_t nfields, @@ -187,9 +190,9 @@ H5HL_DLL herr_t H5TBmake_table(const char *table_title, hid_t loc_id, const char * identifier \p loc_id. The dataset is extended to hold the * new records. * - * \p type_size can be obtained with \c sizeof() if the data is - * stored in a predefined C struct, otherwise, use H5Tget_size() on - * the compound datatype. + * \p type_size can be obtained with \c sizeof(), if the data is + * stored in a predefined C struct. Otherwise, it can be obtained + * by calling H5TBget_field_info() if not already known. * */ H5HL_DLL herr_t H5TBappend_records(hid_t loc_id, const char *dset_name, hsize_t nrecords, size_t type_size, @@ -219,9 +222,9 @@ H5HL_DLL herr_t H5TBappend_records(hid_t loc_id, const char *dset_name, hsize_t * index position start of the table named \p dset_name attached * to the object specified by the identifier \p loc_id. * - * \p type_size can be obtained with \c sizeof() if the data is - * stored in a predefined C struct, otherwise, use H5Tget_size() on - * the compound datatype. + * \p type_size can be obtained with \c sizeof(), if the data is + * stored in a predefined C struct. Otherwise, it can be obtained + * by calling H5TBget_field_info() if not already known. * */ H5HL_DLL herr_t H5TBwrite_records(hid_t loc_id, const char *dset_name, hsize_t start, hsize_t nrecords, @@ -254,9 +257,9 @@ H5HL_DLL herr_t H5TBwrite_records(hid_t loc_id, const char *dset_name, hsize_t s * dataset named \p dset_name attached to the object specified * by the identifier \p loc_id. * - * \p type_size can be obtained with \c sizeof() if the data is - * stored in a predefined C struct, otherwise, use H5Tget_size() on - * the compound datatype. + * \p type_size can be obtained with \c sizeof(), if the data is + * stored in a predefined C struct. Otherwise, it can be obtained + * by calling H5TBget_field_info() if not already known. * */ H5HL_DLL herr_t H5TBwrite_fields_name(hid_t loc_id, const char *dset_name, const char *field_names, @@ -292,9 +295,9 @@ H5HL_DLL herr_t H5TBwrite_fields_name(hid_t loc_id, const char *dset_name, const * dataset named \p dset_name attached to the object * specified by the identifier \p loc_id. * - * \p type_size can be obtained with \c sizeof() if the data is - * stored in a predefined C struct, otherwise, use H5Tget_size() on - * the compound datatype. + * \p type_size can be obtained with \c sizeof(), if the data is + * stored in a predefined C struct. Otherwise, it can be obtained + * by calling H5TBget_field_info() if not already known. * */ H5HL_DLL herr_t H5TBwrite_fields_index(hid_t loc_id, const char *dset_name, hsize_t nfields, @@ -332,9 +335,9 @@ H5HL_DLL herr_t H5TBwrite_fields_index(hid_t loc_id, const char *dset_name, hsiz * \p dset_name attached to the object specified by * the identifier \p loc_id. * - * \p type_size can be obtained with \c sizeof() if the predefined C - * structure is available, otherwise, use H5Tget_size() on the - * compound datatype. + * \p dst_size can be obtained with \c sizeof(), if the data is + * stored in a predefined C struct. Otherwise, it can be obtained + * by calling H5TBget_field_info() if not already known. * */ H5HL_DLL herr_t H5TBread_table(hid_t loc_id, const char *dset_name, size_t dst_size, const size_t *dst_offset, @@ -365,9 +368,9 @@ H5HL_DLL herr_t H5TBread_table(hid_t loc_id, const char *dset_name, size_t dst_s * by \p field_names from a dataset named \p dset_name * attached to the object specified by the identifier \p loc_id. * - * \p type_size can be obtained with \c sizeof() if the predefined C - * structure is available, otherwise, use H5Tget_size() on the - * compound datatype. + * \p type_size can be obtained with \c sizeof(), if the data is + * stored in a predefined C struct. Otherwise, it can be obtained + * by calling H5TBget_field_info() if not already known. * */ H5HL_DLL herr_t H5TBread_fields_name(hid_t loc_id, const char *dset_name, const char *field_names, @@ -403,9 +406,9 @@ H5HL_DLL herr_t H5TBread_fields_name(hid_t loc_id, const char *dset_name, const * by \p field_index from a dataset named \p dset_name attached * to the object specified by the identifier \p loc_id. * - * \p type_size can be obtained with \c sizeof() if the predefined C - * structure is available, otherwise, use H5Tget_size() on the - * compound datatype. + * \p type_size can be obtained with \c sizeof(), if the data is + * stored in a predefined C struct. Otherwise, it can be obtained + * by calling H5TBget_field_info() if not already known. * */ H5HL_DLL herr_t H5TBread_fields_index(hid_t loc_id, const char *dset_name, hsize_t nfields, @@ -438,9 +441,9 @@ H5HL_DLL herr_t H5TBread_fields_index(hid_t loc_id, const char *dset_name, hsize * named \p dset_name attached to the object specified by the * identifier \p loc_id. * - * \p type_size can be obtained with \c sizeof() if the predefined C - * structure is available, otherwise, use H5Tget_size() on the - * compound datatype. + * \p type_size can be obtained with \c sizeof(), if the data is + * stored in a predefined C struct. Otherwise, it can be obtained + * by calling H5TBget_field_info() if not already known. * */ H5HL_DLL herr_t H5TBread_records(hid_t loc_id, const char *dset_name, hsize_t start, hsize_t nrecords, From 7dffba170676ff998849d0a8d9e248ae983390db Mon Sep 17 00:00:00 2001 From: Binh-Minh Date: Tue, 26 May 2026 11:46:03 -0400 Subject: [PATCH 08/12] Used a more robust condition when checking EOF --- src/H5Fsuper_cache.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/H5Fsuper_cache.c b/src/H5Fsuper_cache.c index 9043aeb78fb..e18f57aad23 100644 --- a/src/H5Fsuper_cache.c +++ b/src/H5Fsuper_cache.c @@ -627,9 +627,8 @@ H5F__cache_superblock_deserialize(const void *_image, size_t len, void *_udata, HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "root address cannot be 0"); /* Validate addresses against stored_eof. - Skip for multi-file and split drivers which use relative/fractional addresses - that are not actual file offsets. */ - if (udata->f->shared->lf->cls->value != H5_VFD_MULTI) { + Skip for VFDs that don't use absolute file offsets */ + if (H5F_HAS_FEATURE(udata->f, H5FD_FEAT_DEFAULT_VFD_COMPATIBLE)) { if (sblock->base_addr > udata->stored_eof) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "base address exceeds stored EOF"); if (sblock->root_addr >= udata->stored_eof) From 0fdb23c3a423bda4a3d89d33fb441025bda3d929 Mon Sep 17 00:00:00 2001 From: Binh-Minh Date: Tue, 26 May 2026 12:23:54 -0400 Subject: [PATCH 09/12] Corrected incorrect conflict resolving --- hl/src/H5TBpublic.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/hl/src/H5TBpublic.h b/hl/src/H5TBpublic.h index 0e98094b83a..f14c17be191 100644 --- a/hl/src/H5TBpublic.h +++ b/hl/src/H5TBpublic.h @@ -140,10 +140,6 @@ extern "C" { * \param[in] nrecords The number of records * \param[in] type_size The size in bytes of the structure * associated with the table - * \param[in] field_names An array containing the names of - * the fields - * associated with the table; - * This value is obtained with \c sizeof(). * \param[in] field_names An array containing the names of the fields. * Names longer than #HLTB_MAX_FIELD_LEN - 1 characters * are silently truncated when read back by From 032da886f36d1738e13f1112549c1b41c9f4cc2a Mon Sep 17 00:00:00 2001 From: bmribler <39579120+bmribler@users.noreply.github.com> Date: Thu, 4 Jun 2026 01:21:27 -0400 Subject: [PATCH 10/12] Update src/H5Fsuper_cache.c Co-authored-by: Neil Fortner --- src/H5Fsuper_cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/H5Fsuper_cache.c b/src/H5Fsuper_cache.c index e18f57aad23..8f01fbf29ed 100644 --- a/src/H5Fsuper_cache.c +++ b/src/H5Fsuper_cache.c @@ -631,7 +631,7 @@ H5F__cache_superblock_deserialize(const void *_image, size_t len, void *_udata, if (H5F_HAS_FEATURE(udata->f, H5FD_FEAT_DEFAULT_VFD_COMPATIBLE)) { if (sblock->base_addr > udata->stored_eof) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "base address exceeds stored EOF"); - if (sblock->root_addr >= udata->stored_eof) + if (sblock->root_addr >= (udata->stored_eof - sblock->base_addr)) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "root group address beyond stored EOF"); if (H5_addr_defined(sblock->ext_addr) && sblock->ext_addr >= udata->stored_eof) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "superblock extension address exceeds stored EOF"); From 4094ca3bdc369f43d9482e2aa0455f56c1621914 Mon Sep 17 00:00:00 2001 From: bmribler <39579120+bmribler@users.noreply.github.com> Date: Thu, 4 Jun 2026 01:21:45 -0400 Subject: [PATCH 11/12] Update src/H5Fsuper_cache.c Co-authored-by: Neil Fortner --- src/H5Fsuper_cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/H5Fsuper_cache.c b/src/H5Fsuper_cache.c index 8f01fbf29ed..ba688bf8c4b 100644 --- a/src/H5Fsuper_cache.c +++ b/src/H5Fsuper_cache.c @@ -633,7 +633,7 @@ H5F__cache_superblock_deserialize(const void *_image, size_t len, void *_udata, HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "base address exceeds stored EOF"); if (sblock->root_addr >= (udata->stored_eof - sblock->base_addr)) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "root group address beyond stored EOF"); - if (H5_addr_defined(sblock->ext_addr) && sblock->ext_addr >= udata->stored_eof) + if (H5_addr_defined(sblock->ext_addr) && sblock->ext_addr >= (udata->stored_eof - sblock->base_addr)) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "superblock extension address exceeds stored EOF"); } From a280adfd9092eb3b43818f6a4281e8d4505d1042 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 4 Jun 2026 05:31:04 +0000 Subject: [PATCH 12/12] Committing clang-format changes --- src/H5Fsuper_cache.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/H5Fsuper_cache.c b/src/H5Fsuper_cache.c index ba688bf8c4b..ce143e5b4e8 100644 --- a/src/H5Fsuper_cache.c +++ b/src/H5Fsuper_cache.c @@ -633,7 +633,8 @@ H5F__cache_superblock_deserialize(const void *_image, size_t len, void *_udata, HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "base address exceeds stored EOF"); if (sblock->root_addr >= (udata->stored_eof - sblock->base_addr)) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "root group address beyond stored EOF"); - if (H5_addr_defined(sblock->ext_addr) && sblock->ext_addr >= (udata->stored_eof - sblock->base_addr)) + if (H5_addr_defined(sblock->ext_addr) && + sblock->ext_addr >= (udata->stored_eof - sblock->base_addr)) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "superblock extension address exceeds stored EOF"); }