summaryrefslogtreecommitdiffstats
path: root/c++
diff options
context:
space:
mode:
authorMark Kittisopikul <mkitti@users.noreply.github.com>2023-07-16 04:31:57 (GMT)
committerGitHub <noreply@github.com>2023-07-16 04:31:57 (GMT)
commit426a7f82f6ce4d75ec8bfd30d1fa198c49efaa97 (patch)
treeb6c081097820ecf75c62fca196ab6e85f8e81cb8 /c++
parent305ac8886566968ae58ba771e0ae2ba6434ac9f0 (diff)
downloadhdf5-426a7f82f6ce4d75ec8bfd30d1fa198c49efaa97.zip
hdf5-426a7f82f6ce4d75ec8bfd30d1fa198c49efaa97.tar.gz
hdf5-426a7f82f6ce4d75ec8bfd30d1fa198c49efaa97.tar.bz2
Avoid truncating at null byte when copying to std::string (#3083)
--------- Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Diffstat (limited to 'c++')
-rw-r--r--c++/src/H5DataSet.cpp2
-rw-r--r--c++/test/dsets.cpp78
2 files changed, 79 insertions, 1 deletions
diff --git a/c++/src/H5DataSet.cpp b/c++/src/H5DataSet.cpp
index 7d19a6d..40b40f2 100644
--- a/c++/src/H5DataSet.cpp
+++ b/c++/src/H5DataSet.cpp
@@ -729,7 +729,7 @@ DataSet::p_read_fixed_len(const hid_t mem_type_id, const hid_t mem_space_id, con
}
// Get string from the C char* and release resource allocated locally
- strg = strg_C;
+ strg = H5std_string(strg_C, data_size);
delete[] strg_C;
}
}
diff --git a/c++/test/dsets.cpp b/c++/test/dsets.cpp
index e1cee97..9de6db1 100644
--- a/c++/test/dsets.cpp
+++ b/c++/test/dsets.cpp
@@ -1364,6 +1364,83 @@ test_operator(H5File &file)
} // test_operator
/*-------------------------------------------------------------------------
+ * Function: test_read_string
+ *
+ * Purpose Tests DataSet::read(H5std_string ...)
+ *
+ * Return Success: 0
+ *
+ * Failure: -1
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+test_read_string(H5File &file)
+{
+ SUBTEST("DataSet::read(H5std_string)");
+ try {
+ const H5std_string DATASET_NAME("test_read_string");
+ const unsigned long NX = 8;
+ const char DATA[NX] = {'a', 0, 0, 0, 0, 0, 0, 'Z'};
+ const H5std_string EXPECTED_STR = H5std_string(DATA, NX);
+ H5std_string str;
+
+ /*
+ * Write characters with internal null bytes
+ */
+
+ PredType datatype(PredType::NATIVE_INT8);
+ hsize_t dimsf[RANK1] = {NX};
+ DataSpace dataspace(RANK1, dimsf);
+ DataSet dataset = file.createDataSet(DATASET_NAME, datatype, dataspace);
+ dataset.write(DATA, datatype);
+ dataset.close();
+
+ /*
+ * Read characters with internal null bytes as a string.
+ * The read std::string should NOT be truncated at the first null byte.
+ */
+
+ dataset = file.openDataSet(DATASET_NAME);
+ dataset.read(str, datatype);
+ dataset.close();
+ verify_val(str.length(), NX, "test_read_string", __LINE__, __FILE__);
+ verify_val(str, EXPECTED_STR, "test_read_string", __LINE__, __FILE__);
+
+ /*
+ * Write the H5std_string back to the dataset.
+ */
+ dataset = file.openDataSet(DATASET_NAME);
+ dataset.write(str, datatype);
+ dataset.close();
+
+ /*
+ * Read characters with internal null bytes as a string, after rewrite.
+ * The read std::string should NOT be truncated at the first null byte.
+ */
+
+ dataset = file.openDataSet(DATASET_NAME);
+ dataset.read(str, datatype);
+ dataset.close();
+ verify_val(str.length(), NX, "test_read_string", __LINE__, __FILE__);
+ verify_val(str, EXPECTED_STR, "test_read_string", __LINE__, __FILE__);
+
+ /*
+ * Success
+ */
+ PASSED();
+ return 0;
+ }
+ catch (Exception &E) {
+ // H5_FAILED should probably be invoked before verify_val
+ H5_FAILED();
+ issue_fail_msg("test_read_string", __LINE__, __FILE__);
+
+ // clean up and return with failure
+ return -1;
+ }
+} // test_read_string
+
+/*-------------------------------------------------------------------------
* Function: test_dset
*
* Purpose Tests the dataset interface (H5D)
@@ -1403,6 +1480,7 @@ test_dset()
nerrors += test_virtual() < 0 ? 1 : 0;
nerrors += test_operator(file) < 0 ? 1 : 0;
nerrors += test_chunk_cache(fapl) < 0 ? 1 : 0;
+ nerrors += test_read_string(file) < 0 ? 1 : 0;
// Close group "emit diagnostics".
grp.close();