From 9aa47d6ad51e5b1651eccb480603094a2e24d115 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 2 Jan 2007 23:42:13 -0500 Subject: [svn-r13100] Description: Fix bug which could possibly corrupt file data if an attribute was renamed to a longer name. Tested on: FreeBSD/32 6.1 (duty) --- src/H5A.c | 2 +- src/H5Oattribute.c | 33 +++++++++++++++++++++++++++++---- src/H5Ocache.c | 13 +++++-------- test/tattr.c | 10 ---------- 4 files changed, 35 insertions(+), 23 deletions(-) diff --git a/src/H5A.c b/src/H5A.c index 072fc99..6021c21 100644 --- a/src/H5A.c +++ b/src/H5A.c @@ -1508,7 +1508,7 @@ H5A_copy(H5A_t *_new_attr, const H5A_t *old_attr) /* Allocate attribute structure */ if(_new_attr == NULL) { - if(NULL == (new_attr = H5FL_CALLOC(H5A_t))) + if(NULL == (new_attr = H5FL_MALLOC(H5A_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") allocated_attr = TRUE; } /* end if */ diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c index 63a35e5..423ffc3 100644 --- a/src/H5Oattribute.c +++ b/src/H5Oattribute.c @@ -808,7 +808,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5O_attr_rename_mod_cb(H5O_t UNUSED *oh, H5O_mesg_t *mesg/*in,out*/, +H5O_attr_rename_mod_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, unsigned UNUSED sequence, unsigned *oh_flags_ptr, void *_udata/*in,out*/) { H5O_iter_ren_t *udata = (H5O_iter_ren_t *)_udata; /* Operator user data */ @@ -850,12 +850,37 @@ HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, H5_ITER_ERROR, "renaming a shared attribu H5MM_xfree(((H5A_t *)mesg->native)->name); ((H5A_t *)mesg->native)->name = H5MM_xstrdup(udata->new_name); - /* Indicate that we found an existing attribute with the old name*/ - udata->found = TRUE; - /* Mark message as dirty */ mesg->dirty = TRUE; + /* Check for attribute name getting longer */ + if(HDstrlen(udata->new_name) > HDstrlen(udata->old_name)) { + /* Increment attribute count */ + /* (must be incremented before call to H5O_msg_append_real(), in order for + * sanity checks to pass - QAK) + */ + if(oh->version > H5O_VERSION_1) + oh->nattrs++; + + /* Append attribute to object header */ + if(H5O_msg_append_real(udata->f, udata->dxpl_id, oh, H5O_MSG_ATTR, 0, 0, mesg->native, oh_flags_ptr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, H5_ITER_ERROR, "unable to relocate attribute in header") + + /* If the later version of the object header format, decrement attribute */ + /* (must be decremented before call to H5O_release_mesg(), in order for + * sanity checks to pass - QAK) + */ + if(oh->version > H5O_VERSION_1) + oh->nattrs--; + + /* Convert message into a null message (i.e. delete it) */ + if(H5O_release_mesg(udata->f, udata->dxpl_id, oh, mesg, TRUE, TRUE) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, H5_ITER_ERROR, "unable to convert into null message") + } /* end if */ + + /* Indicate that we found an existing attribute with the old name */ + udata->found = TRUE; + /* Stop iterating */ ret_value = H5_ITER_STOP; diff --git a/src/H5Ocache.c b/src/H5Ocache.c index 098746b..74083e4 100644 --- a/src/H5Ocache.c +++ b/src/H5Ocache.c @@ -169,19 +169,16 @@ H5O_flush_msgs(H5F_t *f, H5O_t *oh) encode = H5O_MSG_SHARED->encode; else encode = curr_msg->type->encode; -/* XXX: fix me */ -#ifdef NOT_YET +#ifndef NDEBUG +/* Sanity check that the message won't overwrite past it's allocated space */ if(!(curr_msg->flags & H5O_MSG_FLAG_SHARED)) { size_t msg_size; - HDfprintf(stderr, "%s: curr_msg->type->name = '%s'\n", FUNC, curr_msg->type->name); - HDfprintf(stderr, "%s: curr_msg->raw_size = %Zu\n", FUNC, curr_msg->raw_size); msg_size = curr_msg->type->raw_size(f, curr_msg->native); - HDfprintf(stderr, "%s: msg_size = %Zu\n", FUNC, msg_size); - if(msg_size > curr_msg->raw_size) - HDfprintf(stderr, "%s: YOW!\n", FUNC); + msg_size = H5O_ALIGN_OH(oh, msg_size); + HDassert(msg_size <= curr_msg->raw_size); } /* end if */ -#endif /* NOT_YET */ +#endif /* NDEBUG */ if((encode)(f, curr_msg->raw, curr_msg->native) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode object header message") } /* end if */ diff --git a/test/tattr.c b/test/tattr.c index 4bada59..4567ef8 100644 --- a/test/tattr.c +++ b/test/tattr.c @@ -270,12 +270,6 @@ test_attr_basic_write(hid_t fapl) ret=H5Aclose(attr2); CHECK(ret, FAIL, "H5Aclose"); -#ifndef OLD_WAY - /* change first attribute back to the original name */ - ret=H5Arename(dataset, ATTR_TMP_NAME, ATTR1_NAME); - CHECK(ret, FAIL, "H5Arename"); -#endif /* OLD_WAY */ - ret = H5Sclose(sid1); CHECK(ret, FAIL, "H5Sclose"); ret = H5Sclose(sid2); @@ -363,11 +357,7 @@ test_attr_basic_read(hid_t fapl) VERIFY(ret, 2, "H5Aget_num_attrs"); /* Open first attribute for the dataset */ -#ifndef OLD_WAY - attr=H5Aopen_name(dataset, ATTR1_NAME); -#else /* OLD_WAY */ attr=H5Aopen_name(dataset, ATTR_TMP_NAME); -#endif /* OLD_WAY */ CHECK(attr, FAIL, "H5Aopen_name"); /* Read attribute information */ -- cgit v0.12