diff options
author | Mohamad Chaarawi <chaarawi@hdfgroup.org> | 2016-02-18 20:50:37 (GMT) |
---|---|---|
committer | Mohamad Chaarawi <chaarawi@hdfgroup.org> | 2016-02-18 20:50:37 (GMT) |
commit | 70ad55b1052e018acd90b22ab44260a8a1721e0b (patch) | |
tree | 5211dad79d57dcc3875f443557918db8a1b5c6a6 /src/H5B2int.c | |
parent | b3df4e9c8d716db4ea2680f6bb4ac16d1084dea5 (diff) | |
download | hdf5-70ad55b1052e018acd90b22ab44260a8a1721e0b.zip hdf5-70ad55b1052e018acd90b22ab44260a8a1721e0b.tar.gz hdf5-70ad55b1052e018acd90b22ab44260a8a1721e0b.tar.bz2 |
[svn-r29150] fix for Jira issue 9670 - HDF5 segfaults on corrupted file.
Change compare callback in Btree2 class to correctly account for errors.
tested on bb-8.
Diffstat (limited to 'src/H5B2int.c')
-rw-r--r-- | src/H5B2int.c | 60 |
1 files changed, 42 insertions, 18 deletions
diff --git a/src/H5B2int.c b/src/H5B2int.c index 09addce..a184b4b 100644 --- a/src/H5B2int.c +++ b/src/H5B2int.c @@ -134,20 +134,24 @@ H5FL_SEQ_EXTERN(H5B2_node_info_t); * *------------------------------------------------------------------------- */ -int +herr_t H5B2__locate_record(const H5B2_class_t *type, unsigned nrec, size_t *rec_off, - const uint8_t *native, const void *udata, unsigned *idx) + const uint8_t *native, const void *udata, unsigned *idx, int *cmp) { unsigned lo = 0, hi; /* Low & high index values */ unsigned my_idx = 0; /* Final index value */ - int cmp = -1; /* Key comparison value */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE - FUNC_ENTER_PACKAGE_NOERR + *cmp = -1; hi = nrec; - while(lo < hi && cmp) { + while(lo < hi && *cmp) { my_idx = (lo + hi) / 2; - if((cmp = (type->compare)(udata, native + rec_off[my_idx])) < 0) + if((type->compare)(udata, native + rec_off[my_idx], cmp) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records") + if(*cmp < 0) hi = my_idx; else lo = my_idx + 1; @@ -155,7 +159,8 @@ H5B2__locate_record(const H5B2_class_t *type, unsigned nrec, size_t *rec_off, *idx = my_idx; - FUNC_LEAVE_NOAPI(cmp) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5B2__locate_record */ @@ -1614,7 +1619,9 @@ H5B2__insert_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr idx = 0; else { /* Find correct location to insert this record */ - if((cmp = H5B2__locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx)) == 0) + if(H5B2__locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx, &cmp) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records") + if(cmp == 0) HGOTO_ERROR(H5E_BTREE, H5E_EXISTS, FAIL, "record is already in B-tree") if(cmp > 0) idx++; @@ -1711,7 +1718,10 @@ H5B2__insert_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth, size_t split_nrec; /* Number of records to split node at */ /* Locate node pointer for child */ - if((cmp = H5B2__locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx)) == 0) + if(H5B2__locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, + udata, &idx, &cmp) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records") + if(cmp == 0) HGOTO_ERROR(H5E_BTREE, H5E_EXISTS, FAIL, "record is already in B-tree") if(cmp > 0) idx++; @@ -1766,8 +1776,11 @@ H5B2__insert_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth, } /* end else */ /* Locate node pointer for child (after split/redistribute) */ -/* Actually, this can be easily updated (for 2-node redistrib.) and shouldn't require re-searching */ - if((cmp = H5B2__locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx)) == 0) + /* Actually, this can be easily updated (for 2-node redistrib.) and shouldn't require re-searching */ + if(H5B2__locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, + udata, &idx, &cmp) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records") + if(cmp == 0) HGOTO_ERROR(H5E_BTREE, H5E_EXISTS, FAIL, "record is already in B-tree") if(cmp > 0) idx++; @@ -1861,7 +1874,8 @@ H5B2__update_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr idx = 0; else { /* Find correct location to insert this record */ - cmp = H5B2__locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx); + if(H5B2__locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx, &cmp) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records") /* Check for inserting a record */ if(0 != cmp) { @@ -1999,7 +2013,8 @@ H5B2__update_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth, HDassert(internal->nrec == curr_node_ptr->node_nrec); /* Locate node pointer for child */ - cmp = H5B2__locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx); + if(H5B2__locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx, &cmp) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records") /* Check for modifying existing record */ if(0 == cmp) { @@ -2520,6 +2535,7 @@ H5B2__remove_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr haddr_t leaf_addr = HADDR_UNDEF; /* Leaf address on disk */ unsigned leaf_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting leaf node */ unsigned idx; /* Location of record which matches key */ + int cmp; /* Comparison value of records */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -2539,7 +2555,9 @@ H5B2__remove_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr HDassert(leaf->nrec == curr_node_ptr->node_nrec); /* Find correct location to remove this record */ - if(H5B2__locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx) != 0) + if(H5B2__locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx, &cmp) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records") + if(cmp != 0) HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "record is not in B-tree") /* Check for invalidating the min/max record for the tree */ @@ -2683,7 +2701,9 @@ H5B2__remove_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, hbool_t *depth_decreased, if(swap_loc) idx = 0; else { - cmp = H5B2__locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx); + if(H5B2__locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, + udata, &idx, &cmp) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records") if(cmp >= 0) idx++; } /* end else */ @@ -2745,7 +2765,8 @@ H5B2__remove_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, hbool_t *depth_decreased, idx = 0; else { /* Actually, this can be easily updated (for 2-node redistrib.) and shouldn't require re-searching */ - cmp = H5B2__locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx); + if(H5B2__locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx, &cmp) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records") if(cmp >= 0) idx++; } /* end else */ @@ -3229,7 +3250,8 @@ H5B2__neighbor_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_p HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to protect B-tree leaf node") /* Locate node pointer for child */ - cmp = H5B2__locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx); + if(H5B2__locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx, &cmp) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records") if(cmp > 0) idx++; else @@ -3316,7 +3338,9 @@ H5B2__neighbor_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth, HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to protect B-tree internal node") /* Locate node pointer for child */ - cmp = H5B2__locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx); + if(H5B2__locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, + udata, &idx, &cmp) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records") if(cmp > 0) idx++; |