diff options
author | Allen Byrne <byrn@hdfgroup.org> | 2017-09-13 13:47:07 (GMT) |
---|---|---|
committer | Allen Byrne <byrn@hdfgroup.org> | 2017-09-13 13:47:07 (GMT) |
commit | 11a16203c5617cd58c4ab64ed08c3f01129d1707 (patch) | |
tree | 84dcecb49a27fe84129ef875f1fa8da746cb5570 | |
parent | e12411c48048d8a802ee0adb6fd3a57692a10919 (diff) | |
parent | fff22784451a27fe33ca7571f1144d015d6379fb (diff) | |
download | hdf5-11a16203c5617cd58c4ab64ed08c3f01129d1707.zip hdf5-11a16203c5617cd58c4ab64ed08c3f01129d1707.tar.gz hdf5-11a16203c5617cd58c4ab64ed08c3f01129d1707.tar.bz2 |
Merging in latest from upstream (HDFFV/hdf5:refs/heads/hdf5_1_8)
* commit 'fff22784451a27fe33ca7571f1144d015d6379fb':
Fix for HDFFV-9947 Fix to return error when encoding dataspace selection exceeds 32 bit integer limit.
Add info for release notes
Fix for daily test failure Fix for the compilation error from the PGI compiler.
Modifications based on comments from pull request review (1) Remove unnecessary asserts (2) Add code to insert bad offset values to the test file in gen_bad_offset.c
Fix for HDFFV-10216 segfault in H5G_node_cmp3 with corrupt h5 file Fix H5HL_offset_into() to return error when offset exceeds heap data block size. Also fix other places that call this routine to detect error return.
-rw-r--r-- | MANIFEST | 2 | ||||
-rw-r--r-- | release_docs/RELEASE.txt | 9 | ||||
-rw-r--r-- | src/H5Gent.c | 20 | ||||
-rw-r--r-- | src/H5Glink.c | 27 | ||||
-rw-r--r-- | src/H5Gnode.c | 779 | ||||
-rw-r--r-- | src/H5Gstab.c | 22 | ||||
-rw-r--r-- | src/H5HL.c | 15 | ||||
-rw-r--r-- | src/H5Oefl.c | 50 | ||||
-rw-r--r-- | src/H5Shyper.c | 55 | ||||
-rw-r--r-- | src/H5Spkg.h | 3 | ||||
-rw-r--r-- | src/H5Spoint.c | 24 | ||||
-rw-r--r-- | test/CMakeTests.cmake | 2 | ||||
-rw-r--r-- | test/Makefile.am | 2 | ||||
-rw-r--r-- | test/bad_offset.h5 | bin | 0 -> 3312 bytes | |||
-rw-r--r-- | test/gen_bad_offset.c | 147 | ||||
-rw-r--r-- | test/th5s.c | 97 | ||||
-rw-r--r-- | test/tmisc.c | 55 |
17 files changed, 832 insertions, 477 deletions
@@ -831,6 +831,7 @@ ./test/accum.c ./test/app_ref.c ./test/bad_compound.h5 +./test/bad_offset.h5 ./test/be_data.h5 ./test/be_extlink1.h5 ./test/be_extlink2.h5 @@ -876,6 +877,7 @@ ./test/fixed_idx.h5 ./test/flush1.c ./test/flush2.c +./test/gen_bad_offset.c ./test/gen_bad_ohdr.c ./test/gen_bad_compound.c ./test/gen_bogus.c diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 5b21e77..f8136b9 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -130,7 +130,14 @@ Bug Fixes since HDF5-1.8.19 Library ------- - - None + - Fix H5HL_offset_into() + + (1) Fix H5HL_offset_into() to return error when offset exceeds heap data + block size. + (2) Fix other places in the library that call this routine to detect + error routine. + + (HDFFV-10216, VC, 2017/09/05) Parallel Library diff --git a/src/H5Gent.c b/src/H5Gent.c index 05e8b3c..bb6aa38 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 7b99207..255add0 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 12e0d5e..2c4b840 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 H5RC_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; + 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))) - 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_WRITE))) - 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_WRITE))) - 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_WRITE))) + 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 -= 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 -= 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_WRITE))) - 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))) - 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))) - 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))) - 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, H5RC_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))) - 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))) @@ -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") /* Insert the new object in the destination file's group */ /* (Don't increment the link count - that's already done above for hard links) */ @@ -1377,15 +1358,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 * *------------------------------------------------------------------------- */ @@ -1393,10 +1374,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 @@ -1412,7 +1393,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))) - 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) { @@ -1431,8 +1412,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++; @@ -1465,8 +1446,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 */ @@ -1483,16 +1464,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 * *------------------------------------------------------------------------- */ @@ -1500,10 +1481,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) @@ -1530,33 +1511,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 */ @@ -1564,7 +1545,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 f9a8884..0eb7b0b 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) @@ -533,17 +533,18 @@ done: void * H5HL_offset_into(const H5HL_t *heap, size_t offset) { - /* - * We need to have called some other function before this to get a - * valid heap pointer. So, this can remain "FUNC_ENTER_NOAPI_NOINIT" - */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + void *ret_value = NULL; + + FUNC_ENTER_NOAPI(NULL) /* Sanity check */ HDassert(heap); - HDassert(offset < heap->dblk_size); + if(offset >= heap->dblk_size) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, NULL, "unable to offset into local heap data block") + ret_value = heap->dblk_image + offset; - FUNC_LEAVE_NOAPI(heap->dblk_image + offset) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5HL_offset_into() */ diff --git a/src/H5Oefl.c b/src/H5Oefl.c index 1de3059..218d250 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; /* 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))) 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/src/H5Shyper.c b/src/H5Shyper.c index 32f6200..09d450f 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -2071,21 +2071,53 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf) { const H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */ hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary hyperslab counts */ - hsize_t offset[H5O_LAYOUT_NDIMS]; /* Offset of element in dataspace */ - hsize_t start[H5O_LAYOUT_NDIMS]; /* Location of start of hyperslab */ - hsize_t end[H5O_LAYOUT_NDIMS]; /* Location of end of hyperslab */ - hsize_t temp_off; /* Offset in a given dimension */ + hsize_t offset[H5O_LAYOUT_NDIMS]; /* Offset of element in dataspace */ + hsize_t start[H5O_LAYOUT_NDIMS]; /* Location of start of hyperslab */ + hsize_t end[H5O_LAYOUT_NDIMS]; /* Location of end of hyperslab */ + hsize_t bounds_start[H5S_MAX_RANK]; /* Selection bounds */ + hsize_t bounds_end[H5S_MAX_RANK]; /* Selection bounds */ + hsize_t temp_off; /* Offset in a given dimension */ uint8_t *lenp; /* pointer to length location for later storage */ uint32_t len = 0; /* number of bytes used */ hsize_t block_count; /* block counter for regular hyperslabs */ unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */ unsigned ndims; /* Rank of the dataspace */ int done; /* Whether we are done with the iteration */ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_NOAPI_NOINIT HDassert(space); + /* Set some convienence values */ + ndims = space->extent.rank; + fast_dim = ndims - 1; + diminfo=space->select.sel_info.hslab->opt_diminfo; + + /* Calculate the # of blocks */ + if(H5S_hyper_is_regular(space)) { + /* Check each dimension */ + for(block_count = 1, u = 0; u < ndims; u++) + block_count *= diminfo[u].count; + } /* end if */ + else + /* Spin through hyperslab spans */ + block_count = H5S_hyper_span_nblocks(space->select.sel_info.hslab->span_lst); + + /* Get bounding box */ + if(H5S_hyper_bounds(space, bounds_start, bounds_end) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get selection bounds") + + /* Determine whether the number of blocks or the high bounds in the selection exceed (2^32 - 1) */ + if(block_count > H5S_UINT32_MAX) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "invalid number of blocks in selection") + else { + for(u = 0; u < ndims; u++) + if(bounds_end[u] > H5S_UINT32_MAX) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "invalid hyperslab selection") + } + /* Store the preamble information */ UINT32ENCODE(buf, (uint32_t)H5S_GET_SELECT_TYPE(space)); /* Store the type of selection */ UINT32ENCODE(buf, (uint32_t)1); /* Store the version number */ @@ -2101,15 +2133,6 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf) if(space->select.sel_info.hslab->diminfo_valid) { unsigned u; /* Local counting variable */ - /* Set some convienence values */ - ndims = space->extent.rank; - fast_dim = ndims - 1; - diminfo=space->select.sel_info.hslab->opt_diminfo; - - /* Check each dimension */ - for(block_count = 1, u = 0; u < ndims; u++) - block_count *= diminfo[u].count; - /* Encode number of hyperslabs */ H5_CHECK_OVERFLOW(block_count, hsize_t, uint32_t); UINT32ENCODE(buf, (uint32_t)block_count); @@ -2188,7 +2211,6 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf) } /* end if */ else { /* Encode number of hyperslabs */ - block_count = H5S_hyper_span_nblocks(space->select.sel_info.hslab->span_lst); H5_CHECK_OVERFLOW(block_count, hsize_t, uint32_t); UINT32ENCODE(buf, (uint32_t)block_count); len+=4; @@ -2204,7 +2226,8 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf) /* Encode length */ UINT32ENCODE(lenp, (uint32_t)len); /* Store the length of the extra information */ - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* H5S_hyper_serialize() */ diff --git a/src/H5Spkg.h b/src/H5Spkg.h index 2fa872b..0597994 100644 --- a/src/H5Spkg.h +++ b/src/H5Spkg.h @@ -46,6 +46,9 @@ * and 'size' callbacks for places to change when updating this. */ #define H5O_SDSPACE_VERSION_LATEST H5O_SDSPACE_VERSION_2 +/* Maximum values for uint16_t and uint32_t */ +#define H5S_UINT16_MAX 65535 /* 2^16 - 1 */ +#define H5S_UINT32_MAX 4294967295 /* 2^32 - 1 */ /* * Dataspace extent information diff --git a/src/H5Spoint.c b/src/H5Spoint.c index 36684ea..e1dbb4d 100644 --- a/src/H5Spoint.c +++ b/src/H5Spoint.c @@ -821,12 +821,29 @@ H5S_point_serialize (const H5S_t *space, uint8_t *buf) H5S_pnt_node_t *curr; /* Point information nodes */ uint8_t *lenp; /* pointer to length location for later storage */ uint32_t len=0; /* number of bytes used */ - unsigned u; /* local counting variable */ + unsigned u; /* local counting variable */ + hsize_t bounds_start[H5S_MAX_RANK]; /* Selection bounding box */ + hsize_t bounds_end[H5S_MAX_RANK]; /* Selection bounding box */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_NOAPI_NOINIT HDassert(space); + /* Get bounding box for the selection */ + HDmemset(bounds_end, 0, sizeof(bounds_end)); + if(H5S_point_bounds(space, bounds_start, bounds_end) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get selection bounds") + + /* Determine whether the number of points or the high bounds in the selection exceed (2^32 - 1) */ + if(space->select.num_elem > H5S_UINT32_MAX) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "invalid number of points in selection") + else { + for(u = 0; u < space->extent.rank; u++) + if(bounds_end[u] > H5S_UINT32_MAX) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "invalid points selection") + } + /* Store the preamble information */ UINT32ENCODE(buf, (uint32_t)H5S_GET_SELECT_TYPE(space)); /* Store the type of selection */ UINT32ENCODE(buf, (uint32_t)1); /* Store the version number */ @@ -858,7 +875,8 @@ H5S_point_serialize (const H5S_t *space, uint8_t *buf) /* Encode length */ UINT32ENCODE(lenp, (uint32_t)len); /* Store the length of the extra information */ - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* H5S_point_serialize() */ diff --git a/test/CMakeTests.cmake b/test/CMakeTests.cmake index 154fed9..8e2c48b 100644 --- a/test/CMakeTests.cmake +++ b/test/CMakeTests.cmake @@ -103,6 +103,7 @@ endif () # -------------------------------------------------------------------- set (HDF5_REFERENCE_TEST_FILES bad_compound.h5 + bad_offset.h5 be_data.h5 be_extlink1.h5 be_extlink2.h5 @@ -1016,6 +1017,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 7fbccdd..7c55e5b 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -67,7 +67,7 @@ endif BUILD_ALL_PROGS=gen_bad_ohdr gen_bogus gen_cross gen_deflate gen_filters gen_idx \ gen_new_array gen_new_fill gen_new_group gen_new_mtime gen_new_super \ gen_noencoder gen_nullspace gen_udlinks space_overflow gen_sizes_lheap \ - gen_file_image + gen_file_image 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/th5s.c b/test/th5s.c index 98be156..c56f0cc 100644 --- a/test/th5s.c +++ b/test/th5s.c @@ -1317,6 +1317,102 @@ test_h5s_encode(void) /**************************************************************** ** +** test_h5s_encode_exceed32(): +** Verify that encoding selection that exceeds (2^32 - 1) +** (32 bit integer limit) will return error. +** See HDFFV-9947 and the RFC for "H5Sencode/H5Sdecode Format Change" +** +****************************************************************/ +static void +test_h5s_encode_exceed32(void) +{ + hid_t sid; /* Dataspace ID */ + size_t hyper_buf_size=0, pt_buf_size=0; /* Buffer size for H5Sencode */ + unsigned char *hyper_buf=NULL, *pt_buf=NULL; /* Buffers for H5Sencode */ + hsize_t numparticles = 8388608; + unsigned num_dsets = 513; + hsize_t total_particles = numparticles * num_dsets; + hsize_t vdsdims[1] = {total_particles}; + hsize_t start, count, block; /* Hyperslab selection specification */ + hsize_t coord[4]; /* Coordinates for point selection */ + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing Dataspace Encoding Exceeding 32 bits integer limit\n")); + + /*------------------------------------------------------------------------- + * Test encoding and decoding of simple dataspace and hyperslab selection. + *------------------------------------------------------------------------- + */ + + /* Create dataspace */ + sid = H5Screate_simple(1, vdsdims, NULL); + CHECK(sid, FAIL, "H5Screate_simple"); + + start = 0; + block = total_particles; /* 4303355904 (exceeds 2^32) */ + count = 1; + + ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, &start, NULL, &count, &block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + /* Encode data space in a buffer */ + ret = H5Sencode(sid, NULL, &hyper_buf_size); + CHECK(ret, FAIL, "H5Sencode"); + + /* Allocate buffer */ + if(hyper_buf_size > 0) { + hyper_buf = (unsigned char*)HDcalloc((size_t)1, hyper_buf_size); + CHECK(hyper_buf, NULL, "HDcalloc"); + } + + /* H5Sencode should fail because block exceeds (2^32 - 1) */ + H5E_BEGIN_TRY { + ret = H5Sencode(sid, hyper_buf, &hyper_buf_size); + } H5E_END_TRY + VERIFY(ret, FAIL, "H5Sencode"); + + /*------------------------------------------------------------------------- + * Test encoding and decoding of simple dataspace and points selection. + *------------------------------------------------------------------------- + */ + + /* Select points in dataspace */ + coord[0] = 5; + coord[1] = 15; + coord[2] = 4294967296; /* 2^32 */ + coord[3] = 19; + ret = H5Sselect_elements(sid, H5S_SELECT_SET, (size_t)4, coord); + CHECK(ret, FAIL, "H5Sselect_elements"); + + /* Encode data space in a buffer */ + ret = H5Sencode(sid, NULL, &pt_buf_size); + CHECK(ret, FAIL, "H5Sencode"); + + /* Allocate buffer */ + if(pt_buf_size > 0) + pt_buf = (unsigned char*)HDcalloc((size_t)1, pt_buf_size); + + /* H5Sencode should fail because coord[2] exceeds (2^32 - 1) */ + H5E_BEGIN_TRY { + ret = H5Sencode(sid, pt_buf, &pt_buf_size); + } H5E_END_TRY + VERIFY(ret, FAIL, "H5Sencode"); + + /* Close the dataspace */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + + /* Free the buffers */ + if(hyper_buf) + HDfree(hyper_buf); + if(pt_buf) + HDfree(pt_buf); + +} /* test_h5s_encode_exceed32() */ + +/**************************************************************** +** ** test_h5s_scalar_write(): Test scalar H5S (dataspace) writing code. ** ****************************************************************/ @@ -2384,6 +2480,7 @@ test_h5s(void) test_h5s_null(); /* Test Null dataspace H5S code */ test_h5s_zero_dim(); /* Test dataspace with zero dimension size */ test_h5s_encode(); /* Test encoding and decoding */ + test_h5s_encode_exceed32(); /* Testing encoding when selection exceeds 32 bits limit */ test_h5s_scalar_write(); /* Test scalar H5S writing code */ test_h5s_scalar_read(); /* Test scalar H5S reading code */ diff --git a/test/tmisc.c b/test/tmisc.c index 9766816..aae1a99 100644 --- a/test/tmisc.c +++ b/test/tmisc.c @@ -323,6 +323,11 @@ unsigned m13_rdata[MISC13_DIM1][MISC13_DIM2]; /* Data read from dataset #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 @@ -5423,6 +5428,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() */ + /**************************************************************** ** @@ -5471,6 +5525,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() */ |