Skip to content

Commit

Permalink
Avoid truncating at null byte when copying to std::string (#3083)
Browse files Browse the repository at this point in the history

---------

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
mkitti and github-actions[bot] authored Jul 16, 2023
1 parent 305ac88 commit 426a7f8
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 1 deletion.
2 changes: 1 addition & 1 deletion c++/src/H5DataSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down
78 changes: 78 additions & 0 deletions c++/test/dsets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1363,6 +1363,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
*
Expand Down Expand Up @@ -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();
Expand Down
7 changes: 7 additions & 0 deletions release_docs/RELEASE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,13 @@ Bug Fixes since HDF5-1.14.0 release

Fixes GitHub issue #2432

- Reading a H5std_string (std::string) via a C++ DataSet previously
truncated the string at the first null byte as if reading a C string.
Fixed length datasets are now read into H5std_string as a fixed length
string of the appropriate size. Variable length datasets will still be
truncated at the first null byte.

Fixes Github issue #3034

Java Library
------------
Expand Down

0 comments on commit 426a7f8

Please sign in to comment.