Skip to content

Commit

Permalink
Expand check for variable-length or reference types when clearing dat…
Browse files Browse the repository at this point in the history
…atype conversion paths (HDFGroup#4085)

When clearing out datatype conversion paths involving variable-length or reference datatypes
on file close, also check for these datatypes inside compound or array datatypes
  • Loading branch information
jhendersonHDF authored and lrknox committed Mar 21, 2024
1 parent 5504374 commit 4115059
Show file tree
Hide file tree
Showing 2 changed files with 225 additions and 60 deletions.
90 changes: 78 additions & 12 deletions src/H5T.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,12 +350,13 @@ static H5T_path_t *H5T__path_find_real(const H5T_t *src, const H5T_t *dst, const
H5T_conv_func_t *conv);
static bool H5T_path_match(H5T_path_t *path, H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst,
H5VL_object_t *owned_vol_obj, H5T_conv_t func);
static bool H5T__detect_vlen_ref(const H5T_t *dt);
static H5T_t *H5T__initiate_copy(const H5T_t *old_dt);
static H5T_t *H5T__copy_transient(H5T_t *old_dt);
static H5T_t *H5T__copy_all(H5T_t *old_dt);
static herr_t H5T__complete_copy(H5T_t *new_dt, const H5T_t *old_dt, H5T_shared_t *reopened_fo,
bool set_memory_type, H5T_copy_func_t copyfn);
static bool H5T_path_match_find_type_with_volobj(const H5T_t *datatype, const H5VL_object_t *owned_vol_obj);
static bool H5T__detect_vlen_ref(const H5T_t *dt);
static H5T_t *H5T__initiate_copy(const H5T_t *old_dt);
static H5T_t *H5T__copy_transient(H5T_t *old_dt);
static H5T_t *H5T__copy_all(H5T_t *old_dt);
static herr_t H5T__complete_copy(H5T_t *new_dt, const H5T_t *old_dt, H5T_shared_t *reopened_fo,
bool set_memory_type, H5T_copy_func_t copyfn);

/*****************************/
/* Library Private Variables */
Expand Down Expand Up @@ -5182,10 +5183,10 @@ H5T_path_match(H5T_path_t *path, H5T_pers_t pers, const char *name, H5T_t *src,
{
bool ret_value = true;

assert(path);

FUNC_ENTER_NOAPI_NOINIT_NOERR

assert(path);

if (
/* Check that the specified conversion function persistence matches */
((H5T_PERS_SOFT == pers && path->is_hard) || (H5T_PERS_HARD == pers && !path->is_hard)) ||
Expand All @@ -5200,11 +5201,12 @@ H5T_path_match(H5T_path_t *path, H5T_pers_t pers, const char *name, H5T_t *src,
(src && H5T_cmp(src, path->src, false)) || (dst && H5T_cmp(dst, path->dst, false)) ||

/*
* Check that the specified VOL object matches the VOL object
* in the conversion path
* Check that the specified VOL object pointer matches the `owned_vol_obj`
* field for either the source datatype or destination datatype in the
* conversion path
*/
(owned_vol_obj && (owned_vol_obj != path->src->shared->owned_vol_obj) &&
(owned_vol_obj != path->dst->shared->owned_vol_obj)) ||
(owned_vol_obj && (H5T_path_match_find_type_with_volobj(path->src, owned_vol_obj) == false) &&
(H5T_path_match_find_type_with_volobj(path->dst, owned_vol_obj) == false)) ||

/* Check that the specified conversion function matches */
(func && func != path->conv.u.app_func))
Expand All @@ -5213,6 +5215,70 @@ H5T_path_match(H5T_path_t *path, H5T_pers_t pers, const char *name, H5T_t *src,
FUNC_LEAVE_NOAPI(ret_value)
} /* H5T_path_match() */

/*-------------------------------------------------------------------------
* Function: H5T_path_match_find_type_with_volobj
*
* Purpose: Helper function to determine whether a datatype is or
* contains a datatype that has a VOL object pointer matching
* the given VOL object pointer.
*
* Return: true/false (can't fail)
*
*-------------------------------------------------------------------------
*/
static bool
H5T_path_match_find_type_with_volobj(const H5T_t *datatype, const H5VL_object_t *owned_vol_obj)
{
bool ret_value = false;

FUNC_ENTER_NOAPI_NOINIT_NOERR

assert(datatype);
assert(owned_vol_obj);

ret_value = (datatype->shared->owned_vol_obj == owned_vol_obj);
if (!ret_value) {
switch (datatype->shared->type) {
case H5T_COMPOUND:
for (unsigned i = 0; i < datatype->shared->u.compnd.nmembs; i++) {
if (ret_value)
break;
ret_value = H5T_path_match_find_type_with_volobj(datatype->shared->u.compnd.memb[i].type,
owned_vol_obj);
}
break;

case H5T_VLEN:
/* Should be an error if no parent, but simplify logic for a true/false return value */
if (datatype->shared->parent)
ret_value = H5T_path_match_find_type_with_volobj(datatype->shared->parent, owned_vol_obj);
break;

case H5T_ARRAY:
/* Should be an error if no parent, but simplify logic for a true/false return value */
if (datatype->shared->parent)
ret_value = H5T_path_match_find_type_with_volobj(datatype->shared->parent, owned_vol_obj);
break;

case H5T_INTEGER:
case H5T_FLOAT:
case H5T_TIME:
case H5T_STRING:
case H5T_BITFIELD:
case H5T_OPAQUE:
case H5T_REFERENCE: /* Should have been determined by above check */
case H5T_ENUM:
case H5T_NO_CLASS: /* Error value, but simplify logic for a true/false return value */
case H5T_NCLASSES: /* Error value, but simplify logic for a true/false return value */
default:
ret_value = false;
break;
}
}

FUNC_LEAVE_NOAPI(ret_value)
}

/*-------------------------------------------------------------------------
* Function: H5T_path_noop
*
Expand Down
Loading

0 comments on commit 4115059

Please sign in to comment.