diff options
author | Neil Fortner <nfortne2@hdfgroup.org> | 2008-10-07 03:47:09 (GMT) |
---|---|---|
committer | Neil Fortner <nfortne2@hdfgroup.org> | 2008-10-07 03:47:09 (GMT) |
commit | 7d95527f306abb71d54e19d1deb435c5038b98b4 (patch) | |
tree | 035899c1b4641a7b818ce1a86a8d498d781b3746 /src | |
parent | 2e9986a01ec179e4254622ab2b581631374b30ad (diff) | |
download | hdf5-7d95527f306abb71d54e19d1deb435c5038b98b4.zip hdf5-7d95527f306abb71d54e19d1deb435c5038b98b4.tar.gz hdf5-7d95527f306abb71d54e19d1deb435c5038b98b4.tar.bz2 |
[svn-r15796] Purpose: Close bug #1322
Description: Fixes a possible datatype id leak that could occur during compound
datatype conversion, or more precisely, when unregistering those conversions.
Datatype ids normally registered by the library are no longer visible to the
application via H5Fget_obj_ids and H5Fget_obj_count.
Tested: kagiso, linew, smirom (h5committest)
Diffstat (limited to 'src')
-rw-r--r-- | src/H5Dint.c | 2 | ||||
-rw-r--r-- | src/H5E.c | 2 | ||||
-rw-r--r-- | src/H5F.c | 30 | ||||
-rw-r--r-- | src/H5Fprivate.h | 4 | ||||
-rw-r--r-- | src/H5Gname.c | 6 | ||||
-rw-r--r-- | src/H5I.c | 11 | ||||
-rw-r--r-- | src/H5Iprivate.h | 2 | ||||
-rw-r--r-- | src/H5Oattribute.c | 4 | ||||
-rw-r--r-- | src/H5Pint.c | 4 | ||||
-rw-r--r-- | src/H5T.c | 2 | ||||
-rw-r--r-- | src/H5Tconv.c | 68 |
11 files changed, 83 insertions, 52 deletions
diff --git a/src/H5Dint.c b/src/H5Dint.c index 7a2dcc9..bab3038 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -2570,7 +2570,7 @@ H5D_flush(const H5F_t *f, hid_t dxpl_id, unsigned flags) udata.flags = flags; /* Iterate over all the open datasets */ - H5I_search(H5I_DATASET, H5D_flush_cb, &udata); + H5I_search(H5I_DATASET, H5D_flush_cb, &udata, FALSE); done: FUNC_LEAVE_NOAPI(ret_value) @@ -501,7 +501,7 @@ H5E_unregister_class(H5E_cls_t *cls) /* Iterate over all the messages and delete those in this error class */ /* (Ignore return value, since callback isn't designed to return a particular object) */ - (void)H5I_search(H5I_ERROR_MSG, H5E_close_msg_cb, cls); + (void)H5I_search(H5I_ERROR_MSG, H5E_close_msg_cb, cls, FALSE); /* Free error class structure */ if(cls->cls_name) @@ -64,7 +64,7 @@ typedef struct H5F_olist_t { } H5F_olist_t; /* PRIVATE PROTOTYPES */ -static size_t H5F_get_objects(const H5F_t *f, unsigned types, size_t max_objs, hid_t *obj_id_list); +static size_t H5F_get_objects(const H5F_t *f, unsigned types, size_t max_objs, hid_t *obj_id_list, hbool_t app_ref); static int H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key); static herr_t H5F_get_vfd_handle(const H5F_t *file, hid_t fapl, void** file_handle); static H5F_t *H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, @@ -393,7 +393,7 @@ H5Fget_obj_count(hid_t file_id, unsigned types) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not an object type") /* H5F_get_obj_count doesn't fail */ - ret_value = H5F_get_obj_count(f, types); + ret_value = H5F_get_obj_count(f, types, TRUE); done: FUNC_LEAVE_API(ret_value) @@ -420,14 +420,14 @@ done: *------------------------------------------------------------------------- */ size_t -H5F_get_obj_count(const H5F_t *f, unsigned types) +H5F_get_obj_count(const H5F_t *f, unsigned types, hbool_t app_ref) { size_t ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_obj_count) /* H5F_get_objects doesn't fail */ - ret_value=H5F_get_objects(f, types, 0, NULL); + ret_value=H5F_get_objects(f, types, 0, NULL, app_ref); FUNC_LEAVE_NOAPI(ret_value) } @@ -467,7 +467,7 @@ H5Fget_obj_ids(hid_t file_id, unsigned types, size_t max_objs, hid_t *oid_list) HDassert(oid_list); /* H5F_get_objects doesn't fail */ - ret_value = H5F_get_obj_ids(f, types, max_objs, oid_list); + ret_value = H5F_get_obj_ids(f, types, max_objs, oid_list, TRUE); done: FUNC_LEAVE_API(ret_value) @@ -493,14 +493,14 @@ done: *------------------------------------------------------------------------- */ size_t -H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *oid_list) +H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *oid_list, hbool_t app_ref) { size_t ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_obj_ids) /* H5F_get_objects doesn't fail */ - ret_value = H5F_get_objects(f, types, max_objs, oid_list); + ret_value = H5F_get_objects(f, types, max_objs, oid_list, app_ref); FUNC_LEAVE_NOAPI(ret_value) } @@ -522,7 +522,7 @@ H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *oid_list *--------------------------------------------------------------------------- */ static size_t -H5F_get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_list) +H5F_get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_list, hbool_t app_ref) { size_t obj_id_count=0; /* Number of open IDs */ H5F_olist_t olist; /* Structure to hold search results */ @@ -551,35 +551,35 @@ H5F_get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_ * is found, so don't return failure in this function. */ if(types & H5F_OBJ_FILE) { olist.obj_type = H5I_FILE; - (void)H5I_search(H5I_FILE, H5F_get_objects_cb, &olist); + (void)H5I_search(H5I_FILE, H5F_get_objects_cb, &olist, app_ref); } /* end if */ /* Search through dataset IDs to count number of datasets, and put their * IDs on the object list */ if(types & H5F_OBJ_DATASET) { olist.obj_type = H5I_DATASET; - (void)H5I_search(H5I_DATASET, H5F_get_objects_cb, &olist); + (void)H5I_search(H5I_DATASET, H5F_get_objects_cb, &olist, app_ref); } /* Search through group IDs to count number of groups, and put their * IDs on the object list */ if(types & H5F_OBJ_GROUP) { olist.obj_type = H5I_GROUP; - (void)H5I_search(H5I_GROUP, H5F_get_objects_cb, &olist); + (void)H5I_search(H5I_GROUP, H5F_get_objects_cb, &olist, app_ref); } /* Search through datatype IDs to count number of named datatypes, and put their * IDs on the object list */ if(types & H5F_OBJ_DATATYPE) { olist.obj_type = H5I_DATATYPE; - (void)H5I_search(H5I_DATATYPE, H5F_get_objects_cb, &olist); + (void)H5I_search(H5I_DATATYPE, H5F_get_objects_cb, &olist, app_ref); } /* Search through attribute IDs to count number of attributes, and put their * IDs on the object list */ if(types & H5F_OBJ_ATTR) { olist.obj_type = H5I_ATTR; - (void)H5I_search(H5I_ATTR, H5F_get_objects_cb, &olist); + (void)H5I_search(H5I_ATTR, H5F_get_objects_cb, &olist, app_ref); } /* Set the number of objects currently open */ @@ -1964,7 +1964,7 @@ H5F_try_close(H5F_t *f) unsigned u; /* Local index variable */ /* Get the list of IDs of open dataset, group, & attribute objects */ - while((obj_count = H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_DATASET|H5F_OBJ_GROUP|H5F_OBJ_ATTR, (int)(sizeof(objs)/sizeof(objs[0])), objs)) != 0) { + while((obj_count = H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_DATASET|H5F_OBJ_GROUP|H5F_OBJ_ATTR, (int)(sizeof(objs)/sizeof(objs[0])), objs, FALSE)) != 0) { /* Try to close all the open objects in this file */ for(u = 0; u < obj_count; u++) if(H5I_dec_ref(objs[u], FALSE) < 0) @@ -1976,7 +1976,7 @@ H5F_try_close(H5F_t *f) * they could be using one of the named datatypes and then the * open named datatype ID will get closed twice) */ - while((obj_count = H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_DATATYPE, (int)(sizeof(objs)/sizeof(objs[0])), objs)) != 0) { + while((obj_count = H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_DATATYPE, (int)(sizeof(objs)/sizeof(objs[0])), objs, FALSE)) != 0) { /* Try to close all the open objects in this file */ for(u = 0; u < obj_count; u++) if(H5I_dec_ref(objs[u], FALSE) < 0) diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index cb716fc..d975167 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -471,8 +471,8 @@ H5_DLL unsigned H5F_get_intent(const H5F_t *f); H5_DLL char *H5F_get_extpath(const H5F_t *f); H5_DLL herr_t H5F_get_fileno(const H5F_t *f, unsigned long *filenum); H5_DLL hid_t H5F_get_id(H5F_t *file, hbool_t app_ref); -H5_DLL size_t H5F_get_obj_count(const H5F_t *f, unsigned types); -H5_DLL size_t H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *obj_id_list); +H5_DLL size_t H5F_get_obj_count(const H5F_t *f, unsigned types, hbool_t app_ref); +H5_DLL size_t H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *obj_id_list, hbool_t app_ref); H5_DLL haddr_t H5F_get_base_addr(const H5F_t *f); H5_DLL haddr_t H5F_get_eoa(const H5F_t *f); #ifdef H5_HAVE_PARALLEL diff --git a/src/H5Gname.c b/src/H5Gname.c index d745b87..0634aef 100644 --- a/src/H5Gname.c +++ b/src/H5Gname.c @@ -1009,15 +1009,15 @@ H5G_name_replace(const H5O_link_t *lnk, H5G_names_op_t op, H5F_t *src_file, /* Search through group IDs */ if(search_group) - H5I_search(H5I_GROUP, H5G_name_replace_cb, &names); + H5I_search(H5I_GROUP, H5G_name_replace_cb, &names, FALSE); /* Search through dataset IDs */ if(search_dataset) - H5I_search(H5I_DATASET, H5G_name_replace_cb, &names); + H5I_search(H5I_DATASET, H5G_name_replace_cb, &names, FALSE); /* Search through datatype IDs */ if(search_datatype) - H5I_search(H5I_DATATYPE, H5G_name_replace_cb, &names); + H5I_search(H5I_DATATYPE, H5G_name_replace_cb, &names, FALSE); } /* end if */ } /* end if */ @@ -1877,7 +1877,7 @@ H5Isearch(H5I_type_t type, H5I_search_func_t func, void *key) if(H5I_IS_LIB_TYPE(type)) HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type") - ret_value = H5I_search(type, func, key); + ret_value = H5I_search(type, func, key, TRUE); done: FUNC_LEAVE_API(ret_value) @@ -1905,12 +1905,15 @@ done: * Programmer: Robb Matzke * Friday, February 19, 1999 * - * Modifications: + * Modifications: Neil Fortner + * Wednesday, October 1, 2008 + * Added app_ref parameter. When set to TRUE, the function will only + * operate on ids that have a nonzero application reference count. * *------------------------------------------------------------------------- */ void * -H5I_search(H5I_type_t type, H5I_search_func_t func, void *key) +H5I_search(H5I_type_t type, H5I_search_func_t func, void *key, hbool_t app_ref) { H5I_id_type_t *type_ptr; /*ptr to the type */ void *ret_value = NULL; /*return value */ @@ -1935,7 +1938,7 @@ H5I_search(H5I_type_t type, H5I_search_func_t func, void *key) id_ptr = type_ptr->id_list[i]; while(id_ptr) { next_id = id_ptr->next; /* Protect against ID being deleted in callback */ - if((*func)(id_ptr->obj_ptr, id_ptr->id, key)) + if((!app_ref || id_ptr->app_count) && (*func)(id_ptr->obj_ptr, id_ptr->id, key)) HGOTO_DONE(id_ptr->obj_ptr); /*found the item*/ id_ptr = next_id; } /* end while */ diff --git a/src/H5Iprivate.h b/src/H5Iprivate.h index f06bf79..0923af7 100644 --- a/src/H5Iprivate.h +++ b/src/H5Iprivate.h @@ -61,7 +61,7 @@ H5_DLL H5I_type_t H5I_get_type(hid_t id); H5_DLL hid_t H5I_get_file_id(hid_t obj_id, hbool_t app_ref); H5_DLL void *H5I_remove(hid_t id); H5_DLL void *H5I_remove_verify(hid_t id, H5I_type_t id_type); -H5_DLL void *H5I_search(H5I_type_t type, H5I_search_func_t func, void *key); +H5_DLL void *H5I_search(H5I_type_t type, H5I_search_func_t func, void *key, hbool_t app_ref); H5_DLL int H5I_get_ref(hid_t id, hbool_t app_ref); H5_DLL int H5I_inc_ref(hid_t id, hbool_t app_ref); H5_DLL int H5I_dec_ref(hid_t id, hbool_t app_ref); diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c index 71c59f3..846d2ec 100644 --- a/src/H5Oattribute.c +++ b/src/H5Oattribute.c @@ -684,7 +684,7 @@ htri_t H5O_attr_find_opened_attr(const H5O_loc_t *loc, H5A_t **attr, const char* HGOTO_ERROR(H5E_ATTR, H5E_BADVALUE, FAIL, "can't get file serial number") /* Count all opened attributes */ - if((num_open_attr = H5F_get_obj_count(loc->file, H5F_OBJ_ATTR | H5F_OBJ_LOCAL)) < 0) + if((num_open_attr = H5F_get_obj_count(loc->file, H5F_OBJ_ATTR | H5F_OBJ_LOCAL, FALSE)) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "can't get number of opened attributes") /* Find out whether the attribute has been opened */ @@ -692,7 +692,7 @@ htri_t H5O_attr_find_opened_attr(const H5O_loc_t *loc, H5A_t **attr, const char* attr_id_list = (hid_t*)H5MM_malloc(num_open_attr*sizeof(hid_t)); /* Retrieve the IDs of all opened attributes */ - if(H5F_get_obj_ids(loc->file, H5F_OBJ_ATTR | H5F_OBJ_LOCAL, num_open_attr, attr_id_list) < 0) + if(H5F_get_obj_ids(loc->file, H5F_OBJ_ATTR | H5F_OBJ_LOCAL, num_open_attr, attr_id_list, FALSE) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't IDs of opened attributes") for(i=0; i<num_open_attr; i++) { diff --git a/src/H5Pint.c b/src/H5Pint.c index a7bad06..e522010 100644 --- a/src/H5Pint.c +++ b/src/H5Pint.c @@ -4348,7 +4348,7 @@ H5P_open_class_path(const char *path) check_info.name=curr_name; /* Find the class with this name & parent by iterating over the open classes */ - if(NULL == (curr_class = (H5P_genclass_t *)H5I_search(H5I_GENPROP_CLS, H5P_check_class, &check_info))) + if(NULL == (curr_class = (H5P_genclass_t *)H5I_search(H5I_GENPROP_CLS, H5P_check_class, &check_info, FALSE))) HGOTO_ERROR (H5E_PLIST, H5E_NOTFOUND, NULL, "can't locate class"); /* Advance the pointer in the path to the start of the next component */ @@ -4362,7 +4362,7 @@ H5P_open_class_path(const char *path) check_info.name = curr_name; /* Find the class with this name & parent by iterating over the open classes */ - if(NULL == (curr_class = (H5P_genclass_t *)H5I_search(H5I_GENPROP_CLS, H5P_check_class, &check_info))) + if(NULL == (curr_class = (H5P_genclass_t *)H5I_search(H5I_GENPROP_CLS, H5P_check_class, &check_info, FALSE))) HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, NULL, "can't locate class") /* Copy it */ @@ -1449,7 +1449,7 @@ H5T_term_interface(void) H5T_g.nsoft = H5T_g.asoft = 0; /* Unlock all datatypes, then free them */ - H5I_search (H5I_DATATYPE, H5T_unlock_cb, NULL); + H5I_search (H5I_DATATYPE, H5T_unlock_cb, NULL, FALSE); H5I_dec_type_ref(H5I_DATATYPE); /* Reset all the datatype IDs */ diff --git a/src/H5Tconv.c b/src/H5Tconv.c index b02e72a..05277a8 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -884,6 +884,7 @@ typedef struct H5T_conv_struct_t { hid_t *dst_memb_id; /*destination member type ID's */ H5T_path_t **memb_path; /*conversion path for each member */ H5T_subset_info_t subset_info; /*info related to compound subsets */ + unsigned src_nmembs; /*needed by free function */ } H5T_conv_struct_t; /* Conversion data for H5T_conv_enum() */ @@ -1751,6 +1752,48 @@ done: /*------------------------------------------------------------------------- + * Function: H5T_conv_struct_free + * + * Purpose: Free the private data structure used by the compound + * conversion functions. + * + * Return: The result of H5MM_xfree(priv) (NULL) + * + * Programmer: Neil Fortner + * Wednesday, October 1, 2008 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static H5T_conv_struct_t * +H5T_conv_struct_free(H5T_conv_struct_t *priv) +{ + int *src2dst = priv->src2dst; + hid_t *src_memb_id = priv->src_memb_id, + *dst_memb_id = priv->dst_memb_id; + unsigned i; + int status; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_conv_struct_free) + + for (i=0; i<priv->src_nmembs; i++) + if (src2dst[i] >= 0) { + status = H5I_dec_ref(src_memb_id[i], FALSE); + HDassert(status >= 0); + status = H5I_dec_ref(dst_memb_id[src2dst[i]], FALSE); + HDassert(status >= 0); + } + + H5MM_xfree(src2dst); + H5MM_xfree(src_memb_id); + H5MM_xfree(dst_memb_id); + H5MM_xfree(priv->memb_path); + FUNC_LEAVE_NOAPI(H5MM_xfree(priv)); +} + + +/*------------------------------------------------------------------------- * Function: H5T_conv_struct_init * * Purpose: Initialize the `priv' field of `cdata' with conversion @@ -1824,6 +1867,7 @@ H5T_conv_struct_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata, hid_t dxpl_id) NULL == (priv->dst_memb_id = H5MM_malloc(dst_nmembs * sizeof(hid_t)))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") src2dst = priv->src2dst; + priv->src_nmembs = src_nmembs; /* The flag of special optimization to indicate if source members and destination * members are a subset of each other. Initialize it to FALSE */ @@ -1885,11 +1929,7 @@ H5T_conv_struct_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata, hid_t dxpl_id) H5T_path_t *tpath = H5T_path_find(src->shared->u.compnd.memb[i].type, dst->shared->u.compnd.memb[src2dst[i]].type, NULL, NULL, dxpl_id, FALSE); if(NULL == (priv->memb_path[i] = tpath)) { - H5MM_xfree(priv->src2dst); - H5MM_xfree(priv->src_memb_id); - H5MM_xfree(priv->dst_memb_id); - H5MM_xfree(priv->memb_path); - cdata->priv = priv = H5MM_xfree (priv); + cdata->priv = priv = H5T_conv_struct_free(priv); HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unable to convert member datatype") } /* end if */ } /* end if */ @@ -2073,11 +2113,7 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, /* * Free the private conversion data. */ - H5MM_xfree(priv->src2dst); - H5MM_xfree(priv->src_memb_id); - H5MM_xfree(priv->dst_memb_id); - H5MM_xfree(priv->memb_path); - cdata->priv = priv = H5MM_xfree (priv); + cdata->priv = priv = H5T_conv_struct_free(priv); break; case H5T_CONV_CONV: @@ -2346,11 +2382,7 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, if (dst_memb->size > src_memb->size) { offset -= src_memb->size; if (dst_memb->size > src->shared->size-offset) { - H5MM_xfree(priv->src2dst); - H5MM_xfree(priv->src_memb_id); - H5MM_xfree(priv->dst_memb_id); - H5MM_xfree(priv->memb_path); - cdata->priv = priv = H5MM_xfree (priv); + cdata->priv = priv = H5T_conv_struct_free(priv); HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "convertion is unsupported by this function"); } } @@ -2363,11 +2395,7 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, * Free the private conversion data. */ priv = (H5T_conv_struct_t *)(cdata->priv); - H5MM_xfree(priv->src2dst); - H5MM_xfree(priv->src_memb_id); - H5MM_xfree(priv->dst_memb_id); - H5MM_xfree(priv->memb_path); - cdata->priv = priv = H5MM_xfree (priv); + cdata->priv = priv = H5T_conv_struct_free(priv); break; case H5T_CONV_CONV: |