summaryrefslogtreecommitdiffstats
path: root/src
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
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')
-rw-r--r--src/H5T.c37
-rw-r--r--src/H5Tcompound.c6
2 files changed, 26 insertions, 17 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:
diff --git a/src/H5Tcompound.c b/src/H5Tcompound.c
index 8ba3d69..201d3ae 100644
--- a/src/H5Tcompound.c
+++ b/src/H5Tcompound.c
@@ -469,10 +469,12 @@ H5T__insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member)
/* Add member to end of member array */
idx = parent->shared->u.compnd.nmembs;
- parent->shared->u.compnd.memb[idx].name = H5MM_xstrdup(name);
parent->shared->u.compnd.memb[idx].offset = offset;
parent->shared->u.compnd.memb[idx].size = total_size;
- parent->shared->u.compnd.memb[idx].type = H5T_copy(member, H5T_COPY_ALL);
+ if (NULL == (parent->shared->u.compnd.memb[idx].name = H5MM_xstrdup(name)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "couldn't duplicate name string")
+ if (NULL == (parent->shared->u.compnd.memb[idx].type = H5T_copy(member, H5T_COPY_ALL)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "couldn't copy datatype")
parent->shared->u.compnd.sorted = H5T_SORT_NONE;
parent->shared->u.compnd.nmembs++;