From a8b7a996da6e8d44e8953655ac90d57721767110 Mon Sep 17 00:00:00 2001 From: "Christopher M. Pierce" Date: Thu, 17 Sep 2026 01:04:18 -0700 Subject: [PATCH 1/2] add test for iteration open failure --- tests/test_write.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/test_write.c b/tests/test_write.c index e760aa0..53bfb5e 100644 --- a/tests/test_write.c +++ b/tests/test_write.c @@ -1009,6 +1009,29 @@ void test_invalid_pattern_ambiguous(void) { TEST_ASSERT_NOT_EQUAL(PMD_SUCCESS, result); } +/** + * Test: %T filename pattern that matches a file HDF5 cannot open fails + */ +void test_pattern_open_invalid_hdf5_fails(void) { + pmd_series *series; + pmd_status result; + + /* Create a file whose name matches bad_%T.h5 but is not HDF5 */ + FILE *bad_file = fopen(TEST_TEMP_DIR "/bad_0.h5", "wb"); + TEST_ASSERT_NOT_NULL(bad_file); + TEST_ASSERT_TRUE(fputs("not an hdf5 file\n", bad_file) >= 0); + TEST_ASSERT_EQUAL_INT(0, fclose(bad_file)); + + /* Read-only must be checked first: RDWR writes root attributes during open */ + result = pmd_open_series(TEST_TEMP_DIR "/bad_%T.h5", &series, PMD_RDONLY); + TEST_ASSERT_EQUAL_INT(PMD_ERROR_HDF5, result); + TEST_ASSERT_NULL(series); + + result = pmd_open_series(TEST_TEMP_DIR "/bad_%T.h5", &series, PMD_RDWR); + TEST_ASSERT_EQUAL_INT(PMD_ERROR_HDF5, result); + TEST_ASSERT_NULL(series); +} + /** * Test: Various valid file-based iteration patterns * Tests multiple pattern formats in a parameterized style @@ -2708,6 +2731,7 @@ int main(void) { RUN_TEST(test_write_nonconsecutive_iterations_file_based); RUN_TEST(test_write_fails_no_parent_directory); RUN_TEST(test_invalid_pattern_ambiguous); + RUN_TEST(test_pattern_open_invalid_hdf5_fails); RUN_TEST(test_valid_filebased_patterns); RUN_TEST(test_truncate_deletes_existing_files); RUN_TEST(test_filebased_fails_parent_before_t_missing); From 47f406e5b5933e96e348ae21139df572fc9d88f9 Mon Sep 17 00:00:00 2001 From: "Christopher M. Pierce" Date: Thu, 17 Sep 2026 01:06:46 -0700 Subject: [PATCH 2/2] check for open failure --- parcel.h | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/parcel.h b/parcel.h index b4140bf..6da108d 100644 --- a/parcel.h +++ b/parcel.h @@ -1942,17 +1942,22 @@ pmd_status pmd_open_series(const char *filename, pmd_series **series_out, pmd_ac // Open the HDF5 file file_id = H5Fopen(iter_filename, H5F_ACC_RDONLY, H5P_DEFAULT); - if (file_id >= 0) { - /* Read metadata from the opened file */ - status = read_series_metadata_from_file(file_id, series, filename); - if (status != PMD_SUCCESS) { - goto cleanup; - } + if (file_id < 0) { + pmd_log(PMD_LOG_ERROR, "Failed to open '%s' (matched pattern '%s') as HDF5", + iter_filename, filename); + status = PMD_ERROR_HDF5; + goto cleanup; + } - /* Close file since we will not store for file-based mode */ - H5Fclose(file_id); - file_id = -1; + /* Read metadata from the opened file */ + status = read_series_metadata_from_file(file_id, series, filename); + if (status != PMD_SUCCESS) { + goto cleanup; } + + /* Close file since we will not store for file-based mode */ + H5Fclose(file_id); + file_id = -1; } /* Set directory from pattern if not already set */