diff options
27 files changed, 883 insertions, 514 deletions
@@ -909,6 +909,7 @@ ./test/atomic_reader.c ./test/atomic_writer.c ./test/bad_compound.h5 +./test/bad_offset.h5 ./test/be_data.h5 ./test/be_extlink1.h5 ./test/be_extlink2.h5 @@ -972,6 +973,7 @@ ./test/fsm_aggr_persist.h5 ./test/genall5.c ./test/genall5.h +./test/gen_bad_offset.c ./test/gen_bad_ohdr.c ./test/gen_bad_compound.c ./test/gen_bogus.c @@ -1714,6 +1716,9 @@ ./tools/testfiles/tgrp_comments.ls ./tools/testfiles/tgrp_comments.ddl ./tools/testfiles/tgrp_comments.h5 +./tools/testfiles/tgrpnullspace.h5 +./tools/testfiles/tgrpnullspace.ddl +./tools/testfiles/tgrpnullspace.ls ./tools/testfiles/thlink-1.ddl ./tools/testfiles/thlink-2.ddl ./tools/testfiles/thlink-3.ddl @@ -1769,6 +1774,7 @@ ./tools/testfiles/tno-subset.h5 ./tools/testfiles/tno-subset.ddl ./tools/testfiles/tnullspace.h5 +./tools/testfiles/tnullspace.h5.xml ./tools/testfiles/tnullspace.ddl ./tools/testfiles/tobjref.h5 ./tools/testfiles/topaque.h5 diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 2dbe7e9..3f9e9c0 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -147,6 +147,16 @@ Bug Fixes since HDF5-1.10.1 release Tools ----- + - h5ls + + h5ls generated error on stack when it encountered a H5S_NULL + dataspace. + + Adding checks for H5S_NULL before calling H5Sis_simple (located + in the h5tools_dump_mem function) fixed the issue. + + (ADB - 2017/08/17, HDFFV-10188) + - h5dump h5dump segfaulted on output of XML file. diff --git a/src/H5Gent.c b/src/H5Gent.c index b781fae..7987850 100644 --- a/src/H5Gent.c +++ b/src/H5Gent.c @@ -541,8 +541,8 @@ herr_t H5G__ent_debug(const H5G_entry_t *ent, FILE *stream, int indent, int fwidth, const H5HL_t *heap) { - const char *lval = NULL; - int nested_indent, nested_fwidth; + const char *lval = NULL; + int nested_indent, nested_fwidth; FUNC_ENTER_PACKAGE_NOERR @@ -551,14 +551,14 @@ H5G__ent_debug(const H5G_entry_t *ent, FILE *stream, int indent, int fwidth, nested_fwidth = MAX(0, fwidth - 3); HDfprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth, - "Name offset into private heap:", - (unsigned long) (ent->name_off)); + "Name offset into private heap:", + (unsigned long) (ent->name_off)); HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth, - "Object header address:", ent->header); + "Object header address:", ent->header); HDfprintf(stream, "%*s%-*s ", indent, "", fwidth, - "Cache info type:"); + "Cache info type:"); switch(ent->type) { case H5G_NOTHING_CACHED: HDfprintf(stream, "Nothing Cached\n"); @@ -581,13 +581,13 @@ H5G__ent_debug(const H5G_entry_t *ent, FILE *stream, int indent, int fwidth, HDfprintf(stream, "%*s%-*s\n", indent, "", fwidth, "Cached information:"); HDfprintf(stream, "%*s%-*s %lu\n", nested_indent, "", nested_fwidth, - "Link value offset:", - (unsigned long)(ent->cache.slink.lval_offset)); + "Link value offset:", + (unsigned long)(ent->cache.slink.lval_offset)); if(heap) { lval = (const char *)H5HL_offset_into(heap, ent->cache.slink.lval_offset); HDfprintf(stream, "%*s%-*s %s\n", nested_indent, "", nested_fwidth, - "Link value:", - lval); + "Link value:", + (lval == NULL) ? "" : lval); } /* end if */ else HDfprintf(stream, "%*s%-*s\n", nested_indent, "", nested_fwidth, "Warning: Invalid heap address given, name not displayed!"); diff --git a/src/H5Glink.c b/src/H5Glink.c index d246ee7..e199f89 100644 --- a/src/H5Glink.c +++ b/src/H5Glink.c @@ -224,7 +224,10 @@ herr_t H5G__ent_to_link(H5O_link_t *lnk, const H5HL_t *heap, const H5G_entry_t *ent, const char *name) { - FUNC_ENTER_PACKAGE_NOERR + hbool_t dup_soft = FALSE; /* xstrdup the symbolic link name or not */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE /* check arguments */ HDassert(lnk); @@ -236,18 +239,21 @@ H5G__ent_to_link(H5O_link_t *lnk, const H5HL_t *heap, lnk->cset = H5F_DEFAULT_CSET; lnk->corder = 0; lnk->corder_valid = FALSE; /* Creation order not valid for this link */ - lnk->name = H5MM_xstrdup(name); - HDassert(lnk->name); + if((lnk->name = H5MM_xstrdup(name)) == NULL) + HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to duplicate link name") /* Object is a symbolic or hard link */ if(ent->type == H5G_CACHED_SLINK) { const char *s; /* Pointer to link value */ - s = (const char *)H5HL_offset_into(heap, ent->cache.slink.lval_offset); - HDassert(s); + if((s = (const char *)H5HL_offset_into(heap, ent->cache.slink.lval_offset)) == NULL) + HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to get symbolic link name") /* Copy the link value */ - lnk->u.soft.name = H5MM_xstrdup(s); + if((lnk->u.soft.name = H5MM_xstrdup(s)) == NULL) + HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to duplicate symbolic link name") + + dup_soft = TRUE; /* Set link type */ lnk->type = H5L_TYPE_SOFT; @@ -260,7 +266,14 @@ H5G__ent_to_link(H5O_link_t *lnk, const H5HL_t *heap, lnk->type = H5L_TYPE_HARD; } /* end else */ - FUNC_LEAVE_NOAPI(SUCCEED) +done: + if(ret_value < 0) { + if(lnk->name) + H5MM_xfree(lnk->name); + if(ent->type == H5G_CACHED_SLINK && dup_soft) + H5MM_xfree(lnk->u.soft.name); + } + FUNC_LEAVE_NOAPI(ret_value) } /* end H5G__ent_to_link() */ diff --git a/src/H5Gnode.c b/src/H5Gnode.c index 20924ee..76e2c4b 100644 --- a/src/H5Gnode.c +++ b/src/H5Gnode.c @@ -13,14 +13,14 @@ /*------------------------------------------------------------------------- * - * Created: H5Gnode.c - * Jun 26 1997 - * Robb Matzke <matzke@llnl.gov> + * Created: H5Gnode.c + * Jun 26 1997 + * Robb Matzke <matzke@llnl.gov> * - * Purpose: Functions for handling symbol table nodes. A - * symbol table node is a small collection of symbol - * table entries. A B-tree usually points to the - * symbol table nodes for any given symbol table. + * Purpose: Functions for handling symbol table nodes. A + * symbol table node is a small collection of symbol + * table entries. A B-tree usually points to the + * symbol table nodes for any given symbol table. * *------------------------------------------------------------------------- */ @@ -35,16 +35,16 @@ /***********/ /* Headers */ /***********/ -#include "H5private.h" /* Generic Functions */ -#include "H5ACprivate.h" /* Metadata cache */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5Fprivate.h" /* File access */ -#include "H5FLprivate.h" /* Free Lists */ -#include "H5Gpkg.h" /* Groups */ -#include "H5HLprivate.h" /* Local Heaps */ -#include "H5MFprivate.h" /* File memory management */ -#include "H5MMprivate.h" /* Memory management */ -#include "H5Ppublic.h" /* Property Lists */ +#include "H5private.h" /* Generic Functions */ +#include "H5ACprivate.h" /* Metadata cache */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fprivate.h" /* File access */ +#include "H5FLprivate.h" /* Free Lists */ +#include "H5Gpkg.h" /* Groups */ +#include "H5HLprivate.h" /* Local Heaps */ +#include "H5MFprivate.h" /* File memory management */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Ppublic.h" /* Property Lists */ /****************/ @@ -77,20 +77,16 @@ typedef struct H5G_node_key_t { /* B-tree callbacks */ static H5UC_t *H5G_node_get_shared(const H5F_t *f, const void *_udata); static herr_t H5G_node_create(H5F_t *f, hid_t dxpl_id, H5B_ins_t op, void *_lt_key, - void *_udata, void *_rt_key, - haddr_t *addr_p/*out*/); + void *_udata, void *_rt_key, haddr_t *addr_p/*out*/); static int H5G_node_cmp2(void *_lt_key, void *_udata, void *_rt_key); static int H5G_node_cmp3(void *_lt_key, void *_udata, void *_rt_key); static htri_t H5G_node_found(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_lt_key, - void *_udata); + void *_udata); static H5B_ins_t H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key, - hbool_t *lt_key_changed, void *_md_key, - void *_udata, void *_rt_key, - hbool_t *rt_key_changed, - haddr_t *new_node_p/*out*/); + hbool_t *lt_key_changed, void *_md_key, void *_udata, void *_rt_key, + hbool_t *rt_key_changed, haddr_t *new_node_p/*out*/); static H5B_ins_t H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *lt_key, - hbool_t *lt_key_changed, void *udata, - void *rt_key, hbool_t *rt_key_changed); + hbool_t *lt_key_changed, void *udata, void *rt_key, hbool_t *rt_key_changed); static herr_t H5G_node_decode_key(const H5B_shared_t *shared, const uint8_t *raw, void *_key); static herr_t H5G_node_encode_key(const H5B_shared_t *shared, uint8_t *raw, const void *_key); static herr_t H5G_node_debug_key(FILE *stream, int indent, int fwidth, @@ -103,21 +99,21 @@ static herr_t H5G_node_debug_key(FILE *stream, int indent, int fwidth, /* H5G inherits B-tree like properties from H5B */ H5B_class_t H5B_SNODE[1] = {{ - H5B_SNODE_ID, /*id */ - sizeof(H5G_node_key_t), /*sizeof_nkey */ - H5G_node_get_shared, /*get_shared */ - H5G_node_create, /*new */ - H5G_node_cmp2, /*cmp2 */ - H5G_node_cmp3, /*cmp3 */ - H5G_node_found, /*found */ - H5G_node_insert, /*insert */ - TRUE, /*follow min branch? */ - TRUE, /*follow max branch? */ - H5B_RIGHT, /*critical key */ - H5G_node_remove, /*remove */ - H5G_node_decode_key, /*decode */ - H5G_node_encode_key, /*encode */ - H5G_node_debug_key /*debug */ + H5B_SNODE_ID, /*id */ + sizeof(H5G_node_key_t), /*sizeof_nkey */ + H5G_node_get_shared, /*get_shared */ + H5G_node_create, /*new */ + H5G_node_cmp2, /*cmp2 */ + H5G_node_cmp3, /*cmp3 */ + H5G_node_found, /*found */ + H5G_node_insert, /*insert */ + TRUE, /*follow min branch? */ + TRUE, /*follow max branch? */ + H5B_RIGHT, /*critical key */ + H5G_node_remove, /*remove */ + H5G_node_decode_key, /*decode */ + H5G_node_encode_key, /*encode */ + H5G_node_debug_key /*debug */ }}; /* Declare a free list to manage the H5G_node_t struct */ @@ -138,17 +134,16 @@ H5FL_SEQ_DEFINE(H5G_entry_t); /*------------------------------------------------------------------------- - * Function: H5G_node_get_shared + * Function: H5G_node_get_shared * - * Purpose: Returns the shared B-tree info for the specified UDATA. + * Purpose: Returns the shared B-tree info for the specified UDATA. * - * Return: Success: Pointer to the raw B-tree page for this - file's groups + * Return: Success: Pointer to the raw B-tree page for this file's groups * - * Failure: Can't fail + * Failure: Can't fail * - * Programmer: Robb Matzke - * Wednesday, October 8, 1997 + * Programmer: Robb Matzke + * Wednesday, October 8, 1997 * * Modifications: * @@ -167,22 +162,22 @@ H5G_node_get_shared(const H5F_t *f, const void H5_ATTR_UNUSED *_udata) /*------------------------------------------------------------------------- - * Function: H5G_node_decode_key + * Function: H5G_node_decode_key * - * Purpose: Decodes a raw key into a native key. + * Purpose: Decodes a raw key into a native key. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 8 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jul 8 1997 * *------------------------------------------------------------------------- */ static herr_t H5G_node_decode_key(const H5B_shared_t *shared, const uint8_t *raw, void *_key) { - H5G_node_key_t *key = (H5G_node_key_t *) _key; + H5G_node_key_t *key = (H5G_node_key_t *) _key; FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -199,13 +194,13 @@ H5G_node_decode_key(const H5B_shared_t *shared, const uint8_t *raw, void *_key) /*------------------------------------------------------------------------- * Function: H5G_node_encode_key * - * Purpose: Encodes a native key into a raw key. + * Purpose: Encodes a native key into a raw key. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 8 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jul 8 1997 * *------------------------------------------------------------------------- */ @@ -227,13 +222,13 @@ H5G_node_encode_key(const H5B_shared_t *shared, uint8_t *raw, const void *_key) /*------------------------------------------------------------------------- - * Function: H5G_node_debug_key + * Function: H5G_node_debug_key * - * Purpose: Prints a key. + * Purpose: Prints a key. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Quincey Koziol + * Programmer: Quincey Koziol * Friday, February 28, 2003 * *------------------------------------------------------------------------- @@ -242,7 +237,7 @@ static herr_t H5G_node_debug_key(FILE *stream, int indent, int fwidth, const void *_key, const void *_udata) { - const H5G_node_key_t *key = (const H5G_node_key_t *) _key; + const H5G_node_key_t *key = (const H5G_node_key_t *) _key; const H5G_bt_common_t *udata = (const H5G_bt_common_t *) _udata; FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -250,15 +245,15 @@ H5G_node_debug_key(FILE *stream, int indent, int fwidth, const void *_key, HDassert(key); HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, "Heap offset:", - (unsigned)key->offset); + (unsigned)key->offset); if(udata->heap) { const char *s; HDfprintf(stream, "%*s%-*s ", indent, "", fwidth, "Name:"); - s = (const char *)H5HL_offset_into(udata->heap, key->offset); - HDfprintf(stream, "%s\n", s); + if((s = (const char *)H5HL_offset_into(udata->heap, key->offset)) != NULL) + HDfprintf(stream, "%s\n", s); } /* end if */ else HDfprintf(stream, "%*s%-*s ", indent, "", fwidth, "Cannot get name; heap address not specified\n"); @@ -270,13 +265,13 @@ H5G_node_debug_key(FILE *stream, int indent, int fwidth, const void *_key, /*------------------------------------------------------------------------- * Function: H5G__node_free * - * Purpose: Destroy a symbol table node in memory. + * Purpose: Destroy a symbol table node in memory. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Jan 15 2003 + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Jan 15 2003 * *------------------------------------------------------------------------- */ @@ -305,29 +300,29 @@ H5G__node_free(H5G_node_t *sym) * Function: H5G_node_create * * Purpose: Creates a new empty symbol table node. This function is - * called by the B-tree insert function for an empty tree. It - * is also called internally to split a symbol node with LT_KEY - * and RT_KEY null pointers. + * called by the B-tree insert function for an empty tree. It + * is also called internally to split a symbol node with LT_KEY + * and RT_KEY null pointers. * - * Return: Success: Non-negative. The address of symbol table - * node is returned through the ADDR_P argument. + * Return: Success: Non-negative. The address of symbol table + * node is returned through the ADDR_P argument. * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jun 23 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jun 23 1997 * *------------------------------------------------------------------------- */ static herr_t H5G_node_create(H5F_t *f, hid_t dxpl_id, H5B_ins_t H5_ATTR_UNUSED op, void *_lt_key, - void H5_ATTR_UNUSED *_udata, void *_rt_key, haddr_t *addr_p/*out*/) + void H5_ATTR_UNUSED *_udata, void *_rt_key, haddr_t *addr_p/*out*/) { - H5G_node_key_t *lt_key = (H5G_node_key_t *)_lt_key; - H5G_node_key_t *rt_key = (H5G_node_key_t *)_rt_key; - H5G_node_t *sym = NULL; - herr_t ret_value = SUCCEED; /* Return value */ + H5G_node_key_t *lt_key = (H5G_node_key_t *)_lt_key; + H5G_node_key_t *rt_key = (H5G_node_key_t *)_rt_key; + H5G_node_t *sym = NULL; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -338,15 +333,15 @@ H5G_node_create(H5F_t *f, hid_t dxpl_id, H5B_ins_t H5_ATTR_UNUSED op, void *_lt_ HDassert(H5B_INS_FIRST == op); if(NULL == (sym = H5FL_CALLOC(H5G_node_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") sym->node_size = H5G_NODE_SIZE(f); if(HADDR_UNDEF == (*addr_p = H5MF_alloc(f, H5FD_MEM_BTREE, dxpl_id, (hsize_t)sym->node_size))) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to allocate file space") + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to allocate file space") if(NULL == (sym->entry = H5FL_SEQ_CALLOC(H5G_entry_t, (size_t)(2 * H5F_SYM_LEAF_K(f))))) - HGOTO_ERROR(H5E_SYM, H5E_CANTALLOC, FAIL, "memory allocation failed") + HGOTO_ERROR(H5E_SYM, H5E_CANTALLOC, FAIL, "memory allocation failed") if(H5AC_insert_entry(f, dxpl_id, H5AC_SNODE, *addr_p, sym, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to cache symbol table leaf node") + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to cache symbol table leaf node") /* * The left and right symbols in an empty tree are both the * empty string stored at offset zero by the H5G functions. This @@ -375,53 +370,51 @@ done: * Function: H5G_node_cmp2 * * Purpose: Compares two keys from a B-tree node (LT_KEY and RT_KEY). - * The UDATA pointer supplies extra data not contained in the - * keys (in this case, the heap address). + * The UDATA pointer supplies extra data not contained in the + * keys (in this case, the heap address). * - * Return: Success: negative if LT_KEY is less than RT_KEY. + * Return: Success: negative if LT_KEY is less than RT_KEY. * - * positive if LT_KEY is greater than RT_KEY. + * positive if LT_KEY is greater than RT_KEY. * - * zero if LT_KEY and RT_KEY are equal. + * zero if LT_KEY and RT_KEY are equal. * - * Failure: FAIL (same as LT_KEY<RT_KEY) + * Failure: FAIL (same as LT_KEY<RT_KEY) * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jun 23 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jun 23 1997 * * Modifications: * *------------------------------------------------------------------------- */ -static int +static herr_t H5G_node_cmp2(void *_lt_key, void *_udata, void *_rt_key) { - H5G_bt_common_t *udata = (H5G_bt_common_t *) _udata; - H5G_node_key_t *lt_key = (H5G_node_key_t *) _lt_key; - H5G_node_key_t *rt_key = (H5G_node_key_t *) _rt_key; - const char *s1, *s2; - const char *base; /* Base of heap */ - int ret_value = -1; /* Return value */ + H5G_bt_common_t *udata = (H5G_bt_common_t *) _udata; + H5G_node_key_t *lt_key = (H5G_node_key_t *) _lt_key; + H5G_node_key_t *rt_key = (H5G_node_key_t *) _rt_key; + const char *s1, *s2; + int ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_NOAPI_NOINIT /* Sanity checks */ HDassert(udata && udata->heap); HDassert(lt_key); HDassert(rt_key); - /* Get base address of heap */ - base = (const char *)H5HL_offset_into(udata->heap, (size_t)0); - HDassert(base); - /* Get pointers to string names */ - s1 = base + lt_key->offset; - s2 = base + rt_key->offset; + if((s1 = (const char *)H5HL_offset_into(udata->heap, lt_key->offset)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get key name") + if((s2 = (const char *)H5HL_offset_into(udata->heap, rt_key->offset)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get key name") /* Set return value */ ret_value = HDstrcmp(s1, s2); +done: FUNC_LEAVE_NOAPI(ret_value) } /* H5G_node_cmp2() */ @@ -430,88 +423,86 @@ H5G_node_cmp2(void *_lt_key, void *_udata, void *_rt_key) * Function: H5G_node_cmp3 * * Purpose: Compares two keys from a B-tree node (LT_KEY and RT_KEY) - * against another key (not necessarily the same type) - * pointed to by UDATA. + * against another key (not necessarily the same type) + * pointed to by UDATA. * - * Return: Success: negative if the UDATA key is less than - * or equal to the LT_KEY + * Return: Success: negative if the UDATA key is less than + * or equal to the LT_KEY * - * positive if the UDATA key is greater - * than the RT_KEY. + * positive if the UDATA key is greater + * than the RT_KEY. * - * zero if the UDATA key falls between - * the LT_KEY (exclusive) and the - * RT_KEY (inclusive). + * zero if the UDATA key falls between + * the LT_KEY (exclusive) and the + * RT_KEY (inclusive). * - * Failure: FAIL (same as UDATA < LT_KEY) + * Failure: FAIL (same as UDATA < LT_KEY) * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jun 23 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jun 23 1997 * * Modifications: * *------------------------------------------------------------------------- */ -static int +static herr_t H5G_node_cmp3(void *_lt_key, void *_udata, void *_rt_key) { - H5G_bt_common_t *udata = (H5G_bt_common_t *) _udata; - H5G_node_key_t *lt_key = (H5G_node_key_t *) _lt_key; - H5G_node_key_t *rt_key = (H5G_node_key_t *) _rt_key; - const char *s; - const char *base; /* Base of heap */ - int ret_value = 0; /* Return value */ + H5G_bt_common_t *udata = (H5G_bt_common_t *) _udata; + H5G_node_key_t *lt_key = (H5G_node_key_t *) _lt_key; + H5G_node_key_t *rt_key = (H5G_node_key_t *) _rt_key; + const char *s; + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_NOAPI_NOINIT /* Sanity checks */ HDassert(udata && udata->heap); HDassert(lt_key); HDassert(rt_key); - /* Get base address of heap */ - base = (const char *)H5HL_offset_into(udata->heap, (size_t)0); - HDassert(base); - /* left side */ - s = base + lt_key->offset; + if((s = (const char *)H5HL_offset_into(udata->heap, lt_key->offset)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get key name") if(HDstrcmp(udata->name, s) <= 0) - ret_value = (-1); + ret_value = (-1); else { /* right side */ - s = base + rt_key->offset; + if((s = (const char *)H5HL_offset_into(udata->heap, rt_key->offset)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get key name") if(HDstrcmp(udata->name, s) > 0) ret_value = 1; } /* end else */ +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_node_cmp3() */ /*------------------------------------------------------------------------- - * Function: H5G_node_found + * Function: H5G_node_found * - * Purpose: The B-tree search engine has found the symbol table node - * which contains the requested symbol if the symbol exists. - * This function should examine that node for the symbol and - * return information about the symbol through the UDATA - * structure which contains the symbol name on function - * entry. + * Purpose: The B-tree search engine has found the symbol table node + * which contains the requested symbol if the symbol exists. + * This function should examine that node for the symbol and + * return information about the symbol through the UDATA + * structure which contains the symbol name on function + * entry. * - * If the operation flag in UDATA is H5G_OPER_FIND, then - * the entry is copied from the symbol table to the UDATA - * entry field. Otherwise the entry is copied from the - * UDATA entry field to the symbol table. + * If the operation flag in UDATA is H5G_OPER_FIND, then + * the entry is copied from the symbol table to the UDATA + * entry field. Otherwise the entry is copied from the + * UDATA entry field to the symbol table. * - * Return: Success: Non-negative (TRUE/FALSE) if found and data - * returned through the UDATA pointer. + * Return: Success: Non-negative (TRUE/FALSE) if found and data + * returned through the UDATA pointer. * - * Failure: Negative if not found. + * Failure: Negative if not found. * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jun 23 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jun 23 1997 * *------------------------------------------------------------------------- */ @@ -519,13 +510,12 @@ static htri_t H5G_node_found(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void H5_ATTR_UNUSED *_lt_key, void *_udata) { - H5G_bt_lkp_t *udata = (H5G_bt_lkp_t *)_udata; - H5G_node_t *sn = NULL; - unsigned lt = 0, idx = 0, rt; - int cmp = 1; - const char *s; - const char *base; /* Base of heap */ - htri_t ret_value = TRUE; /* Return value */ + H5G_bt_lkp_t *udata = (H5G_bt_lkp_t *)_udata; + H5G_node_t *sn = NULL; + unsigned lt = 0, idx = 0, rt; + int cmp = 1; + const char *s; + htri_t ret_value = TRUE; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -540,25 +530,23 @@ H5G_node_found(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void H5_ATTR_UNUSED * Load the symbol table node for exclusive access. */ if(NULL == (sn = (H5G_node_t *)H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, f, H5AC__READ_ONLY_FLAG))) - HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, FAIL, "unable to protect symbol table node") - - /* Get base address of heap */ - base = (const char *)H5HL_offset_into(udata->common.heap, (size_t)0); - HDassert(base); + HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, FAIL, "unable to protect symbol table node") /* * Binary search. */ rt = sn->nsyms; while(lt < rt && cmp) { - idx = (lt + rt) / 2; - s = base + sn->entry[idx].name_off; - cmp = HDstrcmp(udata->common.name, s); - - if (cmp < 0) - rt = idx; - else - lt = idx + 1; + idx = (lt + rt) / 2; + + if((s = (const char *)H5HL_offset_into(udata->common.heap, sn->entry[idx].name_off)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get symbol table name") + cmp = HDstrcmp(udata->common.name, s); + + if (cmp < 0) + rt = idx; + else + lt = idx + 1; } /* end while */ if(cmp) @@ -570,43 +558,41 @@ H5G_node_found(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void H5_ATTR_UNUSED done: if(sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to release symbol table node") + HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to release symbol table node") FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_node_found() */ /*------------------------------------------------------------------------- - * Function: H5G_node_insert + * Function: H5G_node_insert * - * Purpose: The B-tree insertion engine has found the symbol table node - * which should receive the new symbol/address pair. This - * function adds it to that node unless it already existed. + * Purpose: The B-tree insertion engine has found the symbol table node + * which should receive the new symbol/address pair. This + * function adds it to that node unless it already existed. * - * If the node has no room for the symbol then the node is - * split into two nodes. The original node contains the - * low values and the new node contains the high values. - * The new symbol table entry is added to either node as - * appropriate. When a split occurs, this function will - * write the maximum key of the low node to the MID buffer - * and return the address of the new node. + * If the node has no room for the symbol then the node is + * split into two nodes. The original node contains the + * low values and the new node contains the high values. + * The new symbol table entry is added to either node as + * appropriate. When a split occurs, this function will + * write the maximum key of the low node to the MID buffer + * and return the address of the new node. * - * If the new key is larger than RIGHT then update RIGHT - * with the new key. + * If the new key is larger than RIGHT then update RIGHT + * with the new key. * - * Return: Success: An insertion command for the caller, one of - * the H5B_INS_* constants. The address of the - * new node, if any, is returned through the - * NEW_NODE_P argument. NEW_NODE_P might not be - * initialized if the return value is - * H5B_INS_NOOP. + * Return: Success: An insertion command for the caller, one of + * the H5B_INS_* constants. The address of the + * new node, if any, is returned through the + * NEW_NODE_P argument. NEW_NODE_P might not be + * initialized if the return value is H5B_INS_NOOP. * - * Failure: H5B_INS_ERROR, NEW_NODE_P might not be - * initialized. + * Failure: H5B_INS_ERROR, NEW_NODE_P might not be initialized. * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jun 24 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jun 24 1997 * *------------------------------------------------------------------------- */ @@ -617,18 +603,17 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_rt_key, hbool_t *rt_key_changed, haddr_t *new_node_p) { - H5G_node_key_t *md_key = (H5G_node_key_t *) _md_key; - H5G_node_key_t *rt_key = (H5G_node_key_t *) _rt_key; - H5G_bt_ins_t *udata = (H5G_bt_ins_t *) _udata; - H5G_node_t *sn = NULL, *snrt = NULL; - unsigned sn_flags = H5AC__NO_FLAGS_SET, snrt_flags = H5AC__NO_FLAGS_SET; - const char *s; - const char *base; /* Base of heap */ - unsigned lt = 0, rt; /* Binary search cntrs */ - int cmp = 1, idx = -1; - H5G_node_t *insert_into = NULL; /*node that gets new entry*/ - H5G_entry_t ent; /* Entry to insert in node */ - H5B_ins_t ret_value = H5B_INS_ERROR; + H5G_node_key_t *md_key = (H5G_node_key_t *) _md_key; + H5G_node_key_t *rt_key = (H5G_node_key_t *) _rt_key; + H5G_bt_ins_t *udata = (H5G_bt_ins_t *) _udata; + H5G_node_t *sn = NULL, *snrt = NULL; + unsigned sn_flags = H5AC__NO_FLAGS_SET, snrt_flags = H5AC__NO_FLAGS_SET; + const char *s; + unsigned lt = 0, rt; /* Binary search cntrs */ + int cmp = 1, idx = -1; + H5G_node_t *insert_into = NULL; /*node that gets new entry*/ + H5G_entry_t ent; /* Entry to insert in node */ + H5B_ins_t ret_value = H5B_INS_ERROR; FUNC_ENTER_NOAPI_NOINIT @@ -646,96 +631,93 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, * Load the symbol node. */ if(NULL == (sn = (H5G_node_t *)H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, f, H5AC__NO_FLAGS_SET))) - HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_INS_ERROR, "unable to protect symbol table node") - - /* Get base address of heap */ - base = (const char *)H5HL_offset_into(udata->common.heap, (size_t)0); - HDassert(base); + HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_INS_ERROR, "unable to protect symbol table node") /* * Where does the new symbol get inserted? We use a binary search. */ rt = sn->nsyms; while(lt < rt) { - idx = (int)((lt + rt) / 2); - s = base + sn->entry[idx].name_off; + idx = (int)((lt + rt) / 2); + if((s = (const char *)H5HL_offset_into(udata->common.heap, sn->entry[idx].name_off)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get symbol table name") /* Check if symbol is already present */ - if(0 == (cmp = HDstrcmp(udata->common.name, s))) + if(0 == (cmp = HDstrcmp(udata->common.name, s))) HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, H5B_INS_ERROR, "symbol is already present in symbol table") - if (cmp < 0) - rt = (unsigned)idx; - else - lt = (unsigned)(idx + 1); + if (cmp < 0) + rt = (unsigned)idx; + else + lt = (unsigned)(idx + 1); } /* end while */ idx += cmp > 0 ? 1 : 0; /* Convert link information & name to symbol table entry */ if(H5G__ent_convert(f, dxpl_id, udata->common.heap, udata->common.name, udata->lnk, udata->obj_type, udata->crt_info, &ent) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTCONVERT, H5B_INS_ERROR, "unable to convert link") + HGOTO_ERROR(H5E_SYM, H5E_CANTCONVERT, H5B_INS_ERROR, "unable to convert link") /* Determine where to place entry in node */ if(sn->nsyms >= 2 * H5F_SYM_LEAF_K(f)) { - /* - * The node is full. Split it into a left and right - * node and return the address of the new right node (the - * left node is at the same address as the original node). - */ - ret_value = H5B_INS_RIGHT; - - /* The right node */ - if(H5G_node_create(f, dxpl_id, H5B_INS_FIRST, NULL, NULL, NULL, new_node_p/*out*/) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, H5B_INS_ERROR, "unable to split symbol table node") - - if(NULL == (snrt = (H5G_node_t *)H5AC_protect(f, dxpl_id, H5AC_SNODE, *new_node_p, f, H5AC__NO_FLAGS_SET))) - HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_INS_ERROR, "unable to split symbol table node") - - HDmemcpy(snrt->entry, sn->entry + H5F_SYM_LEAF_K(f), - H5F_SYM_LEAF_K(f) * sizeof(H5G_entry_t)); - snrt->nsyms = H5F_SYM_LEAF_K(f); + /* + * The node is full. Split it into a left and right + * node and return the address of the new right node (the + * left node is at the same address as the original node). + */ + ret_value = H5B_INS_RIGHT; + + /* The right node */ + if(H5G_node_create(f, dxpl_id, H5B_INS_FIRST, NULL, NULL, NULL, new_node_p/*out*/) < 0) + HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, H5B_INS_ERROR, "unable to split symbol table node") + + if(NULL == (snrt = (H5G_node_t *)H5AC_protect(f, dxpl_id, H5AC_SNODE, *new_node_p, f, H5AC__NO_FLAGS_SET))) + HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_INS_ERROR, "unable to split symbol table node") + + HDmemcpy(snrt->entry, sn->entry + H5F_SYM_LEAF_K(f), + H5F_SYM_LEAF_K(f) * sizeof(H5G_entry_t)); + snrt->nsyms = H5F_SYM_LEAF_K(f); snrt_flags |= H5AC__DIRTIED_FLAG; - /* The left node */ - HDmemset(sn->entry + H5F_SYM_LEAF_K(f), 0, - H5F_SYM_LEAF_K(f) * sizeof(H5G_entry_t)); - sn->nsyms = H5F_SYM_LEAF_K(f); + /* The left node */ + HDmemset(sn->entry + H5F_SYM_LEAF_K(f), 0, + H5F_SYM_LEAF_K(f) * sizeof(H5G_entry_t)); + sn->nsyms = H5F_SYM_LEAF_K(f); sn_flags |= H5AC__DIRTIED_FLAG; - /* The middle key */ - md_key->offset = sn->entry[sn->nsyms - 1].name_off; + /* The middle key */ + md_key->offset = sn->entry[sn->nsyms - 1].name_off; - /* Where to insert the new entry? */ - if(idx <= (int)H5F_SYM_LEAF_K(f)) { - insert_into = sn; - if(idx == (int)H5F_SYM_LEAF_K(f)) - md_key->offset = ent.name_off; - } /* end if */ + /* Where to insert the new entry? */ + if(idx <= (int)H5F_SYM_LEAF_K(f)) { + insert_into = sn; + if(idx == (int)H5F_SYM_LEAF_K(f)) + md_key->offset = ent.name_off; + } /* end if */ else { - idx -= (int)H5F_SYM_LEAF_K(f); - insert_into = snrt; - if(idx == (int)H5F_SYM_LEAF_K(f)) { - rt_key->offset = ent.name_off; - *rt_key_changed = TRUE; - } /* end if */ - } /* end else */ + idx -= (int)H5F_SYM_LEAF_K(f); + insert_into = snrt; + if(idx == (int)H5F_SYM_LEAF_K(f)) { + rt_key->offset = ent.name_off; + *rt_key_changed = TRUE; + } /* end if */ + } /* end else */ } /* end if */ else { - /* Where to insert the new entry? */ - ret_value = H5B_INS_NOOP; + /* Where to insert the new entry? */ + ret_value = H5B_INS_NOOP; sn_flags |= H5AC__DIRTIED_FLAG; - insert_into = sn; - if(idx == (int)sn->nsyms) { - rt_key->offset = ent.name_off; - *rt_key_changed = TRUE; - } /* end if */ + insert_into = sn; + if(idx == (int)sn->nsyms) { + rt_key->offset = ent.name_off; + *rt_key_changed = TRUE; + } /* end if */ } /* end else */ /* Move entries down to make room for new entry */ HDassert(idx >= 0); HDmemmove(insert_into->entry + idx + 1, insert_into->entry + idx, - (insert_into->nsyms - (unsigned)idx) * sizeof(H5G_entry_t)); + (insert_into->nsyms - (unsigned)idx) * sizeof(H5G_entry_t)); /* Copy new entry into table */ H5G__ent_copy(&(insert_into->entry[idx]), &ent, H5_COPY_SHALLOW); @@ -745,56 +727,56 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, done: if(snrt && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, *new_node_p, snrt, snrt_flags) < 0) - HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to release symbol table node") + HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to release symbol table node") if(sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, sn_flags) < 0) - HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to release symbol table node") + HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to release symbol table node") FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_node_insert() */ /*------------------------------------------------------------------------- - * Function: H5G_node_remove + * Function: H5G_node_remove * - * Purpose: The B-tree removal engine has found the symbol table node - * which should contain the name which is being removed. This - * function removes the name from the symbol table and - * decrements the link count on the object to which the name - * points. + * Purpose: The B-tree removal engine has found the symbol table node + * which should contain the name which is being removed. This + * function removes the name from the symbol table and + * decrements the link count on the object to which the name + * points. * - * If the udata->name parameter is set to NULL, then remove - * all entries in this symbol table node. This only occurs - * during the deletion of the entire group, so don't bother - * freeing individual name entries in the local heap, the group's - * symbol table removal code will just free the entire local - * heap eventually. Do reduce the link counts for each object - * however. + * If the udata->name parameter is set to NULL, then remove + * all entries in this symbol table node. This only occurs + * during the deletion of the entire group, so don't bother + * freeing individual name entries in the local heap, the group's + * symbol table removal code will just free the entire local + * heap eventually. Do reduce the link counts for each object + * however. * - * Return: Success: If all names are removed from the symbol - * table node then H5B_INS_REMOVE is returned; - * otherwise H5B_INS_NOOP is returned. + * Return: Success: If all names are removed from the symbol + * table node then H5B_INS_REMOVE is returned; + * otherwise H5B_INS_NOOP is returned. * - * Failure: H5B_INS_ERROR + * Failure: H5B_INS_ERROR * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Thursday, September 24, 1998 * *------------------------------------------------------------------------- */ static H5B_ins_t H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/, - hbool_t H5_ATTR_UNUSED *lt_key_changed/*out*/, - void *_udata/*in,out*/, void *_rt_key/*in,out*/, - hbool_t *rt_key_changed/*out*/) + hbool_t H5_ATTR_UNUSED *lt_key_changed/*out*/, + void *_udata/*in,out*/, void *_rt_key/*in,out*/, + hbool_t *rt_key_changed/*out*/) { - H5G_node_key_t *lt_key = (H5G_node_key_t *)_lt_key; - H5G_node_key_t *rt_key = (H5G_node_key_t *)_rt_key; - H5G_bt_rm_t *udata = (H5G_bt_rm_t *)_udata; - H5G_node_t *sn = NULL; - unsigned sn_flags = H5AC__NO_FLAGS_SET; - unsigned lt = 0, rt, idx = 0; - int cmp = 1; - H5B_ins_t ret_value = H5B_INS_ERROR; + H5G_node_key_t *lt_key = (H5G_node_key_t *)_lt_key; + H5G_node_key_t *rt_key = (H5G_node_key_t *)_rt_key; + H5G_bt_rm_t *udata = (H5G_bt_rm_t *)_udata; + H5G_node_t *sn = NULL; + unsigned sn_flags = H5AC__NO_FLAGS_SET; + unsigned lt = 0, rt, idx = 0; + int cmp = 1; + H5B_ins_t ret_value = H5B_INS_ERROR; FUNC_ENTER_NOAPI_NOINIT @@ -807,16 +789,12 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/, /* Load the symbol table */ if(NULL == (sn = (H5G_node_t *)H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, f, H5AC__NO_FLAGS_SET))) - HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_INS_ERROR, "unable to protect symbol table node") + HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_INS_ERROR, "unable to protect symbol table node") /* "Normal" removal of a single entry from the symbol table node */ if(udata->common.name != NULL) { H5O_link_t lnk; /* Constructed link for replacement */ size_t link_name_len; /* Length of string in local heap */ - const char *base; /* Base of heap */ - - /* Get base address of heap */ - base = (const char *)H5HL_offset_into(udata->common.heap, (size_t)0); /* Find the name with a binary search */ rt = sn->nsyms; @@ -824,7 +802,8 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/, const char *s; /* Pointer to string in local heap */ idx = (lt + rt) / 2; - s = base + sn->entry[idx].name_off; + if((s = H5HL_offset_into(udata->common.heap, sn->entry[idx].name_off)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get symbol table name") cmp = HDstrcmp(udata->common.name, s); if(cmp < 0) rt = idx; @@ -846,7 +825,8 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/, lnk.cset = H5T_CSET_ASCII; if(sn->entry[idx].type == H5G_CACHED_SLINK) { lnk.type = H5L_TYPE_SOFT; - lnk.u.soft.name = (char *)H5HL_offset_into(udata->common.heap, sn->entry[idx].cache.slink.lval_offset); + if(NULL == (lnk.u.soft.name = (char *)H5HL_offset_into(udata->common.heap, sn->entry[idx].cache.slink.lval_offset))) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5B_INS_ERROR, "unable to get link name") } /* end if */ else { lnk.type = H5L_TYPE_HARD; @@ -960,22 +940,22 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/, done: if(sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, sn_flags) < 0) - HDONE_ERROR(H5E_SYM, H5E_CANTUNPROTECT, H5B_INS_ERROR, "unable to release symbol table node") + HDONE_ERROR(H5E_SYM, H5E_CANTUNPROTECT, H5B_INS_ERROR, "unable to release symbol table node") FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_node_remove() */ /*------------------------------------------------------------------------- - * Function: H5G__node_iterate + * Function: H5G__node_iterate * - * Purpose: This function gets called during a group iterate operation. + * Purpose: This function gets called during a group iterate operation. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jun 24 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jun 24 1997 * *------------------------------------------------------------------------- */ @@ -983,11 +963,11 @@ int H5G__node_iterate(H5F_t *f, hid_t dxpl_id, const void H5_ATTR_UNUSED *_lt_key, haddr_t addr, const void H5_ATTR_UNUSED *_rt_key, void *_udata) { - H5G_bt_it_it_t *udata = (H5G_bt_it_it_t *)_udata; - H5G_node_t *sn = NULL; - H5G_entry_t *ents; /* Pointer to entries in this node */ - unsigned u; /* Local index variable */ - int ret_value = H5_ITER_CONT; + H5G_bt_it_it_t *udata = (H5G_bt_it_it_t *)_udata; + H5G_node_t *sn = NULL; + H5G_entry_t *ents; /* Pointer to entries in this node */ + unsigned u; /* Local index variable */ + int ret_value = H5_ITER_CONT; FUNC_ENTER_PACKAGE @@ -1000,7 +980,7 @@ H5G__node_iterate(H5F_t *f, hid_t dxpl_id, const void H5_ATTR_UNUSED *_lt_key, h /* Protect the symbol table node & local heap while we iterate over entries */ if(NULL == (sn = (H5G_node_t *)H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, f, H5AC__READ_ONLY_FLAG))) - HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5_ITER_ERROR, "unable to load symbol table node") + HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5_ITER_ERROR, "unable to load symbol table node") /* * Iterate over the symbol table node entries. @@ -1013,8 +993,8 @@ H5G__node_iterate(H5F_t *f, hid_t dxpl_id, const void H5_ATTR_UNUSED *_lt_key, h const char *name; /* Pointer to link name in heap */ /* Get the pointer to the name of the link in the heap */ - name = (const char *)H5HL_offset_into(udata->heap, ents[u].name_off); - HDassert(name); + if((name = (const char *)H5HL_offset_into(udata->heap, ents[u].name_off)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5_ITER_ERROR, "unable to get symbol table node name") /* Convert the entry to a link */ if(H5G__ent_to_link(&lnk, udata->heap, &ents[u], name) < 0) @@ -1043,15 +1023,14 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G__node_iterate() */ - /*------------------------------------------------------------------------- - * Function: H5G__node_sumup + * Function: H5G__node_sumup * - * Purpose: This function gets called during a group iterate operation + * Purpose: This function gets called during a group iterate operation * to return total number of members in the group. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * * Programmer: Raymond Lu * Nov 20, 2002 @@ -1060,11 +1039,11 @@ done: */ int H5G__node_sumup(H5F_t *f, hid_t dxpl_id, const void H5_ATTR_UNUSED *_lt_key, haddr_t addr, - const void H5_ATTR_UNUSED *_rt_key, void *_udata) + const void H5_ATTR_UNUSED *_rt_key, void *_udata) { hsize_t *num_objs = (hsize_t *)_udata; - H5G_node_t *sn = NULL; - int ret_value = H5_ITER_CONT; + H5G_node_t *sn = NULL; + int ret_value = H5_ITER_CONT; FUNC_ENTER_PACKAGE @@ -1077,7 +1056,7 @@ H5G__node_sumup(H5F_t *f, hid_t dxpl_id, const void H5_ATTR_UNUSED *_lt_key, had /* Find the object node and add the number of symbol entries. */ if(NULL == (sn = (H5G_node_t *)H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, f, H5AC__READ_ONLY_FLAG))) - HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5_ITER_ERROR, "unable to load symbol table node") + HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5_ITER_ERROR, "unable to load symbol table node") *num_objs += sn->nsyms; @@ -1090,12 +1069,12 @@ done: /*------------------------------------------------------------------------- - * Function: H5G__node_by_idx + * Function: H5G__node_by_idx * - * Purpose: This function gets called during a group iterate operation + * Purpose: This function gets called during a group iterate operation * to return object name by giving idx. * - * Return: 0 if object isn't found in this node; 1 if object is found; + * Return: 0 if object isn't found in this node; 1 if object is found; * Negative on failure * * Programmer: Raymond Lu @@ -1105,11 +1084,11 @@ done: */ int H5G__node_by_idx(H5F_t *f, hid_t dxpl_id, const void H5_ATTR_UNUSED *_lt_key, haddr_t addr, - const void H5_ATTR_UNUSED *_rt_key, void *_udata) + const void H5_ATTR_UNUSED *_rt_key, void *_udata) { - H5G_bt_it_idx_common_t *udata = (H5G_bt_it_idx_common_t *)_udata; - H5G_node_t *sn = NULL; - int ret_value = H5_ITER_CONT; + H5G_bt_it_idx_common_t *udata = (H5G_bt_it_idx_common_t *)_udata; + H5G_node_t *sn = NULL; + int ret_value = H5_ITER_CONT; FUNC_ENTER_PACKAGE @@ -1122,7 +1101,7 @@ H5G__node_by_idx(H5F_t *f, hid_t dxpl_id, const void H5_ATTR_UNUSED *_lt_key, ha /* Get a pointer to the symbol table node */ if(NULL == (sn = (H5G_node_t *)H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, f, H5AC__READ_ONLY_FLAG))) - HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5_ITER_ERROR, "unable to load symbol table node"); + HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5_ITER_ERROR, "unable to load symbol table node"); /* Find the node, locate the object symbol table entry and retrieve the name */ if(udata->idx >= udata->num_objs && udata->idx < (udata->num_objs + sn->nsyms)) { @@ -1151,12 +1130,12 @@ done: /*------------------------------------------------------------------------- - * Function: H5G__node_init + * Function: H5G__node_init * - * Purpose: This function gets called during a file opening to initialize + * Purpose: This function gets called during a file opening to initialize * global information about group B-tree nodes for file. * - * Return: Non-negative on success + * Return: Non-negative on success * Negative on failure * * Programmer: Quincey Koziol @@ -1167,9 +1146,9 @@ done: herr_t H5G__node_init(H5F_t *f) { - H5B_shared_t *shared; /* Shared B-tree node info */ - size_t sizeof_rkey; /* Size of raw (disk) key */ - herr_t ret_value = SUCCEED; /* Return value */ + H5B_shared_t *shared; /* Shared B-tree node info */ + size_t sizeof_rkey; /* Size of raw (disk) key */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -1181,14 +1160,14 @@ H5G__node_init(H5F_t *f) /* Allocate & initialize global info for the shared structure */ if(NULL == (shared = H5B_shared_new(f, H5B_SNODE, sizeof_rkey))) - HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, FAIL, "memory allocation failed for shared B-tree info") + HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, FAIL, "memory allocation failed for shared B-tree info") /* Set up the "local" information for this file's groups */ - /* <none> */ + /* <none> */ /* Make shared B-tree info reference counted */ if(H5F_SET_GRP_BTREE_SHARED(f, H5UC_create(shared, H5B_shared_free)) < 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create ref-count wrapper for shared B-tree info") + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create ref-count wrapper for shared B-tree info") done: FUNC_LEAVE_NOAPI(ret_value) @@ -1196,12 +1175,12 @@ done: /*------------------------------------------------------------------------- - * Function: H5G_node_close + * Function: H5G_node_close * - * Purpose: This function gets called during a file close to shutdown + * Purpose: This function gets called during a file close to shutdown * global information about group B-tree nodes for file. * - * Return: Non-negative on success + * Return: Non-negative on success * Negative on failure * * Programmer: Quincey Koziol @@ -1227,12 +1206,12 @@ H5G_node_close(const H5F_t *f) /*------------------------------------------------------------------------- - * Function: H5G__node_copy + * Function: H5G__node_copy * - * Purpose: This function gets called during a group iterate operation + * Purpose: This function gets called during a group iterate operation * to copy objects of this node into a new location. * - * Return: 0(zero) on success/Negative on failure + * Return: 0(zero) on success/Negative on failure * * Programmer: Peter Cao * Sept 10, 2005 @@ -1241,7 +1220,7 @@ H5G_node_close(const H5F_t *f) */ int H5G__node_copy(H5F_t *f, hid_t dxpl_id, const void H5_ATTR_UNUSED *_lt_key, haddr_t addr, - const void H5_ATTR_UNUSED *_rt_key, void *_udata) + const void H5_ATTR_UNUSED *_rt_key, void *_udata) { H5G_bt_it_cpy_t *udata = (H5G_bt_it_cpy_t *)_udata; const H5O_loc_t *src_oloc = udata->src_oloc; @@ -1260,7 +1239,7 @@ H5G__node_copy(H5F_t *f, hid_t dxpl_id, const void H5_ATTR_UNUSED *_lt_key, hadd /* load the symbol table into memory from the source file */ if(NULL == (sn = (H5G_node_t *)H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, f, H5AC__READ_ONLY_FLAG))) - HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5_ITER_ERROR, "unable to load symbol table node") + HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5_ITER_ERROR, "unable to load symbol table node") /* get the base address of the heap */ if(NULL == (heap = H5HL_protect(f, dxpl_id, udata->src_heap_addr, H5AC__READ_ONLY_FLAG))) @@ -1292,7 +1271,8 @@ H5G__node_copy(H5F_t *f, hid_t dxpl_id, const void H5_ATTR_UNUSED *_lt_key, hadd grp_loc.oloc = (H5O_loc_t *)src_oloc; /* Get pointer to link value in local heap */ - link_name = (char *)H5HL_offset_into(heap, tmp_src_ent.cache.slink.lval_offset); + if((link_name = (char *)H5HL_offset_into(heap, tmp_src_ent.cache.slink.lval_offset)) == NULL) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, H5_ITER_ERROR, "unable to get link name") /* Check if the object pointed by the soft link exists in the source file */ if(H5G_loc_info(&grp_loc, link_name, FALSE, &oinfo, H5P_DEFAULT, dxpl_id) >= 0) { @@ -1342,7 +1322,8 @@ H5G__node_copy(H5F_t *f, hid_t dxpl_id, const void H5_ATTR_UNUSED *_lt_key, hadd /* Construct link information for eventual insertion */ lnk.type = H5L_TYPE_SOFT; - lnk.u.soft.name = (char *)H5HL_offset_into(heap, src_ent->cache.slink.lval_offset); + if((lnk.u.soft.name = (char *)H5HL_offset_into(heap, src_ent->cache.slink.lval_offset)) == NULL) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, H5_ITER_ERROR, "unable to get link name") } /* else if */ else HDassert(0 && "Unknown entry type"); @@ -1354,8 +1335,8 @@ H5G__node_copy(H5F_t *f, hid_t dxpl_id, const void H5_ATTR_UNUSED *_lt_key, hadd /* lnk.name = name; */ /* This will be set in callback */ /* Determine name of source object */ - name = (const char *)H5HL_offset_into(heap, src_ent->name_off); - HDassert(name); + if((name = (const char *)H5HL_offset_into(heap, src_ent->name_off)) == NULL) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, H5_ITER_ERROR, "unable to get source object name") /* Set copied metadata tag */ H5_BEGIN_TAG(dxpl_id, H5AC__COPIED_TAG, H5_ITER_ERROR); @@ -1384,15 +1365,15 @@ done: /*------------------------------------------------------------------------- - * Function: H5G__node_build_table + * Function: H5G__node_build_table * - * Purpose: B-link tree callback for building table of links + * Purpose: B-link tree callback for building table of links * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * Nov 19 2006 + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Nov 19 2006 * *------------------------------------------------------------------------- */ @@ -1400,10 +1381,10 @@ int H5G__node_build_table(H5F_t *f, hid_t dxpl_id, const void H5_ATTR_UNUSED *_lt_key, haddr_t addr, const void H5_ATTR_UNUSED *_rt_key, void *_udata) { - H5G_bt_it_bt_t *udata = (H5G_bt_it_bt_t *)_udata; - H5G_node_t *sn = NULL; /* Symbol table node */ - unsigned u; /* Local index variable */ - int ret_value = H5_ITER_CONT; + H5G_bt_it_bt_t *udata = (H5G_bt_it_bt_t *)_udata; + H5G_node_t *sn = NULL; /* Symbol table node */ + unsigned u; /* Local index variable */ + int ret_value = H5_ITER_CONT; FUNC_ENTER_PACKAGE @@ -1419,7 +1400,7 @@ H5G__node_build_table(H5F_t *f, hid_t dxpl_id, const void H5_ATTR_UNUSED *_lt_ke * because we're about to call an application function. */ if(NULL == (sn = (H5G_node_t *)H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, f, H5AC__READ_ONLY_FLAG))) - HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5_ITER_ERROR, "unable to load symbol table node") + HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5_ITER_ERROR, "unable to load symbol table node") /* Check if the link table needs to be extended */ if((udata->ltable->nlinks + sn->nsyms) >= udata->alloc_nlinks) { @@ -1438,8 +1419,8 @@ H5G__node_build_table(H5F_t *f, hid_t dxpl_id, const void H5_ATTR_UNUSED *_lt_ke size_t linkno; /* Link allocated */ /* Get pointer to link's name in the heap */ - name = (const char *)H5HL_offset_into(udata->heap, sn->entry[u].name_off); - HDassert(name); + if((name = (const char *)H5HL_offset_into(udata->heap, sn->entry[u].name_off)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5_ITER_ERROR, "unable to get symbol table link name") /* Determine the link to operate on in the table */ linkno = udata->ltable->nlinks++; @@ -1472,8 +1453,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5G__node_iterate_size(H5F_t *f, hid_t H5_ATTR_UNUSED dxpl_id, const void H5_ATTR_UNUSED *_lt_key, haddr_t H5_ATTR_UNUSED addr, - const void H5_ATTR_UNUSED *_rt_key, void *_udata) +H5G__node_iterate_size(H5F_t *f, hid_t H5_ATTR_UNUSED dxpl_id, const void H5_ATTR_UNUSED *_lt_key, + haddr_t H5_ATTR_UNUSED addr, const void H5_ATTR_UNUSED *_rt_key, void *_udata) { hsize_t *stab_size = (hsize_t *)_udata; /* User data */ @@ -1490,16 +1471,16 @@ H5G__node_iterate_size(H5F_t *f, hid_t H5_ATTR_UNUSED dxpl_id, const void H5_ATT /*------------------------------------------------------------------------- - * Function: H5G_node_debug + * Function: H5G_node_debug * - * Purpose: Prints debugging information about a symbol table node - * or a B-tree node for a symbol table B-tree. + * Purpose: Prints debugging information about a symbol table node + * or a B-tree node for a symbol table B-tree. * - * Return: 0(zero) on success/Negative on failure + * Return: 0(zero) on success/Negative on failure * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 4 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Aug 4 1997 * *------------------------------------------------------------------------- */ @@ -1507,10 +1488,10 @@ herr_t H5G_node_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, int fwidth, haddr_t heap_addr) { - H5G_node_t *sn = NULL; - H5HL_t *heap = NULL; - unsigned u; /* Local index variable */ - herr_t ret_value = SUCCEED; /* Return value */ + H5G_node_t *sn = NULL; + H5HL_t *heap = NULL; + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -1537,33 +1518,33 @@ H5G_node_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, H5E_clear_stack(NULL); /* discard that error */ udata.heap = heap; - if(H5B_debug(f, dxpl_id, addr, stream, indent, fwidth, H5B_SNODE, &udata) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, FAIL, "unable to debug B-tree node"); + if(H5B_debug(f, dxpl_id, addr, stream, indent, fwidth, H5B_SNODE, &udata) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, FAIL, "unable to debug B-tree node"); } /* end if */ else { - fprintf(stream, "%*sSymbol Table Node...\n", indent, ""); - fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, + HDfprintf(stream, "%*sSymbol Table Node...\n", indent, ""); + HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, "Dirty:", sn->cache_info.is_dirty ? "Yes" : "No"); - fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, + HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, "Size of Node (in bytes):", (unsigned)sn->node_size); - fprintf(stream, "%*s%-*s %u of %u\n", indent, "", fwidth, + HDfprintf(stream, "%*s%-*s %u of %u\n", indent, "", fwidth, "Number of Symbols:", sn->nsyms, (unsigned)(2 * H5F_SYM_LEAF_K(f))); indent += 3; fwidth = MAX(0, fwidth - 3); for(u = 0; u < sn->nsyms; u++) { - fprintf(stream, "%*sSymbol %u:\n", indent - 3, "", u); + HDfprintf(stream, "%*sSymbol %u:\n", indent - 3, "", u); if(heap) { const char *s = (const char *)H5HL_offset_into(heap, sn->entry[u].name_off); if(s) - fprintf(stream, "%*s%-*s `%s'\n", indent, "", fwidth, "Name:", s); + HDfprintf(stream, "%*s%-*s `%s'\n", indent, "", fwidth, "Name:", s); } /* end if */ else - fprintf(stream, "%*s%-*s\n", indent, "", fwidth, "Warning: Invalid heap address given, name not displayed!"); + HDfprintf(stream, "%*s%-*s\n", indent, "", fwidth, "Warning: Invalid heap address given, name not displayed!"); H5G__ent_debug(sn->entry + u, stream, indent, fwidth, heap); } /* end for */ @@ -1571,7 +1552,7 @@ H5G_node_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, done: if(sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to release symbol table node") + HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to release symbol table node") if(heap && H5HL_unprotect(heap) < 0) HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap") diff --git a/src/H5Gstab.c b/src/H5Gstab.c index a239cfe..4dc06ca 100644 --- a/src/H5Gstab.c +++ b/src/H5Gstab.c @@ -707,11 +707,12 @@ done: static herr_t H5G_stab_get_name_by_idx_cb(const H5G_entry_t *ent, void *_udata) { - H5G_bt_it_gnbi_t *udata = (H5G_bt_it_gnbi_t *)_udata; + H5G_bt_it_gnbi_t *udata = (H5G_bt_it_gnbi_t *)_udata; size_t name_off; /* Offset of name in heap */ const char *name; /* Pointer to name string in heap */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_NOAPI_NOINIT /* Sanity check */ HDassert(ent); @@ -719,12 +720,15 @@ H5G_stab_get_name_by_idx_cb(const H5G_entry_t *ent, void *_udata) /* Get name offset in heap */ name_off = ent->name_off; - name = (const char *)H5HL_offset_into(udata->heap, name_off); - HDassert(name); - udata->name = H5MM_strdup(name); - HDassert(udata->name); - FUNC_LEAVE_NOAPI(SUCCEED) + if((name = (const char *)H5HL_offset_into(udata->heap, name_off)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get symbol table link name") + + if((udata->name = H5MM_strdup(name)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to duplicate symbol table link name") + +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_stab_get_name_by_idx_cb */ @@ -941,8 +945,8 @@ H5G_stab_lookup_by_idx_cb(const H5G_entry_t *ent, void *_udata) HDassert(udata && udata->heap); /* Get a pointer to the link name */ - name = (const char *)H5HL_offset_into(udata->heap, ent->name_off); - HDassert(name); + if((name = (const char *)H5HL_offset_into(udata->heap, ent->name_off)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get symbol table link name") /* Convert the entry to a link */ if(H5G__ent_to_link(udata->lnk, udata->heap, ent, name) < 0) @@ -400,18 +400,20 @@ END_FUNC(PRIV) /* end H5HL_protect() */ * *------------------------------------------------------------------------- */ -BEGIN_FUNC(PRIV, NOERR, -void *, NULL, -, +BEGIN_FUNC(PRIV, ERR, +void *, NULL, NULL, H5HL_offset_into(const H5HL_t *heap, size_t offset)) /* Sanity check */ HDassert(heap); - HDassert(offset < heap->dblk_size); + if(offset >= heap->dblk_size) + H5E_THROW(H5E_CANTGET, "unable to offset into local heap data block"); ret_value = heap->dblk_image + offset; +CATCH + /* No special processing on errors */ END_FUNC(PRIV) /* end H5HL_offset_into() */ - /*------------------------------------------------------------------------- * Function: H5HL_unprotect diff --git a/src/H5Oefl.c b/src/H5Oefl.c index 0456b00..49c442f 100644 --- a/src/H5Oefl.c +++ b/src/H5Oefl.c @@ -67,17 +67,17 @@ const H5O_msg_class_t H5O_MSG_EFL[1] = {{ /*------------------------------------------------------------------------- - * Function: H5O_efl_decode + * Function: H5O_efl_decode * * Purpose: Decode an external file list message and return a pointer to - * the message (and some other data). + * the message (and some other data). * - * Return: Success: Ptr to a new message struct. + * Return: Success: Ptr to a new message struct. * - * Failure: NULL + * Failure: NULL * * Programmer: Robb Matzke - * Tuesday, November 25, 1997 + * Tuesday, November 25, 1997 * * Modification: * Raymond Lu @@ -90,12 +90,12 @@ static void * H5O_efl_decode(H5F_t *f, hid_t dxpl_id, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, unsigned H5_ATTR_UNUSED *ioflags, const uint8_t *p) { - H5O_efl_t *mesg = NULL; - int version; - const char *s = NULL; - H5HL_t *heap; - size_t u; /* Local index variable */ - void *ret_value = NULL; /* Return value */ + H5O_efl_t *mesg = NULL; + int version; + const char *s = NULL; + H5HL_t *heap; + size_t u; /* Local index variable */ + void *ret_value = NULL; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -104,12 +104,12 @@ H5O_efl_decode(H5F_t *f, hid_t dxpl_id, H5O_t H5_ATTR_UNUSED *open_oh, HDassert(p); if(NULL == (mesg = (H5O_efl_t *)H5MM_calloc(sizeof(H5O_efl_t)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Version */ version = *p++; if(version != H5O_EFL_VERSION) - HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for external file list message") + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for external file list message") /* Reserved */ p += 3; @@ -141,24 +141,26 @@ H5O_efl_decode(H5F_t *f, hid_t dxpl_id, H5O_t H5_ATTR_UNUSED *open_oh, /* Decode the file list */ mesg->slot = (H5O_efl_entry_t *)H5MM_calloc(mesg->nalloc * sizeof(H5O_efl_entry_t)); if(NULL == mesg->slot) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") if(NULL == (heap = H5HL_protect(f, dxpl_id, mesg->heap_addr, H5AC__READ_ONLY_FLAG))) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "unable to read protect link value") for(u = 0; u < mesg->nused; u++) { - /* Name */ - H5F_DECODE_LENGTH (f, p, mesg->slot[u].name_offset); - - s = (const char *)H5HL_offset_into(heap, mesg->slot[u].name_offset); - HDassert(s && *s); - mesg->slot[u].name = H5MM_xstrdup (s); + /* Name */ + H5F_DECODE_LENGTH (f, p, mesg->slot[u].name_offset); + + if((s = (const char *)H5HL_offset_into(heap, mesg->slot[u].name_offset)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, NULL, "unable to get external file name") + if(*s == (char)NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, NULL, "invalid external file name") + mesg->slot[u].name = H5MM_xstrdup (s); HDassert(mesg->slot[u].name); - /* File offset */ - H5F_DECODE_LENGTH (f, p, mesg->slot[u].offset); + /* File offset */ + H5F_DECODE_LENGTH (f, p, mesg->slot[u].offset); - /* Size */ - H5F_DECODE_LENGTH (f, p, mesg->slot[u].size); + /* Size */ + H5F_DECODE_LENGTH (f, p, mesg->slot[u].size); } /* end for */ if(H5HL_unprotect(heap) < 0) diff --git a/test/CMakeTests.cmake b/test/CMakeTests.cmake index 5f0d386..5d2f30b 100644 --- a/test/CMakeTests.cmake +++ b/test/CMakeTests.cmake @@ -183,6 +183,7 @@ endforeach () set (HDF5_REFERENCE_TEST_FILES aggr.h5 bad_compound.h5 + bad_offset.h5 be_data.h5 be_extlink1.h5 be_extlink2.h5 @@ -1336,6 +1337,7 @@ if (HDF5_BUILD_GENERATORS) # generator executables set (H5_GENERATORS + gen_bad_offset gen_bad_ohdr gen_bogus gen_cross diff --git a/test/Makefile.am b/test/Makefile.am index f64b6d8..53dbf0d 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -94,7 +94,7 @@ endif BUILD_ALL_PROGS=gen_bad_ohdr gen_bogus gen_cross gen_deflate gen_filters gen_new_array \ gen_new_fill gen_new_group gen_new_mtime gen_new_super gen_noencoder \ gen_nullspace gen_udlinks space_overflow gen_filespace gen_specmetaread \ - gen_sizes_lheap gen_file_image gen_plist + gen_sizes_lheap gen_file_image gen_plist gen_bad_offset if BUILD_ALL_CONDITIONAL noinst_PROGRAMS=$(BUILD_ALL_PROGS) diff --git a/test/bad_offset.h5 b/test/bad_offset.h5 Binary files differnew file mode 100644 index 0000000..231dca2 --- /dev/null +++ b/test/bad_offset.h5 diff --git a/test/gen_bad_offset.c b/test/gen_bad_offset.c new file mode 100644 index 0000000..82e94cd --- /dev/null +++ b/test/gen_bad_offset.c @@ -0,0 +1,147 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Purpose: Generate an HDF5 file for testing H5FFV-10216 + */ +#include "h5test.h" + +#define TESTFILE "bad_offset.h5" +#define GRP1 "group1" +#define GRP2 "group2" +#define DSET "dsetA" +#define SOFT1 "soft_one" +#define SOFT2 "soft_two" + + + +/*------------------------------------------------------------------------- + * Function: main + * + * Generate an HDF5 file with groups, datasets and symbolic links. + * After the file is generated, write bad offset values to + * the heap at 3 locations in the file: + * (A) Open the file: + * fd = HDopen(TESTFILE, O_RDWR, 0663); + * (B) Position the file at: + * (1) HDlseek(fd, (HDoff_t)880, SEEK_SET); + * "/group1/group2": replace heap offset "8" by bad offset + * (2) HDlseek(fd, (HDoff_t)1512, SEEK_SET); + * "/dsetA": replace name offset into private heap "72" by bad offset + * (3) HDlseek(fd, (HDoff_t)1616, SEEK_SET); + * /soft_one: replace link value offset in the scratch pad "32" by bad offset + * (C) Write the bad offset value to the file for (1), (2) and (3): + * write(fd, &val, sizeof(val)); + * + * Note: if the groups/datasets/symbolic links are changed in the file, + * the above locations need to be adjusted accordingly. + * + * Return: EXIT_SUCCESS/EXIT_FAILURE + * + *------------------------------------------------------------------------- + */ +int +main(void) +{ + hid_t fid = -1, gid1 = -1, gid2 = -1; /* File and group IDs */ + hid_t did = -1, sid = -1; /* Dataset and dataspace IDs */ + int fd = -1; /* File descriptor */ + int64_t val = 999; /* Bad offset value */ + + /* Create the test file */ + if((fid = H5Fcreate(TESTFILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR + + /* Create two groups */ + if((gid1 = H5Gcreate2(fid, GRP1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR + if((gid2 = H5Gcreate2(gid1, GRP2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR + + /* Close the groups */ + if(H5Gclose(gid1) < 0) + FAIL_STACK_ERROR + if(H5Gclose(gid2) < 0) + FAIL_STACK_ERROR + + /* Create soft links to the groups */ + if(H5Lcreate_soft("/group1", fid, SOFT1, H5P_DEFAULT, H5P_DEFAULT) < 0) + FAIL_STACK_ERROR + if(H5Lcreate_soft("/group1/group2", fid, SOFT2, H5P_DEFAULT, H5P_DEFAULT) < 0) + FAIL_STACK_ERROR + + /* Create a dataset */ + if((sid = H5Screate(H5S_SCALAR)) < 0) + FAIL_STACK_ERROR + if((did = H5Dcreate2(fid, DSET, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR + + /* Close the dataset */ + if(H5Dclose(did) < 0) + FAIL_STACK_ERROR + + /* Close the dataspace */ + if(H5Sclose(sid) < 0) + FAIL_STACK_ERROR + + /* Close the file */ + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR + + /* + * Write bad offset values at 3 locations in the file + */ + + /* Open the file */ + if((fd = HDopen(TESTFILE, O_RDWR, 0663)) < 0) + FAIL_STACK_ERROR + + /* Position the file for /group1/group2: replace heap offset "8" by bad offset */ + if(HDlseek(fd, (HDoff_t)880, SEEK_SET) < 0) + FAIL_STACK_ERROR + /* Write the bad offset value to the file */ + if(HDwrite(fd, &val, sizeof(val)) < 0) + FAIL_STACK_ERROR + + /* Position the file for /dsetA: replace name offset into private heap "72" by bad offset */ + if(HDlseek(fd, (HDoff_t)1512, SEEK_SET) < 0) + FAIL_STACK_ERROR + /* Write the bad offset value to the file */ + if(HDwrite(fd, &val, sizeof(val)) < 0) + FAIL_STACK_ERROR + + /* Position the file for /soft_one: replace link value offset in the scratch pad "32" by bad offset */ + if(HDlseek(fd, (HDoff_t)1616, SEEK_SET) < 0) + FAIL_STACK_ERROR + /* Write the bad offset value to the file */ + if(HDwrite(fd, &val, sizeof(val)) < 0) + FAIL_STACK_ERROR + + /* Close the file */ + if(HDclose(fd) < 0) + FAIL_STACK_ERROR + + return EXIT_SUCCESS; + +error: + H5E_BEGIN_TRY { + H5Gclose(gid1); + H5Gclose(gid2); + H5Dclose(did); + H5Sclose(sid); + H5Fclose(fid); + } H5E_END_TRY; + + return EXIT_FAILURE; +} /* end main() */ + diff --git a/test/tmisc.c b/test/tmisc.c index 708ca9b..102325a 100644 --- a/test/tmisc.c +++ b/test/tmisc.c @@ -318,6 +318,11 @@ typedef struct #define MISC31_PROPNAME "misc31_prop" #define MISC31_DTYPENAME "dtype" +/* Definitions for misc. test #33 */ +/* Note that this test file is generated by "gen_bad_offset.c" */ +/* and bad offset values are written to that file for testing */ +#define MISC33_FILE "bad_offset.h5" + /**************************************************************** ** ** test_misc1(): test unlinking a dataset from a group and immediately @@ -5472,6 +5477,55 @@ test_misc32(void) } /* end test_misc32() */ +/**************************************************************** +** +** test_misc33(): Test for H5FFV-10216 +** --verify that H5HL_offset_into() returns error if the +** input parameter "offset" exceeds heap data block size. +** --case (1), (2), (3) are scenarios that will traverse to the +** the 3 locations in the file having bad offset values to +** the heap. (See description in gen_bad_offset.c) +** +****************************************************************/ +static void +test_misc33(void) +{ + hid_t fid = -1; /* File ID */ + const char *testfile = H5_get_srcdir_filename(MISC33_FILE); /* Corrected test file name */ + H5O_info_t oinfo; /* Structure for object metadata information */ + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing that bad offset into the heap returns error")); + + /* Open the test file */ + fid = H5Fopen(testfile, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK(fid, FAIL, "H5Fopen"); + + /* Case (1) */ + H5E_BEGIN_TRY { + ret = H5Oget_info_by_name(fid, "/soft_two", &oinfo, H5P_DEFAULT); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Oget_info_by_name"); + + /* Case (2) */ + H5E_BEGIN_TRY { + ret = H5Oget_info_by_name(fid, "/dsetA", &oinfo, H5P_DEFAULT); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Oget_info_by_name"); + + /* Case (3) */ + H5E_BEGIN_TRY { + ret = H5Oget_info_by_name(fid, "/soft_one", &oinfo, H5P_DEFAULT); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Oget_info_by_name"); + + /* Close the file */ + ret = H5Fclose(fid); + CHECK(fid, FAIL, "H5Fclose"); + +} /* end test_misc33() */ + /**************************************************************** ** @@ -5520,6 +5574,7 @@ test_misc(void) test_misc30(); /* Exercise local heap loading bug where free lists were getting dropped */ test_misc31(); /* Test Reentering library through deprecated routines after H5close() */ test_misc32(); /* Test filter memory allocation functions */ + test_misc33(); /* Test to verify that H5HL_offset_into() returns error if offset exceeds heap block */ } /* test_misc() */ diff --git a/tools/lib/h5tools_ref.c b/tools/lib/h5tools_ref.c index e000080..16a949d 100644 --- a/tools/lib/h5tools_ref.c +++ b/tools/lib/h5tools_ref.c @@ -164,7 +164,8 @@ haddr_t ref_path_table_lookup(const char *thepath) { H5O_info_t oi; - + if((HDstrlen(thepath) == 0) || (thepath == NULL)) + return HADDR_UNDEF; /* Allow lookups on the root group, even though it doesn't have any link info */ if(HDstrcmp(thepath, "/")) { H5L_info_t li; diff --git a/tools/src/h5dump/h5dump_xml.c b/tools/src/h5dump/h5dump_xml.c index 49d4f96..d731013 100644 --- a/tools/src/h5dump/h5dump_xml.c +++ b/tools/src/h5dump/h5dump_xml.c @@ -1959,28 +1959,32 @@ xml_dump_data(hid_t obj_id, int obj_data, struct subset_t H5_ATTR_UNUSED * sset, H5Tclose(type); space = H5Aget_space(obj_id); + if(space == H5S_NULL || space == H5S_NO_CLASS) { + status = SUCCEED; + } + else { + ndims = H5Sget_simple_extent_dims(space, size, NULL); - ndims = H5Sget_simple_extent_dims(space, size, NULL); + for (i = 0; i < ndims; i++) + nelmts *= size[i]; - for (i = 0; i < ndims; i++) - nelmts *= size[i]; + buf = HDmalloc((size_t)(nelmts * MAX(H5Tget_size(type), H5Tget_size(p_type)))); + HDassert(buf); - buf = HDmalloc((size_t)(nelmts * MAX(H5Tget_size(type), H5Tget_size(p_type)))); - HDassert(buf); + if (H5Aread(obj_id, p_type, buf) >= 0) { + h5tools_context_t datactx; + HDmemset(&datactx, 0, sizeof(datactx)); + datactx.need_prefix = TRUE; + datactx.indent_level = ctx.indent_level; + datactx.cur_column = ctx.cur_column; + status = h5tools_dump_mem(rawoutstream, outputformat, &datactx, obj_id, p_type, space, buf); + } + /* Reclaim any VL memory, if necessary */ + if (vl_data) + H5Dvlen_reclaim(p_type, space, H5P_DEFAULT, buf); - if (H5Aread(obj_id, p_type, buf) >= 0) { - h5tools_context_t datactx; - HDmemset(&datactx, 0, sizeof(datactx)); - datactx.need_prefix = TRUE; - datactx.indent_level = ctx.indent_level; - datactx.cur_column = ctx.cur_column; - status = h5tools_dump_mem(rawoutstream, outputformat, &datactx, obj_id, p_type, space, buf); + HDfree(buf); } - /* Reclaim any VL memory, if necessary */ - if (vl_data) - H5Dvlen_reclaim(p_type, space, H5P_DEFAULT, buf); - - HDfree(buf); H5Tclose(p_type); H5Sclose(space); H5Tclose(type); diff --git a/tools/src/h5ls/h5ls.c b/tools/src/h5ls/h5ls.c index 8c18794..a181186 100644 --- a/tools/src/h5ls/h5ls.c +++ b/tools/src/h5ls/h5ls.c @@ -1617,38 +1617,40 @@ list_attr(hid_t obj, const char *attr_name, const H5A_info_t H5_ATTR_UNUSED *ain info = &outputformat; - if(hexdump_g) - p_type = H5Tcopy(type); - else - p_type = H5Tget_native_type(type, H5T_DIR_DEFAULT); - - if(p_type >= 0) { - /* VL data special information */ - unsigned int vl_data = 0; /* contains VL datatypes */ - - /* Check if we have VL data in the dataset's datatype */ - if (h5tools_detect_vlen(p_type) == TRUE) - vl_data = TRUE; - - temp_need= nelmts * MAX(H5Tget_size(type), H5Tget_size(p_type)); - HDassert(temp_need == (hsize_t)((size_t)temp_need)); - need = (size_t)temp_need; - buf = HDmalloc(need); - HDassert(buf); - if(H5Aread(attr, p_type, buf) >= 0) { - ctx.need_prefix = TRUE; - ctx.indent_level = 2; - ctx.cur_column = (size_t)curr_pos; - h5tools_dump_mem(rawoutstream, info, &ctx, attr, p_type, space, buf); - } + if(space_type != H5S_NULL && space_type != H5S_NO_CLASS) { + if(hexdump_g) + p_type = H5Tcopy(type); + else + p_type = H5Tget_native_type(type, H5T_DIR_DEFAULT); + + if(p_type >= 0) { + /* VL data special information */ + unsigned int vl_data = 0; /* contains VL datatypes */ + + /* Check if we have VL data in the dataset's datatype */ + if (h5tools_detect_vlen(p_type) == TRUE) + vl_data = TRUE; + + temp_need= nelmts * MAX(H5Tget_size(type), H5Tget_size(p_type)); + HDassert(temp_need == (hsize_t)((size_t)temp_need)); + need = (size_t)temp_need; + buf = HDmalloc(need); + HDassert(buf); + if(H5Aread(attr, p_type, buf) >= 0) { + ctx.need_prefix = TRUE; + ctx.indent_level = 2; + ctx.cur_column = (size_t)curr_pos; + h5tools_dump_mem(rawoutstream, info, &ctx, attr, p_type, space, buf); + } - /* Reclaim any VL memory, if necessary */ - if (vl_data) - H5Dvlen_reclaim(p_type, space, H5P_DEFAULT, buf); + /* Reclaim any VL memory, if necessary */ + if (vl_data) + H5Dvlen_reclaim(p_type, space, H5P_DEFAULT, buf); - HDfree(buf); - H5Tclose(p_type); - } /* end if */ + HDfree(buf); + H5Tclose(p_type); + } /* end if */ + } H5Sclose(space); H5Tclose(type); diff --git a/tools/test/h5dump/CMakeTests.cmake b/tools/test/h5dump/CMakeTests.cmake index 0a72709..d3d1c4d 100644 --- a/tools/test/h5dump/CMakeTests.cmake +++ b/tools/test/h5dump/CMakeTests.cmake @@ -104,6 +104,7 @@ ${HDF5_TOOLS_DIR}/testfiles/tgroup-1.ddl ${HDF5_TOOLS_DIR}/testfiles/tgroup-2.ddl ${HDF5_TOOLS_DIR}/testfiles/tgrp_comments.ddl + ${HDF5_TOOLS_DIR}/testfiles/tgrpnullspace.ddl ${HDF5_TOOLS_DIR}/testfiles/thlink-1.ddl ${HDF5_TOOLS_DIR}/testfiles/thlink-2.ddl ${HDF5_TOOLS_DIR}/testfiles/thlink-3.ddl @@ -272,6 +273,7 @@ ${HDF5_TOOLS_DIR}/testfiles/tfvalues.h5 ${HDF5_TOOLS_DIR}/testfiles/tgroup.h5 ${HDF5_TOOLS_DIR}/testfiles/tgrp_comments.h5 + ${HDF5_TOOLS_DIR}/testfiles/tgrpnullspace.h5 ${HDF5_TOOLS_DIR}/testfiles/thlink.h5 ${HDF5_TOOLS_DIR}/testfiles/thyperslab.h5 ${HDF5_TOOLS_DIR}/testfiles/tints4dims.h5 @@ -887,6 +889,8 @@ tgroup-2.out.err tgrp_comments.out tgrp_comments.out.err + tgrpnullspace.out + tgrpnullspace.out.err thlink-1.out thlink-1.out.err thlink-2.out @@ -1394,6 +1398,7 @@ # test for displaying dataset and attribute of null space ADD_H5_TEST (tnullspace 0 --enable-error-stack tnullspace.h5) + ADD_H5_TEST (tgrpnullspace 0 -p --enable-error-stack tgrpnullspace.h5) # test for displaying dataset and attribute of space with 0 dimension size ADD_H5_TEST (zerodim 0 --enable-error-stack zerodim.h5) diff --git a/tools/test/h5dump/CMakeTestsXML.cmake b/tools/test/h5dump/CMakeTestsXML.cmake index bdc6755..e068c5e 100644 --- a/tools/test/h5dump/CMakeTestsXML.cmake +++ b/tools/test/h5dump/CMakeTestsXML.cmake @@ -53,6 +53,7 @@ ${HDF5_TOOLS_DIR}/testfiles/test35.nc ${HDF5_TOOLS_DIR}/testfiles/tnestedcomp.h5 ${HDF5_TOOLS_DIR}/testfiles/tnodata.h5 + ${HDF5_TOOLS_DIR}/testfiles/tnullspace.h5 ${HDF5_TOOLS_DIR}/testfiles/tobjref.h5 ${HDF5_TOOLS_DIR}/testfiles/topaque.h5 ${HDF5_TOOLS_DIR}/testfiles/torderattr.h5 @@ -117,6 +118,7 @@ ${HDF5_TOOLS_DIR}/testfiles/tname-sp.h5.xml ${HDF5_TOOLS_DIR}/testfiles/tnestedcomp.h5.xml ${HDF5_TOOLS_DIR}/testfiles/tnodata.h5.xml + ${HDF5_TOOLS_DIR}/testfiles/tnullspace.h5.xml ${HDF5_TOOLS_DIR}/testfiles/tobjref.h5.xml ${HDF5_TOOLS_DIR}/testfiles/topaque.h5.xml ${HDF5_TOOLS_DIR}/testfiles/torderattr1.h5.xml @@ -296,6 +298,8 @@ tnodata.h5.out.err tnoname.h5.out tnoname.h5.out.err + tnullspace.h5.out + tnullspace.h5.out.err tobjref.h5.out tobjref.h5.out.err topaque.h5.out @@ -402,9 +406,7 @@ ADD_XML_H5_TEST (tsaf.h5 0 tsaf.h5) ADD_XML_H5_TEST (tempty.h5 0 tempty.h5) ADD_XML_H5_TEST (tnamed_dtype_attr.h5 0 tnamed_dtype_attr.h5) - ##Test dataset and attribute of null space. Commented out: - ## wait until the XML schema is updated for null space. - ## ADD_XML_H5_TEST (tnullspace.h5 0 tnulspace.h5) + ADD_XML_H5_TEST (tnullspace.h5 0 tnullspace.h5) ## So is dataspace with 0 dimension size. ## ADD_XML_H5_TEST (zerodim.h5 0 zerodim.h5) diff --git a/tools/test/h5dump/h5dumpgentest.c b/tools/test/h5dump/h5dumpgentest.c index 2128acb..0eaa2d0 100644 --- a/tools/test/h5dump/h5dumpgentest.c +++ b/tools/test/h5dump/h5dumpgentest.c @@ -112,6 +112,7 @@ #define FILE82 "tcompound_complex2.h5" #define FILE83 "tvlenstr_array.h5" #define FILE84 "tudfilter.h5" +#define FILE85 "tgrpnullspace.h5" /*------------------------------------------------------------------------- * prototypes @@ -286,9 +287,9 @@ typedef struct s1_t { #define F64_DIM1 (F64_ARRAY_BUF_LEN / sizeof(int) + 1) /* File 65 macros */ -#define STRATEGY H5F_FSPACE_STRATEGY_NONE /* File space handling strategy */ -#define THRESHOLD10 10 /* Free-space section threshold */ -#define FSPACE_PAGE_SIZE 8192 /* File space page size */ +#define STRATEGY H5F_FSPACE_STRATEGY_NONE /* File space handling strategy */ +#define THRESHOLD10 10 /* Free-space section threshold */ +#define FSPACE_PAGE_SIZE 8192 /* File space page size */ /* "FILE66" macros and for FILE69 */ #define F66_XDIM 8 @@ -7041,8 +7042,8 @@ gent_extlinks(void) * Function: gent_fs_strategy_threshold * * Purpose: Generate a file with non-default file space strategy, - * non-default free-space section threshold, - * non-default file space page size. + * non-default free-space section threshold, + * non-default file space page size. *------------------------------------------------------------------------- */ static void @@ -9721,7 +9722,7 @@ static void gent_bitnopaquefields(void) uint32_t c; uint64_t d; } s_t; - + hid_t file, grp=-1, type=-1, space=-1, dset=-1; size_t i; hsize_t nelmts = F80_DIM32; @@ -10437,6 +10438,43 @@ H5Z_filter_dynlibud(unsigned int flags, size_t cd_nelmts, *------------------------------------------------------------------------- */ +/*------------------------------------------------------------------------- + * Function: gent_null_space_group + * + * Purpose: generates dataset and attribute of null dataspace in a group + *------------------------------------------------------------------------- + */ +static void gent_null_space_group(void) +{ + hid_t fid, root, group, dataset, space, attr; + int dset_buf = 10; + int point = 4; + + fid = H5Fcreate(FILE85, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + root = H5Gopen2(fid, "/", H5P_DEFAULT); + + group = H5Gcreate2(fid, "/g1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + /* null space */ + space = H5Screate(H5S_NULL); + + /* dataset */ + dataset = H5Dcreate2(group, "dset", H5T_STD_I32BE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + /* nothing should be written */ + H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &dset_buf); + + /* attribute */ + attr = H5Acreate2(group, "attr", H5T_NATIVE_UINT, space, H5P_DEFAULT, H5P_DEFAULT); + H5Awrite(attr, H5T_NATIVE_INT, &point); /* Nothing can be written */ + + H5Dclose(dataset); + H5Aclose(attr); + H5Gclose(group); + H5Gclose(root); + H5Sclose(space); + H5Fclose(fid); +} + int main(void) { gent_group(); @@ -10526,6 +10564,7 @@ int main(void) gent_bitnopaquefields(); gent_intsfourdims(); + gent_null_space_group(); gent_udfilter(); diff --git a/tools/test/h5dump/testh5dump.sh.in b/tools/test/h5dump/testh5dump.sh.in index f0c01e6..1935b0d 100644 --- a/tools/test/h5dump/testh5dump.sh.in +++ b/tools/test/h5dump/testh5dump.sh.in @@ -132,6 +132,7 @@ $SRC_H5DUMP_TESTFILES/tfpformat.h5 $SRC_H5DUMP_TESTFILES/tfvalues.h5 $SRC_H5DUMP_TESTFILES/tgroup.h5 $SRC_H5DUMP_TESTFILES/tgrp_comments.h5 +$SRC_H5DUMP_TESTFILES/tgrpnullspace.h5 $SRC_H5DUMP_TESTFILES/thlink.h5 $SRC_H5DUMP_TESTFILES/thyperslab.h5 $SRC_H5DUMP_TESTFILES/tintsattrs.h5 @@ -260,6 +261,7 @@ $SRC_H5DUMP_TESTFILES/tfpformat.ddl $SRC_H5DUMP_TESTFILES/tgroup-1.ddl $SRC_H5DUMP_TESTFILES/tgroup-2.ddl $SRC_H5DUMP_TESTFILES/tgrp_comments.ddl +$SRC_H5DUMP_TESTFILES/tgrpnullspace.ddl $SRC_H5DUMP_TESTFILES/thlink-1.ddl $SRC_H5DUMP_TESTFILES/thlink-2.ddl $SRC_H5DUMP_TESTFILES/thlink-3.ddl @@ -1268,6 +1270,7 @@ TOOLTEST thyperslab.ddl --enable-error-stack thyperslab.h5 # test for displaying dataset and attribute of null space TOOLTEST tnullspace.ddl --enable-error-stack tnullspace.h5 +TOOLTEST tgrpnullspace.ddl -p --enable-error-stack tgrpnullspace.h5 # test for displaying dataset and attribute of space with 0 dimension size TOOLTEST zerodim.ddl --enable-error-stack zerodim.h5 diff --git a/tools/test/h5dump/testh5dumpxml.sh.in b/tools/test/h5dump/testh5dumpxml.sh.in index b3b9e14..f7af300 100644 --- a/tools/test/h5dump/testh5dumpxml.sh.in +++ b/tools/test/h5dump/testh5dumpxml.sh.in @@ -97,6 +97,7 @@ $SRC_H5DUMP_TESTFILES/tname-sp.h5 $SRC_H5DUMP_TESTFILES/tnamed_dtype_attr.h5 $SRC_H5DUMP_TESTFILES/tnestedcomp.h5 $SRC_H5DUMP_TESTFILES/tnodata.h5 +$SRC_H5DUMP_TESTFILES/tnullspace.h5 $SRC_H5DUMP_TESTFILES/tobjref.h5 $SRC_H5DUMP_TESTFILES/topaque.h5 $SRC_H5DUMP_TESTFILES/torderattr.h5 @@ -162,6 +163,7 @@ $SRC_H5DUMP_TESTFILES/tname-quot.h5.xml $SRC_H5DUMP_TESTFILES/tname-sp.h5.xml $SRC_H5DUMP_TESTFILES/tnestedcomp.h5.xml $SRC_H5DUMP_TESTFILES/tnodata.h5.xml +$SRC_H5DUMP_TESTFILES/tnullspace.h5.xml $SRC_H5DUMP_TESTFILES/tobjref.h5.xml $SRC_H5DUMP_TESTFILES/topaque.h5.xml $SRC_H5DUMP_TESTFILES/torderattr1.h5.xml @@ -355,9 +357,7 @@ TOOLTEST tvlstr.h5.xml --xml tvlstr.h5 TOOLTEST tsaf.h5.xml --xml tsaf.h5 TOOLTEST tempty.h5.xml --xml tempty.h5 TOOLTEST tnamed_dtype_attr.h5.xml --xml tnamed_dtype_attr.h5 -##Test dataset and attribute of null space. Commented out: -## wait until the XML schema is updated for null space. -##TOOLTEST tnullspace.h5.xml --xml tnulspace.h5 +TOOLTEST tnullspace.h5.xml --xml tnullspace.h5 # other options for xml diff --git a/tools/test/h5ls/CMakeTests.cmake b/tools/test/h5ls/CMakeTests.cmake index 5f61eab..a04a4b6 100644 --- a/tools/test/h5ls/CMakeTests.cmake +++ b/tools/test/h5ls/CMakeTests.cmake @@ -33,6 +33,7 @@ ${HDF5_TOOLS_DIR}/testfiles/textlinktar.h5 ${HDF5_TOOLS_DIR}/testfiles/tgroup.h5 ${HDF5_TOOLS_DIR}/testfiles/tgrp_comments.h5 + ${HDF5_TOOLS_DIR}/testfiles/tgrpnullspace.h5 ${HDF5_TOOLS_DIR}/testfiles/thlink.h5 ${HDF5_TOOLS_DIR}/testfiles/tloop.h5 ${HDF5_TOOLS_DIR}/testfiles/tnestedcomp.h5 @@ -89,6 +90,7 @@ ${HDF5_TOOLS_DIR}/testfiles/tgroup-1.ls ${HDF5_TOOLS_DIR}/testfiles/tgroup-2.ls ${HDF5_TOOLS_DIR}/testfiles/tgroup-3.ls + ${HDF5_TOOLS_DIR}/testfiles/tgrpnullspace.ls ${HDF5_TOOLS_DIR}/testfiles/thlink-1.ls ${HDF5_TOOLS_DIR}/testfiles/tloop-1.ls ${HDF5_TOOLS_DIR}/testfiles/tmultifile.ls @@ -241,6 +243,8 @@ textlinksrc-7-old.out.err tgrp_comments.out tgrp_comments.out.err + tgrpnullspace.out + tgrpnullspace.out.err tsoftlinks-1.out tsoftlinks-1.out.err tsoftlinks-2.out @@ -415,6 +419,9 @@ # test for empty data ADD_H5_TEST (tempty 0 -w80 -d tempty.h5) + # test for displaying dataset and attribute of null space + ADD_H5_TEST (tgrpnullspace 0 -w80 -v -S tgrpnullspace.h5) + # test for all dataset types written to attributes # enable -S for avoiding printing NATIVE types ADD_H5_TEST (tattr2 0 -w80 -v -S tattr2.h5) diff --git a/tools/test/h5ls/testh5ls.sh.in b/tools/test/h5ls/testh5ls.sh.in index a88ae88..8c6551b 100644 --- a/tools/test/h5ls/testh5ls.sh.in +++ b/tools/test/h5ls/testh5ls.sh.in @@ -80,6 +80,7 @@ $SRC_H5LS_TESTFILES/textlinksrc.h5 $SRC_H5LS_TESTFILES/textlinktar.h5 $SRC_H5LS_TESTFILES/tgroup.h5 $SRC_H5LS_TESTFILES/tgrp_comments.h5 +$SRC_H5LS_TESTFILES/tgrpnullspace.h5 $SRC_H5LS_TESTFILES/thlink.h5 $SRC_H5LS_TESTFILES/tloop.h5 $SRC_H5LS_TESTFILES/tnestedcomp.h5 @@ -135,6 +136,7 @@ $SRC_H5LS_TESTFILES/tgroup.ls $SRC_H5LS_TESTFILES/tgroup-1.ls $SRC_H5LS_TESTFILES/tgroup-2.ls $SRC_H5LS_TESTFILES/tgroup-3.ls +$SRC_H5LS_TESTFILES/tgrpnullspace.ls $SRC_H5LS_TESTFILES/thlink-1.ls $SRC_H5LS_TESTFILES/tloop-1.ls $SRC_H5LS_TESTFILES/tmultifile.ls @@ -392,6 +394,9 @@ TOOLTEST tarray1.ls 0 -w80 -r -d tarray1.h5 # test for empty data TOOLTEST tempty.ls 0 -w80 -d tempty.h5 +# test for displaying dataset and attribute of null space +TOOLTEST tgrpnullspace.ls 0 -w80 -v -S tgrpnullspace.h5 + # test for all dataset types written to attributes # enable -S for avoiding printing NATIVE types TOOLTEST tattr2.ls 0 -w80 -v -S tattr2.h5 diff --git a/tools/testfiles/tgrpnullspace.ddl b/tools/testfiles/tgrpnullspace.ddl new file mode 100644 index 0000000..2b91527 --- /dev/null +++ b/tools/testfiles/tgrpnullspace.ddl @@ -0,0 +1,33 @@ +HDF5 "tgrpnullspace.h5" { +GROUP "/" { + GROUP "g1" { + ATTRIBUTE "attr" { + DATATYPE H5T_STD_U32LE + DATASPACE NULL + DATA { + } + } + DATASET "dset" { + DATATYPE H5T_STD_I32BE + DATASPACE NULL + STORAGE_LAYOUT { + CONTIGUOUS + SIZE 0 + OFFSET 18446744073709551615 + } + FILTERS { + NONE + } + FILLVALUE { + FILL_TIME H5D_FILL_TIME_IFSET + VALUE H5D_FILL_VALUE_DEFAULT + } + ALLOCATION_TIME { + H5D_ALLOC_TIME_LATE + } + DATA { + } + } + } +} +} diff --git a/tools/testfiles/tgrpnullspace.h5 b/tools/testfiles/tgrpnullspace.h5 Binary files differnew file mode 100644 index 0000000..82a405e --- /dev/null +++ b/tools/testfiles/tgrpnullspace.h5 diff --git a/tools/testfiles/tgrpnullspace.ls b/tools/testfiles/tgrpnullspace.ls new file mode 100644 index 0000000..439414c --- /dev/null +++ b/tools/testfiles/tgrpnullspace.ls @@ -0,0 +1,7 @@ +Opened "tgrpnullspace.h5" with sec2 driver. +g1 Group + Attribute: attr null + Type: 32-bit little-endian unsigned integer + + Location: 1:800 + Links: 1 diff --git a/tools/testfiles/tnullspace.h5.xml b/tools/testfiles/tnullspace.h5.xml new file mode 100644 index 0000000..b1c1974 --- /dev/null +++ b/tools/testfiles/tnullspace.h5.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<hdf5:HDF5-File xmlns:hdf5="http://hdfgroup.org/HDF5/XML/schema/HDF5-File.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://hdfgroup.org/HDF5/XML/schema/HDF5-File http://www.hdfgroup.org/HDF5/XML/schema/HDF5-File.xsd"> +<hdf5:RootGroup OBJ-XID="xid_928" H5Path="/"> + <hdf5:Attribute Name="attr"> + <hdf5:Dataspace> + <!-- unknown dataspace --> + </hdf5:Dataspace> + <hdf5:DataType> + <hdf5:AtomicType> + <hdf5:IntegerType ByteOrder="LE" Sign="false" Size="4" /> + </hdf5:AtomicType> + </hdf5:DataType> + <hdf5:Data> + <hdf5:NoData/> + </hdf5:Data> + </hdf5:Attribute> + <hdf5:Dataset Name="dset" OBJ-XID="xid_976" H5Path= "/dset" Parents="xid_928" H5ParentPaths="/"> + <hdf5:StorageLayout> + <hdf5:ContiguousLayout/> + </hdf5:StorageLayout> + <hdf5:FillValueInfo FillTime="FillIfSet" AllocationTime="Late"> + <hdf5:FillValue> + <hdf5:NoFill/> + </hdf5:FillValue> + </hdf5:FillValueInfo> + <hdf5:Dataspace> + <!-- unknown dataspace --> + </hdf5:Dataspace> + <hdf5:DataType> + <hdf5:AtomicType> + <hdf5:IntegerType ByteOrder="BE" Sign="true" Size="4" /> + </hdf5:AtomicType> + </hdf5:DataType> + <hdf5:Data> + <hdf5:NoData/> + </hdf5:Data> + </hdf5:Dataset> +</hdf5:RootGroup> +</hdf5:HDF5-File> |