diff options
author | Mohamad Chaarawi <chaarawi@hdfgroup.org> | 2016-02-19 14:53:39 (GMT) |
---|---|---|
committer | Mohamad Chaarawi <chaarawi@hdfgroup.org> | 2016-02-19 14:53:39 (GMT) |
commit | 3e449161fc348f071bbd67253e96840a7585fc25 (patch) | |
tree | 732ee44c1872063efe2ffd2cd2ce8b27e3949c59 /src/H5B2.c | |
parent | d44adaf56192bf1fd6b909559dffdfdec04132e7 (diff) | |
download | hdf5-3e449161fc348f071bbd67253e96840a7585fc25.zip hdf5-3e449161fc348f071bbd67253e96840a7585fc25.tar.gz hdf5-3e449161fc348f071bbd67253e96840a7585fc25.tar.bz2 |
[svn-r29156] merge 29150 from trunk.
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/H5B2.c')
-rw-r--r-- | src/H5B2.c | 41 |
1 files changed, 33 insertions, 8 deletions
@@ -450,8 +450,10 @@ H5B2_find(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_found_t op, * find candidates or avoid further searching. */ if(hdr->min_native_rec != NULL) { - if((cmp = (hdr->cls->compare)(udata, hdr->min_native_rec)) < 0) - HGOTO_DONE(FALSE) /* Less than the least record--not found */ + if((hdr->cls->compare)(udata, hdr->min_native_rec, &cmp) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records") + if(cmp < 0) + HGOTO_DONE(FALSE) /* Less than the least record--not found */ else if(cmp == 0) { /* Record is found */ if(op && (op)(hdr->min_native_rec, op_data) < 0) HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "'found' callback failed for B-tree find operation") @@ -459,8 +461,10 @@ H5B2_find(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_found_t op, } /* end if */ } /* end if */ if(hdr->max_native_rec != NULL) { - if((cmp = (hdr->cls->compare)(udata, hdr->max_native_rec)) > 0) - HGOTO_DONE(FALSE) /* Greater than the greatest record--not found */ + if((hdr->cls->compare)(udata, hdr->max_native_rec, &cmp) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records") + if(cmp > 0) + HGOTO_DONE(FALSE) /* Less than the least record--not found */ else if(cmp == 0) { /* Record is found */ if(op && (op)(hdr->max_native_rec, op_data) < 0) HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "'found' callback failed for B-tree find operation") @@ -483,7 +487,13 @@ H5B2_find(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_found_t op, HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load 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) { + /* Unlock current node before failing */ + H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET); + HGOTO_ERROR(H5E_BTREE, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records") + } + if(cmp > 0) idx++; @@ -546,7 +556,12 @@ H5B2_find(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_found_t op, HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to protect B-tree leaf node") /* Locate 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) { + /* unlock current node before failing */ + H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET); + HGOTO_ERROR(H5E_BTREE, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records") + } if(cmp != 0) { /* Unlock leaf node */ @@ -1074,7 +1089,13 @@ H5B2_modify(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_modify_t op, HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load 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) { + /* Unlock current node */ + H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET); + HGOTO_ERROR(H5E_BTREE, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records") + } + if(cmp > 0) idx++; @@ -1146,7 +1167,11 @@ H5B2_modify(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_modify_t op, HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to protect B-tree leaf node") /* Locate 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) { + H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET); + HGOTO_ERROR(H5E_BTREE, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records") + } if(cmp != 0) { /* Unlock leaf node */ |