summaryrefslogtreecommitdiffstats
path: root/src/H5T.c
diff options
context:
space:
mode:
authorDana Robinson <43805+derobins@users.noreply.github.com>2023-06-12 19:14:25 (GMT)
committerGitHub <noreply@github.com>2023-06-12 19:14:25 (GMT)
commita1a9526b1438b5275e15e46b2bd890e94b88231f (patch)
treebb6c5b1792828299228e4a606c098c4721ed0b3a /src/H5T.c
parent37990e63c4751493f9c2af8c46e0c230a49e286f (diff)
downloadhdf5-a1a9526b1438b5275e15e46b2bd890e94b88231f.zip
hdf5-a1a9526b1438b5275e15e46b2bd890e94b88231f.tar.gz
hdf5-a1a9526b1438b5275e15e46b2bd890e94b88231f.tar.bz2
Address memory issues when copying empty enums (#3088)
When copying an empty enum type (including implicitly, as when an enum is contained in a compound type), the library would allocate 0-size blocks of memory and attempt to memcpy 0 bytes from NULL pointers, which are undefined behavior. In debug mode, the library would raise an assert in H5MM. The library now avoid undefined memory operations when copying empty enum types and a test that copies empty enums has been added.
Diffstat (limited to 'src/H5T.c')
-rw-r--r--src/H5T.c37
1 files changed, 22 insertions, 15 deletions
diff --git a/src/H5T.c b/src/H5T.c
index e2debd4..27c7a60 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -3623,21 +3623,28 @@ H5T__complete_copy(H5T_t *new_dt, const H5T_t *old_dt, H5T_shared_t *reopened_fo
* of each new member with copied values. That is, H5T_copy() is a
* deep copy.
*/
- if (NULL == (new_dt->shared->u.enumer.name =
- H5MM_malloc(new_dt->shared->u.enumer.nalloc * sizeof(char *))))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "enam name array memory allocation failed")
- if (NULL == (new_dt->shared->u.enumer.value =
- H5MM_malloc(new_dt->shared->u.enumer.nalloc * new_dt->shared->size)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL,
- "enam value array memory allocation failed")
- H5MM_memcpy(new_dt->shared->u.enumer.value, old_dt->shared->u.enumer.value,
- new_dt->shared->u.enumer.nmembs * new_dt->shared->size);
- for (i = 0; i < new_dt->shared->u.enumer.nmembs; i++) {
- if (NULL == (s = H5MM_xstrdup(old_dt->shared->u.enumer.name[i])))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL,
- "can't copy string for enum value's name")
- new_dt->shared->u.enumer.name[i] = s;
- } /* end for */
+ if (old_dt->shared->u.enumer.nalloc > 0) {
+ if (NULL == (new_dt->shared->u.enumer.name =
+ H5MM_malloc(new_dt->shared->u.enumer.nalloc * sizeof(char *))))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL,
+ "enam name array memory allocation failed")
+ if (NULL == (new_dt->shared->u.enumer.value =
+ H5MM_malloc(new_dt->shared->u.enumer.nalloc * new_dt->shared->size)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL,
+ "enam value array memory allocation failed")
+ H5MM_memcpy(new_dt->shared->u.enumer.value, old_dt->shared->u.enumer.value,
+ new_dt->shared->u.enumer.nmembs * new_dt->shared->size);
+ for (i = 0; i < new_dt->shared->u.enumer.nmembs; i++) {
+ if (NULL == (s = H5MM_xstrdup(old_dt->shared->u.enumer.name[i])))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL,
+ "can't copy string for enum value's name")
+ new_dt->shared->u.enumer.name[i] = s;
+ }
+ }
+ else {
+ /* Empty enum */
+ HDmemset(&new_dt->shared->u.enumer, 0, sizeof(H5T_enum_t));
+ }
break;
case H5T_VLEN: