summaryrefslogtreecommitdiffstats
path: root/src/H5B2int.c
diff options
context:
space:
mode:
authorMohamad Chaarawi <chaarawi@hdfgroup.org>2016-02-18 20:50:37 (GMT)
committerMohamad Chaarawi <chaarawi@hdfgroup.org>2016-02-18 20:50:37 (GMT)
commit70ad55b1052e018acd90b22ab44260a8a1721e0b (patch)
tree5211dad79d57dcc3875f443557918db8a1b5c6a6 /src/H5B2int.c
parentb3df4e9c8d716db4ea2680f6bb4ac16d1084dea5 (diff)
downloadhdf5-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.c60
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++;