diff options
author | Neil Fortner <nfortne2@hdfgroup.org> | 2008-08-11 15:18:54 (GMT) |
---|---|---|
committer | Neil Fortner <nfortne2@hdfgroup.org> | 2008-08-11 15:18:54 (GMT) |
commit | f040f990a065db070a83e3217c209a83e204d6ca (patch) | |
tree | fc5d0086189dfb23a1c30f88b66ccf32cdbb550c /src | |
parent | 2df9af6ae8fd7bf4658e702b3e5046382dc5a852 (diff) | |
download | hdf5-f040f990a065db070a83e3217c209a83e204d6ca.zip hdf5-f040f990a065db070a83e3217c209a83e204d6ca.tar.gz hdf5-f040f990a065db070a83e3217c209a83e204d6ca.tar.bz2 |
[svn-r15459] Purpose: Modify the library to take the proper action when files with incorrect
datatype versions are encountered.
Description: The library now recognizes some problems with datatype versions in
H5O_decode_helper(), and, if not performing strict format checks, automatically
corrects them. Framework added for other message decode routines to
automatically correct file errors. Datatype version information added to
h5debug. Resolves bz#1236, 1266. Test files with incorrect datatype versions
corrected.
Tested: kagiso, smirom, linew (h5committest)
Diffstat (limited to 'src')
-rw-r--r-- | src/H5O.c | 3 | ||||
-rw-r--r-- | src/H5Oainfo.c | 5 | ||||
-rw-r--r-- | src/H5Oalloc.c | 14 | ||||
-rw-r--r-- | src/H5Oattr.c | 9 | ||||
-rw-r--r-- | src/H5Oattribute.c | 3 | ||||
-rw-r--r-- | src/H5Obogus.c | 5 | ||||
-rw-r--r-- | src/H5Obtreek.c | 5 | ||||
-rw-r--r-- | src/H5Ocache.c | 18 | ||||
-rw-r--r-- | src/H5Ocont.c | 5 | ||||
-rw-r--r-- | src/H5Ocopy.c | 7 | ||||
-rw-r--r-- | src/H5Odbg.c | 2 | ||||
-rw-r--r-- | src/H5Odrvinfo.c | 5 | ||||
-rw-r--r-- | src/H5Odtype.c | 95 | ||||
-rw-r--r-- | src/H5Oefl.c | 5 | ||||
-rw-r--r-- | src/H5Ofill.c | 10 | ||||
-rw-r--r-- | src/H5Oginfo.c | 5 | ||||
-rw-r--r-- | src/H5Olayout.c | 5 | ||||
-rw-r--r-- | src/H5Olinfo.c | 5 | ||||
-rw-r--r-- | src/H5Olink.c | 5 | ||||
-rw-r--r-- | src/H5Omessage.c | 15 | ||||
-rw-r--r-- | src/H5Omtime.c | 10 | ||||
-rw-r--r-- | src/H5Oname.c | 5 | ||||
-rw-r--r-- | src/H5Opkg.h | 21 | ||||
-rw-r--r-- | src/H5Opline.c | 5 | ||||
-rw-r--r-- | src/H5Orefcount.c | 5 | ||||
-rw-r--r-- | src/H5Osdspace.c | 5 | ||||
-rw-r--r-- | src/H5Oshared.c | 11 | ||||
-rw-r--r-- | src/H5Oshared.h | 15 | ||||
-rw-r--r-- | src/H5Oshmesg.c | 5 | ||||
-rw-r--r-- | src/H5Ostab.c | 5 | ||||
-rw-r--r-- | src/H5T.c | 5 |
31 files changed, 218 insertions, 100 deletions
@@ -2274,7 +2274,8 @@ H5O_get_info(H5O_loc_t *oloc, hid_t dxpl_id, hbool_t want_ih_info, H5O_info_t *o HDassert(oinfo); /* Get the object header */ - if(NULL == (oh = H5AC_protect(oloc->file, dxpl_id, H5AC_OHDR, oloc->addr, NULL, NULL, H5AC_READ))) + if(NULL == (oh = H5AC_protect(oloc->file, dxpl_id, H5AC_OHDR, oloc->addr, NULL, NULL, + (H5F_get_intent(oloc->file) & H5F_ACC_RDWR) ? H5AC_WRITE : H5AC_READ))) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header") /* Reset the object info structure */ diff --git a/src/H5Oainfo.c b/src/H5Oainfo.c index 968b165..15613c2 100644 --- a/src/H5Oainfo.c +++ b/src/H5Oainfo.c @@ -35,7 +35,8 @@ /* PRIVATE PROTOTYPES */ -static void *H5O_ainfo_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p); +static void *H5O_ainfo_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, + unsigned *ioflags, const uint8_t *p); static herr_t H5O_ainfo_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg); static void *H5O_ainfo_copy(const void *_mesg, void *_dest); static size_t H5O_ainfo_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg); @@ -102,7 +103,7 @@ H5FL_DEFINE_STATIC(H5O_ainfo_t); */ static void * H5O_ainfo_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags, - const uint8_t *p) + unsigned UNUSED *ioflags, const uint8_t *p) { H5O_ainfo_t *ainfo = NULL; /* Attribute info */ unsigned char flags; /* Flags for encoding attribute info */ diff --git a/src/H5Oalloc.c b/src/H5Oalloc.c index 03eb956..f90e95a 100644 --- a/src/H5Oalloc.c +++ b/src/H5Oalloc.c @@ -1482,12 +1482,7 @@ H5O_remove_empty_chunks(H5F_t *f, H5O_t *oh, hid_t dxpl_id) for(v = 0, cont_msg = &oh->mesg[0]; v < oh->nmesgs; v++, cont_msg++) { if(H5O_CONT_ID == cont_msg->type->id) { /* Decode current continuation message if necessary */ - if(NULL == cont_msg->native) { - HDassert(H5O_MSG_CONT->decode); - cont_msg->native = (H5O_MSG_CONT->decode)(f, dxpl_id, 0, cont_msg->raw); - if(NULL == cont_msg->native) - HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode message") - } /* end if */ + H5O_LOAD_NATIVE(f, dxpl_id, 0, oh, cont_msg, FAIL) /* Check for correct chunk to delete */ if(oh->chunk[null_msg->chunkno].addr == ((H5O_cont_t *)(cont_msg->native))->addr) @@ -1545,12 +1540,7 @@ H5O_remove_empty_chunks(H5F_t *f, H5O_t *oh, hid_t dxpl_id) /* Check for continuation message */ if(H5O_CONT_ID == curr_msg->type->id) { /* Decode current continuation message if necessary */ - if(NULL == curr_msg->native) { - HDassert(H5O_MSG_CONT->decode); - curr_msg->native = (H5O_MSG_CONT->decode)(f, dxpl_id, 0, curr_msg->raw); - if(NULL == curr_msg->native) - HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode message") - } /* end if */ + H5O_LOAD_NATIVE(f, dxpl_id, 0, oh, curr_msg, FAIL) /* Check for pointer to chunk after deleted chunk */ if(((H5O_cont_t *)(curr_msg->native))->chunkno > deleted_chunkno) diff --git a/src/H5Oattr.c b/src/H5Oattr.c index 4bfeb3d..ced85c2 100644 --- a/src/H5Oattr.c +++ b/src/H5Oattr.c @@ -30,7 +30,8 @@ /* PRIVATE PROTOTYPES */ static herr_t H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg); -static void *H5O_attr_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p); +static void *H5O_attr_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, + unsigned *ioflags, const uint8_t *p); static void *H5O_attr_copy(const void *_mesg, void *_dest); static size_t H5O_attr_size(const H5F_t *f, const void *_mesg); static herr_t H5O_attr_free(void *mesg); @@ -124,7 +125,7 @@ H5FL_EXTERN(H5S_extent_t); --------------------------------------------------------------------------*/ static void * H5O_attr_decode(H5F_t *f, hid_t dxpl_id, unsigned UNUSED mesg_flags, - const uint8_t *p) + unsigned *ioflags, const uint8_t *p) { H5A_t *attr = NULL; H5S_extent_t *extent; /*extent dimensionality information */ @@ -184,7 +185,7 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, unsigned UNUSED mesg_flags, p += name_len; /* advance the memory pointer */ /* Decode the attribute's datatype */ - if((attr->shared->dt = (H5T_t *)(H5O_MSG_DTYPE->decode)(f, dxpl_id, ((flags & H5O_ATTR_FLAG_TYPE_SHARED) ? H5O_MSG_FLAG_SHARED : 0), p)) == NULL) + if((attr->shared->dt = (H5T_t *)(H5O_MSG_DTYPE->decode)(f, dxpl_id, ((flags & H5O_ATTR_FLAG_TYPE_SHARED) ? H5O_MSG_FLAG_SHARED : 0), ioflags, p)) == NULL) HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute datatype") if(attr->shared->version < H5O_ATTR_VERSION_2) p += H5O_ALIGN_OLD(attr->shared->dt_size); @@ -198,7 +199,7 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, unsigned UNUSED mesg_flags, HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Decode attribute's dataspace extent */ - if((extent = (H5S_extent_t *)(H5O_MSG_SDSPACE->decode)(f, dxpl_id, ((flags & H5O_ATTR_FLAG_SPACE_SHARED) ? H5O_MSG_FLAG_SHARED : 0), p)) == NULL) + if((extent = (H5S_extent_t *)(H5O_MSG_SDSPACE->decode)(f, dxpl_id, ((flags & H5O_ATTR_FLAG_SPACE_SHARED) ? H5O_MSG_FLAG_SHARED : 0), ioflags, p)) == NULL) HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute dataspace") /* Copy the extent information to the dataspace */ diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c index 701dd05..b3a3dc9 100644 --- a/src/H5Oattribute.c +++ b/src/H5Oattribute.c @@ -1206,7 +1206,8 @@ H5O_attr_iterate_real(hid_t loc_id, const H5O_loc_t *loc, hid_t dxpl_id, HDassert(attr_op); /* Protect the object header to iterate over */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) + if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, + NULL, NULL, (H5F_get_intent(loc->file) & H5F_ACC_RDWR) ? H5AC_WRITE : H5AC_READ))) HGOTO_ERROR(H5E_ATTR, H5E_CANTLOAD, FAIL, "unable to load object header") /* Check for attribute info stored */ diff --git a/src/H5Obogus.c b/src/H5Obogus.c index 1233ec0..c257ca4 100644 --- a/src/H5Obogus.c +++ b/src/H5Obogus.c @@ -38,7 +38,8 @@ #ifdef H5O_ENABLE_BOGUS /* PRIVATE PROTOTYPES */ -static void *H5O_bogus_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p); +static void *H5O_bogus_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, + unsigned *ioflags, const uint8_t *p); static herr_t H5O_bogus_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg); static size_t H5O_bogus_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg); static herr_t H5O_bogus_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream, @@ -87,7 +88,7 @@ const H5O_msg_class_t H5O_MSG_BOGUS[1] = {{ */ static void * H5O_bogus_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags, - const uint8_t *p) + unsigned UNUSED *ioflags, const uint8_t *p) { H5O_bogus_t *mesg = NULL; void *ret_value; /* Return value */ diff --git a/src/H5Obtreek.c b/src/H5Obtreek.c index e116ff2..40cc1c8 100644 --- a/src/H5Obtreek.c +++ b/src/H5Obtreek.c @@ -28,7 +28,8 @@ #include "H5Opkg.h" /* Object headers */ #include "H5MMprivate.h" /* Memory management */ -static void *H5O_btreek_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p); +static void *H5O_btreek_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, + unsigned *ioflags, const uint8_t *p); static herr_t H5O_btreek_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg); static void *H5O_btreek_copy(const void *_mesg, void *_dest); static size_t H5O_btreek_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg); @@ -79,7 +80,7 @@ const H5O_msg_class_t H5O_MSG_BTREEK[1] = {{ */ static void * H5O_btreek_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags, - const uint8_t *p) + unsigned UNUSED *ioflags, const uint8_t *p) { H5O_btreek_t *mesg; /* Native message */ void *ret_value; /* Return value */ diff --git a/src/H5Ocache.c b/src/H5Ocache.c index 0d5765e..96aebeb 100644 --- a/src/H5Ocache.c +++ b/src/H5Ocache.c @@ -536,9 +536,10 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, /* Check if next message to examine is a continuation message */ if(H5O_CONT_ID == oh->mesg[curmesg].type->id) { H5O_cont_t *cont; + unsigned ioflags = 0; /* Flags for decode routine */ /* Decode continuation message */ - cont = (H5O_cont_t *)(H5O_MSG_CONT->decode)(f, dxpl_id, 0, oh->mesg[curmesg].raw); + cont = (H5O_cont_t *)(H5O_MSG_CONT->decode)(f, dxpl_id, 0, &ioflags, oh->mesg[curmesg].raw); cont->chunkno = oh->nchunks; /*the next chunk to allocate */ /* Save 'native' form of continuation message */ @@ -547,14 +548,21 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, /* Set up to read in next chunk */ chunk_addr = cont->addr; chunk_size = cont->size; + + /* Mark the object header as dirty if the message was changed by decoding */ + if((ioflags & H5O_DECODEIO_DIRTY) && (H5F_get_intent(f) & H5F_ACC_RDWR)) { + oh->mesg[curmesg].dirty = TRUE; + oh->cache_info.is_dirty = TRUE; + } } /* end if */ /* Check if next message to examine is a ref. count message */ else if(H5O_REFCOUNT_ID == oh->mesg[curmesg].type->id) { H5O_refcount_t *refcount; + unsigned ioflags = 0; /* Flags for decode routine */ /* Decode ref. count message */ HDassert(oh->version > H5O_VERSION_1); - refcount = (H5O_refcount_t *)(H5O_MSG_REFCOUNT->decode)(f, dxpl_id, 0, oh->mesg[curmesg].raw); + refcount = (H5O_refcount_t *)(H5O_MSG_REFCOUNT->decode)(f, dxpl_id, 0, &ioflags, oh->mesg[curmesg].raw); /* Save 'native' form of ref. count message */ oh->mesg[curmesg].native = refcount; @@ -562,6 +570,12 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, /* Set object header values */ oh->has_refcount_msg = TRUE; oh->nlink = *refcount; + + /* Mark the object header as dirty if the message was changed by decoding */ + if((ioflags & H5O_DECODEIO_DIRTY) && (H5F_get_intent(f) & H5F_ACC_RDWR)) { + oh->mesg[curmesg].dirty = TRUE; + oh->cache_info.is_dirty = TRUE; + } } /* end if */ /* Check if next message to examine is a link message */ else if(H5O_LINK_ID == oh->mesg[curmesg].type->id) { diff --git a/src/H5Ocont.c b/src/H5Ocont.c index 92c4a3c..433b178 100644 --- a/src/H5Ocont.c +++ b/src/H5Ocont.c @@ -37,7 +37,8 @@ /* PRIVATE PROTOTYPES */ -static void *H5O_cont_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p); +static void *H5O_cont_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, + unsigned *ioflags, const uint8_t *p); static herr_t H5O_cont_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg); static size_t H5O_cont_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg); static herr_t H5O_cont_free(void *mesg); @@ -90,7 +91,7 @@ H5FL_DEFINE(H5O_cont_t); */ static void * H5O_cont_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags, - const uint8_t *p) + unsigned UNUSED *ioflags, const uint8_t *p) { H5O_cont_t *cont = NULL; void *ret_value; diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c index 4c6092d..91400f5 100644 --- a/src/H5Ocopy.c +++ b/src/H5Ocopy.c @@ -315,7 +315,8 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, HDassert(cpy_info); /* Get source object header */ - if(NULL == (oh_src = (H5O_t *)H5AC_protect(oloc_src->file, dxpl_id, H5AC_OHDR, oloc_src->addr, NULL, NULL, H5AC_READ))) + if(NULL == (oh_src = (H5O_t *)H5AC_protect(oloc_src->file, dxpl_id, H5AC_OHDR, oloc_src->addr, NULL, NULL, + (H5F_get_intent(oloc_src->file) & H5F_ACC_RDWR) ? H5AC_WRITE : H5AC_READ))) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header") /* Get pointer to object class for this object */ @@ -396,7 +397,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, if(copy_type->pre_copy_file) { /* Decode the message if necessary. */ - H5O_LOAD_NATIVE(oloc_src->file, dxpl_id, oh_src, mesg_src, FAIL) + H5O_LOAD_NATIVE(oloc_src->file, dxpl_id, 0, oh_src, mesg_src, FAIL) /* Perform "pre copy" operation on message */ if((copy_type->pre_copy_file)(oloc_src->file, mesg_src->native, &(deleted[mesgno]), cpy_info, udata) < 0) @@ -467,7 +468,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, hbool_t recompute_size; /* Whether copy_file callback created a shared message */ /* Decode the message if necessary. */ - H5O_LOAD_NATIVE(oloc_src->file, dxpl_id, oh_src, mesg_src, FAIL) + H5O_LOAD_NATIVE(oloc_src->file, dxpl_id, 0, oh_src, mesg_src, FAIL) /* Copy the source message */ recompute_size = FALSE; diff --git a/src/H5Odbg.c b/src/H5Odbg.c index e77dcfd..01fd925 100644 --- a/src/H5Odbg.c +++ b/src/H5Odbg.c @@ -488,7 +488,7 @@ H5O_debug_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, haddr_t addr, FILE *stream, i /* decode the message */ debug_type = oh->mesg[i].type; if(NULL == oh->mesg[i].native && debug_type->decode) - H5O_LOAD_NATIVE(f, dxpl_id, oh, &oh->mesg[i], FAIL) + H5O_LOAD_NATIVE(f, dxpl_id, H5O_DECODEIO_NOCHANGE, oh, &oh->mesg[i], FAIL) /* print the message */ HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3), diff --git a/src/H5Odrvinfo.c b/src/H5Odrvinfo.c index fd2d049..7ee37a0 100644 --- a/src/H5Odrvinfo.c +++ b/src/H5Odrvinfo.c @@ -28,7 +28,8 @@ #include "H5Opkg.h" /* Object headers */ #include "H5MMprivate.h" /* Memory management */ -static void *H5O_drvinfo_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p); +static void *H5O_drvinfo_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, + unsigned *ioflags, const uint8_t *p); static herr_t H5O_drvinfo_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg); static void *H5O_drvinfo_copy(const void *_mesg, void *_dest); static size_t H5O_drvinfo_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg); @@ -80,7 +81,7 @@ const H5O_msg_class_t H5O_MSG_DRVINFO[1] = {{ */ static void * H5O_drvinfo_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags, - const uint8_t *p) + unsigned UNUSED *ioflags, const uint8_t *p) { H5O_drvinfo_t *mesg; /* Native message */ void *ret_value; /* Return value */ diff --git a/src/H5Odtype.c b/src/H5Odtype.c index ba343bc..9c669e0 100644 --- a/src/H5Odtype.c +++ b/src/H5Odtype.c @@ -29,7 +29,8 @@ /* PRIVATE PROTOTYPES */ static herr_t H5O_dtype_encode(H5F_t *f, uint8_t *p, const void *mesg); -static void *H5O_dtype_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p); +static void *H5O_dtype_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, + unsigned *ioflags, const uint8_t *p); static void *H5O_dtype_copy(const void *_mesg, void *_dest); static size_t H5O_dtype_size(const H5F_t *f, const void *_mesg); static herr_t H5O_dtype_reset(void *_mesg); @@ -65,6 +66,25 @@ static herr_t H5O_dtype_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, #define H5O_SHARED_DEBUG_REAL H5O_dtype_debug #include "H5Oshared.h" /* Shared Object Header Message Callbacks */ +/* Macros to check for the proper version of a datatype */ +#ifdef H5_STRICT_FORMAT_CHECKS +/* If the version is too low, give an error. No error if nochange is set + * because in that case we are either debugging or deleting the object header */ +#define H5O_DTYPE_CHECK_VERSION(DT, VERS, MIN_VERS, IOF, CLASS, ERR) \ + if(((VERS) < (MIN_VERS)) && !(*(IOF) & H5O_DECODEIO_NOCHANGE)) \ + HGOTO_ERROR(H5E_DATATYPE, H5E_VERSION, ERR, "incorrect " CLASS " datatype version") +#else /* H5_STRICT_FORMAT_CHECKS */ +/* If the version is too low and we are allowed to change the message, upgrade + * it and mark the object header as dirty */ +#define H5O_DTYPE_CHECK_VERSION(DT, VERS, MIN_VERS, IOF, CLASS, ERR) \ + if(((VERS) < (MIN_VERS)) && !(*(IOF) & H5O_DECODEIO_NOCHANGE)) { \ + (VERS) = (MIN_VERS); \ + if(H5T_upgrade_version((DT), (VERS)) < 0) \ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't upgrade " CLASS " encoding version") \ + *(IOF) |= H5O_DECODEIO_DIRTY; \ + } /* end if */ +#endif /* H5_STRICT_FORMAT_CHECKS */ + /* This message derives from H5O message class */ const H5O_msg_class_t H5O_MSG_DTYPE[1] = {{ H5O_DTYPE_ID, /* message id number */ @@ -103,7 +123,7 @@ const H5O_msg_class_t H5O_MSG_DTYPE[1] = {{ *------------------------------------------------------------------------- */ static herr_t -H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt) +H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **pp, H5T_t *dt) { unsigned flags, version; unsigned i; @@ -233,6 +253,7 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt) { unsigned offset_nbytes; /* Size needed to encode member offsets */ size_t max_memb_pos = 0; /* Maximum member covered, so far */ + unsigned max_version = 0; /* Maximum member version */ unsigned j; /* Compute the # of bytes required to store a member offset */ @@ -297,13 +318,17 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") /* Decode the field's datatype information */ - if(H5O_dtype_decode_helper(f, pp, temp_type) < 0) { + if(H5O_dtype_decode_helper(f, ioflags, pp, temp_type) < 0) { for(j = 0; j <= i; j++) H5MM_xfree(dt->shared->u.compnd.memb[j].name); H5MM_xfree(dt->shared->u.compnd.memb); HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "unable to decode member type") } /* end if */ + /* Keep track of the maximum member version found */ + if(temp_type->shared->version > max_version) + max_version = temp_type->shared->version; + /* Go create the array datatype now, for older versions of the datatype message */ if(version == H5O_DTYPE_VERSION_1) { /* Check if this member is an array field */ @@ -372,6 +397,9 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt) dt->shared->u.compnd.packed = FALSE; } /* end if */ } /* end for */ + /* Check that no member of this compound has a version greater + * than the compound itself. */ + H5O_DTYPE_CHECK_VERSION(dt, version, max_version, ioflags, "compound", FAIL) } break; @@ -402,8 +430,14 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt) dt->shared->u.enumer.nmembs = dt->shared->u.enumer.nalloc = flags & 0xffff; if(NULL == (dt->shared->parent = H5T_alloc())) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - if(H5O_dtype_decode_helper(f, pp, dt->shared->parent) < 0) + if(H5O_dtype_decode_helper(f, ioflags, pp, dt->shared->parent) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "unable to decode parent datatype") + + /* Check if the parent of this enum has a version greater than the + * enum itself. */ + H5O_DTYPE_CHECK_VERSION(dt, version, dt->shared->parent->shared->version, + ioflags, "enum", FAIL) + if(NULL == (dt->shared->u.enumer.name = (char **)H5MM_calloc(dt->shared->u.enumer.nalloc * sizeof(char*))) || NULL == (dt->shared->u.enumer.value = (uint8_t *)H5MM_calloc(dt->shared->u.enumer.nalloc * dt->shared->parent->shared->size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") @@ -438,9 +472,14 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt) /* Decode base type of VL information */ if(NULL == (dt->shared->parent = H5T_alloc())) HGOTO_ERROR(H5E_DATATYPE, H5E_NOSPACE, FAIL, "memory allocation failed") - if(H5O_dtype_decode_helper(f, pp, dt->shared->parent) < 0) + if(H5O_dtype_decode_helper(f, ioflags, pp, dt->shared->parent) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "unable to decode VL parent type") + /* Check if the parent of this vlen has a version greater than the + * vlen itself. */ + H5O_DTYPE_CHECK_VERSION(dt, version, dt->shared->parent->shared->version, + ioflags, "vlen", FAIL) + dt->shared->force_conv=TRUE; /* Mark this type as on disk */ if(H5T_set_loc(dt, f, H5T_LOC_DISK) < 0) @@ -471,8 +510,17 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt) /* Decode base type of array */ if(NULL == (dt->shared->parent = H5T_alloc())) HGOTO_ERROR(H5E_DATATYPE, H5E_NOSPACE, FAIL, "memory allocation failed") - if(H5O_dtype_decode_helper(f, pp, dt->shared->parent) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "unable to decode VL parent type") + if(H5O_dtype_decode_helper(f, ioflags, pp, dt->shared->parent) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "unable to decode array parent type") + + /* Check if the parent of this array has a version greater than the + * array itself. */ + H5O_DTYPE_CHECK_VERSION(dt, version, dt->shared->parent->shared->version, + ioflags, "array", FAIL) + + /* There should be no array datatypes with version < 2. */ + H5O_DTYPE_CHECK_VERSION(dt, version, H5O_DTYPE_VERSION_2, ioflags, + "array", FAIL) /* * Set the "force conversion" flag if a VL base datatype is used or @@ -757,6 +805,9 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt) /* Sanity check */ /* (compound datatypes w/array members must be encoded w/version >= 2) */ HDassert(dt->shared->u.compnd.memb[i].type->shared->type != H5T_ARRAY || dt->shared->version >= H5O_DTYPE_VERSION_2); + + /* Check that the version is at least as great as the member */ + HDassert(dt->shared->version >= dt->shared->u.compnd.memb[i].type->shared->version); /* Name */ HDstrcpy((char*)(*pp), dt->shared->u.compnd.memb[i].name); @@ -817,6 +868,9 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt) break; case H5T_ENUM: + /* Check that the version is at least as great as the parent */ + HDassert(dt->shared->version >= dt->shared->parent->shared->version); + /* * Enumeration datatypes... */ @@ -849,6 +903,9 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt) break; case H5T_VLEN: /* Variable length datatypes... */ + /* Check that the version is at least as great as the parent */ + HDassert(dt->shared->version >= dt->shared->parent->shared->version); + flags |= (dt->shared->u.vlen.type & 0x0f); if(dt->shared->u.vlen.type == H5T_VLEN_STRING) { flags |= (dt->shared->u.vlen.pad & 0x0f) << 4; @@ -864,6 +921,12 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt) /* Double-check the number of dimensions */ HDassert(dt->shared->u.array.ndims <= H5S_MAX_RANK); + /* Check that the version is valid */ + HDassert(dt->shared->version >= H5O_DTYPE_VERSION_2); + + /* Check that the version is at least as great as the parent */ + HDassert(dt->shared->version >= dt->shared->parent->shared->version); + /* Encode the number of dimensions */ *(*pp)++ = dt->shared->u.array.ndims; @@ -927,7 +990,8 @@ done: function using malloc() and is returned to the caller. --------------------------------------------------------------------------*/ static void * -H5O_dtype_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags, const uint8_t *p) +H5O_dtype_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags, + unsigned *ioflags/*in,out*/, const uint8_t *p) { H5T_t *dt = NULL; void *ret_value; /* Return value */ @@ -942,21 +1006,13 @@ H5O_dtype_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags, con HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Perform actual decode of message */ - if(H5O_dtype_decode_helper(f, &p, dt) < 0) + if(H5O_dtype_decode_helper(f, ioflags, &p, dt) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, NULL, "can't decode type") /* Set return value */ ret_value = dt; done: - if(ret_value == NULL) { - if(dt != NULL) { - if(dt->shared != NULL) - H5FL_FREE(H5T_shared_t, dt->shared); - H5FL_FREE(H5T_t, dt); - } /* end if */ - } /* end if */ - FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_dtype_decode() */ @@ -1522,6 +1578,9 @@ H5O_dtype_debug(H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *stream, fprintf(stream, "%*s%-*s %lu byte%s\n", indent, "", fwidth, "Size:", (unsigned long)(dt->shared->size), 1 == dt->shared->size ? "" : "s"); + + fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, + "Version:", dt->shared->version); if (H5T_COMPOUND == dt->shared->type) { fprintf(stream, "%*s%-*s %d\n", indent, "", fwidth, @@ -1815,7 +1874,7 @@ H5O_dtype_debug(H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *stream, "Sign scheme:", s); } } - + FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5O_dtype_debug() */ diff --git a/src/H5Oefl.c b/src/H5Oefl.c index 5fa9d6a..5090f9b 100644 --- a/src/H5Oefl.c +++ b/src/H5Oefl.c @@ -29,7 +29,8 @@ #include "H5Opkg.h" /* Object headers */ /* PRIVATE PROTOTYPES */ -static void *H5O_efl_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p); +static void *H5O_efl_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, + unsigned *ioflags, const uint8_t *p); static herr_t H5O_efl_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg); static void *H5O_efl_copy(const void *_mesg, void *_dest); static size_t H5O_efl_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg); @@ -84,7 +85,7 @@ const H5O_msg_class_t H5O_MSG_EFL[1] = {{ */ static void * H5O_efl_decode(H5F_t *f, hid_t dxpl_id, unsigned UNUSED mesg_flags, - const uint8_t *p) + unsigned UNUSED *ioflags, const uint8_t *p) { H5O_efl_t *mesg = NULL; int version; diff --git a/src/H5Ofill.c b/src/H5Ofill.c index 1335274..fccf430 100644 --- a/src/H5Ofill.c +++ b/src/H5Ofill.c @@ -33,10 +33,12 @@ #include "H5Sprivate.h" /* Dataspaces */ -static void *H5O_fill_old_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p); +static void *H5O_fill_old_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, + unsigned *ioflags, const uint8_t *p); static herr_t H5O_fill_old_encode(H5F_t *f, uint8_t *p, const void *_mesg); static size_t H5O_fill_old_size(const H5F_t *f, const void *_mesg); -static void *H5O_fill_new_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p); +static void *H5O_fill_new_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, + unsigned *ioflags, const uint8_t *p); static herr_t H5O_fill_new_encode(H5F_t *f, uint8_t *p, const void *_mesg); static size_t H5O_fill_new_size(const H5F_t *f, const void *_mesg); static void *H5O_fill_copy(const void *_mesg, void *_dest); @@ -181,7 +183,7 @@ H5FL_BLK_EXTERN(type_conv); */ static void * H5O_fill_new_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags, - const uint8_t *p) + unsigned UNUSED *ioflags, const uint8_t *p) { H5O_fill_t *fill = NULL; void *ret_value; @@ -295,7 +297,7 @@ done: */ static void * H5O_fill_old_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags, - const uint8_t *p) + unsigned UNUSED *ioflags, const uint8_t *p) { H5O_fill_t *fill = NULL; /* Decoded fill value message */ void *ret_value; /* Return value */ diff --git a/src/H5Oginfo.c b/src/H5Oginfo.c index 5888f58..850a86a 100644 --- a/src/H5Oginfo.c +++ b/src/H5Oginfo.c @@ -33,7 +33,8 @@ /* PRIVATE PROTOTYPES */ -static void *H5O_ginfo_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p); +static void *H5O_ginfo_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, + unsigned *ioflags, const uint8_t *p); static herr_t H5O_ginfo_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg); static void *H5O_ginfo_copy(const void *_mesg, void *_dest); static size_t H5O_ginfo_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg); @@ -95,7 +96,7 @@ H5FL_DEFINE_STATIC(H5O_ginfo_t); */ static void * H5O_ginfo_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags, - const uint8_t *p) + unsigned UNUSED *ioflags, const uint8_t *p) { H5O_ginfo_t *ginfo = NULL; /* Pointer to group information message */ unsigned char flags; /* Flags for encoding group info */ diff --git a/src/H5Olayout.c b/src/H5Olayout.c index 1f371f3..792c1f0 100644 --- a/src/H5Olayout.c +++ b/src/H5Olayout.c @@ -33,7 +33,8 @@ /* PRIVATE PROTOTYPES */ -static void *H5O_layout_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p); +static void *H5O_layout_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, + unsigned *ioflags, const uint8_t *p); static herr_t H5O_layout_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg); static void *H5O_layout_copy(const void *_mesg, void *_dest); static size_t H5O_layout_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg); @@ -99,7 +100,7 @@ H5FL_DEFINE(H5O_layout_t); */ static void * H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags, - const uint8_t *p) + unsigned UNUSED *ioflags, const uint8_t *p) { H5O_layout_t *mesg = NULL; unsigned u; diff --git a/src/H5Olinfo.c b/src/H5Olinfo.c index 384353c..d96fe82 100644 --- a/src/H5Olinfo.c +++ b/src/H5Olinfo.c @@ -35,7 +35,8 @@ /* PRIVATE PROTOTYPES */ -static void *H5O_linfo_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p); +static void *H5O_linfo_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, + unsigned *ioflags, const uint8_t *p); static herr_t H5O_linfo_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg); static void *H5O_linfo_copy(const void *_mesg, void *_dest); static size_t H5O_linfo_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg); @@ -111,7 +112,7 @@ H5FL_DEFINE_STATIC(H5O_linfo_t); */ static void * H5O_linfo_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags, - const uint8_t *p) + unsigned UNUSED *ioflags, const uint8_t *p) { H5O_linfo_t *linfo = NULL; /* Link info */ unsigned char index_flags; /* Flags for encoding link index info */ diff --git a/src/H5Olink.c b/src/H5Olink.c index 175c937..6298a27 100644 --- a/src/H5Olink.c +++ b/src/H5Olink.c @@ -38,7 +38,8 @@ /* PRIVATE PROTOTYPES */ -static void *H5O_link_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p); +static void *H5O_link_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, + unsigned *ioflags, const uint8_t *p); static herr_t H5O_link_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg); static void *H5O_link_copy(const void *_mesg, void *_dest); static size_t H5O_link_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg); @@ -116,7 +117,7 @@ H5FL_DEFINE_STATIC(H5O_link_t); */ static void * H5O_link_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags, - const uint8_t *p) + unsigned UNUSED *ioflags, const uint8_t *p) { H5O_link_t *lnk = NULL; /* Pointer to link message */ size_t len = 0; /* Length of a string in the message */ diff --git a/src/H5Omessage.c b/src/H5Omessage.c index 3130066..0ff185f 100644 --- a/src/H5Omessage.c +++ b/src/H5Omessage.c @@ -484,7 +484,8 @@ H5O_msg_read(const H5O_loc_t *loc, unsigned type_id, void *mesg, HDassert(type_id < NELMTS(H5O_msg_class_g)); /* Get the object header */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) + if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, + (H5F_get_intent(loc->file) & H5F_ACC_RDWR) ? H5AC_WRITE : H5AC_READ))) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unable to load object header") /* Call the "real" read routine */ @@ -550,7 +551,7 @@ H5O_msg_read_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned type_id, * Decode the message if necessary. If the message is shared then retrieve * native message through the shared interface. */ - H5O_LOAD_NATIVE(f, dxpl_id, oh, &(oh->mesg[idx]), NULL) + H5O_LOAD_NATIVE(f, dxpl_id, 0, oh, &(oh->mesg[idx]), NULL) /* * The object header caches the native message (along with @@ -1230,7 +1231,8 @@ H5O_msg_iterate(const H5O_loc_t *loc, unsigned type_id, HDassert(op); /* Protect the object header to iterate over */ - if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) + if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, + (H5F_get_intent(loc->file) & H5F_ACC_RDWR) ? H5AC_WRITE : H5AC_READ))) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header") /* Call the "real" iterate routine */ @@ -1299,7 +1301,7 @@ H5O_msg_iterate_real(H5F_t *f, H5O_t *oh, const H5O_msg_class_t *type, for(sequence = 0, idx = 0, idx_msg = &oh->mesg[0]; idx < oh->nmesgs && !ret_value; idx++, idx_msg++) { if(type == idx_msg->type) { /* Decode the message if necessary. */ - H5O_LOAD_NATIVE(f, dxpl_id, oh, idx_msg, FAIL) + H5O_LOAD_NATIVE(f, dxpl_id, 0, oh, idx_msg, FAIL) /* Check for making an "internal" (i.e. within the H5O package) callback */ if(op->op_type == H5O_MESG_OP_LIB) @@ -1811,6 +1813,7 @@ H5O_msg_decode(H5F_t *f, hid_t dxpl_id, unsigned type_id, const unsigned char *b { const H5O_msg_class_t *type; /* Actual H5O class type for the ID */ void *ret_value; /* Return value */ + unsigned ioflags = 0; /* Flags for decode routine */ FUNC_ENTER_NOAPI(H5O_msg_decode, NULL) @@ -1821,7 +1824,7 @@ H5O_msg_decode(H5F_t *f, hid_t dxpl_id, unsigned type_id, const unsigned char *b HDassert(type); /* decode */ - if((ret_value = (type->decode)(f, dxpl_id, 0, buf)) == NULL) + if((ret_value = (type->decode)(f, dxpl_id, 0, &ioflags, buf)) == NULL) HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "unable to decode message") done: @@ -2076,7 +2079,7 @@ H5O_delete_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5O_mesg_t *mesg) /* Check if there is a file space deletion callback for this type of message */ if(type->del) { /* Decode the message if necessary. */ - H5O_LOAD_NATIVE(f, dxpl_id, oh, mesg, FAIL) + H5O_LOAD_NATIVE(f, dxpl_id, H5O_DECODEIO_NOCHANGE, oh, mesg, FAIL) if((type->del)(f, dxpl_id, oh, mesg->native) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message") diff --git a/src/H5Omtime.c b/src/H5Omtime.c index df4bdd4..18e35f2 100644 --- a/src/H5Omtime.c +++ b/src/H5Omtime.c @@ -28,11 +28,13 @@ #include "H5Opkg.h" /* Object headers */ -static void *H5O_mtime_new_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p); +static void *H5O_mtime_new_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, + unsigned *ioflags, const uint8_t *p); static herr_t H5O_mtime_new_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg); static size_t H5O_mtime_new_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg); -static void *H5O_mtime_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p); +static void *H5O_mtime_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, + unsigned *ioflags, const uint8_t *p); static herr_t H5O_mtime_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg); static void *H5O_mtime_copy(const void *_mesg, void *_dest); static size_t H5O_mtime_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg); @@ -118,7 +120,7 @@ H5FL_DEFINE(time_t); */ static void * H5O_mtime_new_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags, - const uint8_t *p) + unsigned UNUSED *ioflags, const uint8_t *p) { time_t *mesg; uint32_t tmp_time; /* Temporary copy of the time */ @@ -171,7 +173,7 @@ done: */ static void * H5O_mtime_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags, - const uint8_t *p) + unsigned UNUSED *ioflags, const uint8_t *p) { time_t *mesg, the_time; int i; diff --git a/src/H5Oname.c b/src/H5Oname.c index 44ab432..3b84f75 100644 --- a/src/H5Oname.c +++ b/src/H5Oname.c @@ -33,7 +33,8 @@ /* PRIVATE PROTOTYPES */ -static void *H5O_name_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p); +static void *H5O_name_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, + unsigned *ioflags, const uint8_t *p); static herr_t H5O_name_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg); static void *H5O_name_copy(const void *_mesg, void *_dest); static size_t H5O_name_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg); @@ -84,7 +85,7 @@ const H5O_msg_class_t H5O_MSG_NAME[1] = {{ */ static void * H5O_name_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags, - const uint8_t *p) + unsigned UNUSED *ioflags, const uint8_t *p) { H5O_name_t *mesg; void *ret_value; /* Return value */ diff --git a/src/H5Opkg.h b/src/H5Opkg.h index e2c5661..deffdac 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -174,17 +174,29 @@ #define H5O_SIZEOF_CHKSUM_OH(O) \ H5O_SIZEOF_CHKSUM_VERS((O)->version) +/* Input/output flags for decode functions */ +#define H5O_DECODEIO_NOCHANGE 0x01u /* IN: do not modify values */ +#define H5O_DECODEIO_DIRTY 0x02u /* OUT: message has been changed */ + /* Load native information for a message, if it's not already present */ /* (Only works for messages with decode callback) */ -#define H5O_LOAD_NATIVE(F, DXPL, OH, MSG, ERR) \ +#define H5O_LOAD_NATIVE(F, DXPL, IOF, OH, MSG, ERR) \ if(NULL == (MSG)->native) { \ const H5O_msg_class_t *msg_type = (MSG)->type; \ + unsigned ioflags = (IOF); \ \ /* Decode the message */ \ HDassert(msg_type->decode); \ - if(NULL == ((MSG)->native = (msg_type->decode)((F), (DXPL), (MSG)->flags, (MSG)->raw))) \ + if(NULL == ((MSG)->native = (msg_type->decode)((F), (DXPL), (MSG)->flags, &ioflags, (MSG)->raw))) \ HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, ERR, "unable to decode message") \ \ + /* Mark the object header dirty if the message was changed by decoding */ \ + if((ioflags & H5O_DECODEIO_DIRTY) && (H5F_get_intent((F)) & H5F_ACC_RDWR)) { \ + (MSG)->dirty = TRUE; \ + if(H5AC_mark_pinned_or_protected_entry_dirty((F), (OH)) < 0) \ + HGOTO_ERROR(H5E_OHDR, H5E_CANTMARKDIRTY, ERR, "unable to mark object header as dirty") \ + } \ + \ /* Set the message's "shared info", if it's shareable */ \ if((MSG)->flags & H5O_MSG_FLAG_SHAREABLE) { \ H5O_UPDATE_SHARED((H5O_shared_t *)(MSG)->native, H5O_SHARE_TYPE_HERE, (F), msg_type->id, (MSG)->crt_idx, (OH)->chunk[0].addr) \ @@ -209,7 +221,7 @@ struct H5O_msg_class_t { const char *name; /*for debugging */ size_t native_size; /*size of native message */ unsigned share_flags; /* Message sharing settings */ - void *(*decode)(H5F_t*, hid_t, unsigned, const uint8_t *); + void *(*decode)(H5F_t*, hid_t, unsigned, unsigned *, const uint8_t *); herr_t (*encode)(H5F_t*, hbool_t, uint8_t*, const void *); void *(*copy)(const void *, void *); /*copy native value */ size_t (*raw_size)(const H5F_t *, hbool_t, const void *);/*sizeof encoded message */ @@ -502,7 +514,8 @@ H5_DLL herr_t H5O_release_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5O_mesg_t *mesg, hbool_t adj_link); /* Shared object operators */ -H5_DLL void * H5O_shared_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *buf, const H5O_msg_class_t *type); +H5_DLL void * H5O_shared_decode(H5F_t *f, hid_t dxpl_id, unsigned *ioflags, + const uint8_t *buf, const H5O_msg_class_t *type); H5_DLL herr_t H5O_shared_encode(const H5F_t *f, uint8_t *buf/*out*/, const H5O_shared_t *sh_mesg); H5_DLL size_t H5O_shared_size(const H5F_t *f, const H5O_shared_t *sh_mesg); H5_DLL herr_t H5O_shared_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, diff --git a/src/H5Opline.c b/src/H5Opline.c index 9a926c1..73b71ef 100644 --- a/src/H5Opline.c +++ b/src/H5Opline.c @@ -33,7 +33,8 @@ /* PRIVATE PROTOTYPES */ static herr_t H5O_pline_encode(H5F_t *f, uint8_t *p, const void *mesg); -static void *H5O_pline_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p); +static void *H5O_pline_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, + unsigned *ioflags, const uint8_t *p); static void *H5O_pline_copy(const void *_mesg, void *_dest); static size_t H5O_pline_size(const H5F_t *f, const void *_mesg); static herr_t H5O_pline_reset(void *_mesg); @@ -107,7 +108,7 @@ H5FL_DEFINE(H5O_pline_t); */ static void * H5O_pline_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags, - const uint8_t *p) + unsigned UNUSED *ioflags, const uint8_t *p) { H5O_pline_t *pline = NULL; /* Pipeline message */ H5Z_filter_info_t *filter; /* Filter to decode */ diff --git a/src/H5Orefcount.c b/src/H5Orefcount.c index 0a06d11..77e05f2 100644 --- a/src/H5Orefcount.c +++ b/src/H5Orefcount.c @@ -33,7 +33,8 @@ /* PRIVATE PROTOTYPES */ -static void *H5O_refcount_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p); +static void *H5O_refcount_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, + unsigned *ioflags, const uint8_t *p); static herr_t H5O_refcount_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg); static void *H5O_refcount_copy(const void *_mesg, void *_dest); static size_t H5O_refcount_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg); @@ -90,7 +91,7 @@ H5FL_DEFINE_STATIC(H5O_refcount_t); */ static void * H5O_refcount_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags, - const uint8_t *p) + unsigned UNUSED *ioflags, const uint8_t *p) { H5O_refcount_t *refcount = NULL; /* Reference count */ void *ret_value; /* Return value */ diff --git a/src/H5Osdspace.c b/src/H5Osdspace.c index 414aa98..d272379 100644 --- a/src/H5Osdspace.c +++ b/src/H5Osdspace.c @@ -26,7 +26,8 @@ /* PRIVATE PROTOTYPES */ -static void *H5O_sdspace_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p); +static void *H5O_sdspace_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, + unsigned *ioflags, const uint8_t *p); static herr_t H5O_sdspace_encode(H5F_t *f, uint8_t *p, const void *_mesg); static void *H5O_sdspace_copy(const void *_mesg, void *_dest); static size_t H5O_sdspace_size(const H5F_t *f, const void *_mesg); @@ -109,7 +110,7 @@ H5FL_ARR_EXTERN(hsize_t); --------------------------------------------------------------------------*/ static void * H5O_sdspace_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags, - const uint8_t *p) + unsigned UNUSED *ioflags, const uint8_t *p) { H5S_extent_t *sdim = NULL;/* New extent dimensionality structure */ void *ret_value; diff --git a/src/H5Oshared.c b/src/H5Oshared.c index e406065..aba4ddd 100644 --- a/src/H5Oshared.c +++ b/src/H5Oshared.c @@ -107,8 +107,8 @@ *------------------------------------------------------------------------- */ static void * -H5O_shared_read(H5F_t *f, hid_t dxpl_id, const H5O_shared_t *shared, - const H5O_msg_class_t *type) +H5O_shared_read(H5F_t *f, hid_t dxpl_id, unsigned *ioflags, + const H5O_shared_t *shared, const H5O_msg_class_t *type) { H5HF_t *fheap = NULL; H5WB_t *wb = NULL; /* Wrapped buffer for attribute data */ @@ -159,7 +159,7 @@ H5O_shared_read(H5F_t *f, hid_t dxpl_id, const H5O_shared_t *shared, HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "can't read message from fractal heap.") /* Decode the message */ - if(NULL == (ret_value = (type->decode)(f, dxpl_id, 0, mesg_ptr))) + if(NULL == (ret_value = (type->decode)(f, dxpl_id, 0, ioflags, mesg_ptr))) HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "can't decode shared message.") } /* end if */ else { @@ -277,7 +277,8 @@ done: *------------------------------------------------------------------------- */ void * -H5O_shared_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *buf, const H5O_msg_class_t *type) +H5O_shared_decode(H5F_t *f, hid_t dxpl_id, unsigned *ioflags, + const uint8_t *buf, const H5O_msg_class_t *type) { H5O_shared_t sh_mesg; /* Shared message info */ unsigned version; /* Shared message version */ @@ -343,7 +344,7 @@ H5O_shared_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *buf, const H5O_msg_cla sh_mesg.msg_type_id = type->id; /* Retrieve actual message, through decoded shared message info */ - if(NULL == (ret_value = H5O_shared_read(f, dxpl_id, &sh_mesg, type))) + if(NULL == (ret_value = H5O_shared_read(f, dxpl_id, ioflags, &sh_mesg, type))) HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to retrieve native message") done: diff --git a/src/H5Oshared.h b/src/H5Oshared.h index 582d29b..2e23e60 100644 --- a/src/H5Oshared.h +++ b/src/H5Oshared.h @@ -48,7 +48,8 @@ *------------------------------------------------------------------------- */ static H5_inline void * -H5O_SHARED_DECODE(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p) +H5O_SHARED_DECODE(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, + unsigned *ioflags, const uint8_t *p) { void *ret_value; /* Return value */ @@ -67,12 +68,20 @@ H5O_SHARED_DECODE(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p /* Check for shared message */ if(mesg_flags & H5O_MSG_FLAG_SHARED) { /* Retrieve native message info indirectly through shared message */ - if(NULL == (ret_value = H5O_shared_decode(f, dxpl_id, p, H5O_SHARED_TYPE))) + if(NULL == (ret_value = H5O_shared_decode(f, dxpl_id, ioflags, p, H5O_SHARED_TYPE))) HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "unable to decode shared message") + + /* We currently do not support automatically fixing shared messages */ +#ifdef H5_STRICT_FORMAT_CHECKS + if(*ioflags & H5O_DECODEIO_DIRTY) + HGOTO_ERROR(H5E_OHDR, H5E_UNSUPPORTED, NULL, "unable to mark shared message dirty") +#else /* H5_STRICT_FORMAT_CHECKS */ + *ioflags &= ~H5O_DECODEIO_DIRTY; +#endif /* H5_STRICT_FORMAT_CHECKS */ } /* end if */ else { /* Decode native message directly */ - if(NULL == (ret_value = H5O_SHARED_DECODE_REAL(f, dxpl_id, mesg_flags, p))) + if(NULL == (ret_value = H5O_SHARED_DECODE_REAL(f, dxpl_id, mesg_flags, ioflags, p))) HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "unable to decode native message") } /* end else */ diff --git a/src/H5Oshmesg.c b/src/H5Oshmesg.c index e66bdec..ed32fda 100644 --- a/src/H5Oshmesg.c +++ b/src/H5Oshmesg.c @@ -28,7 +28,8 @@ #include "H5Opkg.h" /* Object headers */ #include "H5MMprivate.h" /* Memory management */ -static void *H5O_shmesg_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p); +static void *H5O_shmesg_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, + unsigned *ioflags, const uint8_t *p); static herr_t H5O_shmesg_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg); static void *H5O_shmesg_copy(const void *_mesg, void *_dest); static size_t H5O_shmesg_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg); @@ -76,7 +77,7 @@ const H5O_msg_class_t H5O_MSG_SHMESG[1] = {{ */ static void * H5O_shmesg_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags, - const uint8_t *p) + unsigned UNUSED *ioflags, const uint8_t *p) { H5O_shmesg_table_t *mesg; /* Native message */ void *ret_value; /* Return value */ diff --git a/src/H5Ostab.c b/src/H5Ostab.c index 231f2ce..521a358 100644 --- a/src/H5Ostab.c +++ b/src/H5Ostab.c @@ -36,7 +36,8 @@ /* PRIVATE PROTOTYPES */ -static void *H5O_stab_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, const uint8_t *p); +static void *H5O_stab_decode(H5F_t *f, hid_t dxpl_id, unsigned mesg_flags, + unsigned *ioflags, const uint8_t *p); static herr_t H5O_stab_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg); static void *H5O_stab_copy(const void *_mesg, void *_dest); static size_t H5O_stab_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg); @@ -96,7 +97,7 @@ H5FL_DEFINE_STATIC(H5O_stab_t); */ static void * H5O_stab_decode(H5F_t *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags, - const uint8_t *p) + unsigned UNUSED *ioflags, const uint8_t *p) { H5O_stab_t *stab=NULL; void *ret_value; /* Return value */ @@ -5150,6 +5150,11 @@ H5T_upgrade_version_cb(H5T_t *dt, void *op_value) dt->shared->version = *(unsigned *)op_value; break; + case H5T_VLEN: + if(dt->shared->parent->shared->version > dt->shared->version) + dt->shared->version = dt->shared->parent->shared->version; + break; + default: break; } /* end switch */ |