summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNeil Fortner <nfortne2@hdfgroup.org>2008-08-11 15:18:54 (GMT)
committerNeil Fortner <nfortne2@hdfgroup.org>2008-08-11 15:18:54 (GMT)
commitf040f990a065db070a83e3217c209a83e204d6ca (patch)
treefc5d0086189dfb23a1c30f88b66ccf32cdbb550c /src
parent2df9af6ae8fd7bf4658e702b3e5046382dc5a852 (diff)
downloadhdf5-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.c3
-rw-r--r--src/H5Oainfo.c5
-rw-r--r--src/H5Oalloc.c14
-rw-r--r--src/H5Oattr.c9
-rw-r--r--src/H5Oattribute.c3
-rw-r--r--src/H5Obogus.c5
-rw-r--r--src/H5Obtreek.c5
-rw-r--r--src/H5Ocache.c18
-rw-r--r--src/H5Ocont.c5
-rw-r--r--src/H5Ocopy.c7
-rw-r--r--src/H5Odbg.c2
-rw-r--r--src/H5Odrvinfo.c5
-rw-r--r--src/H5Odtype.c95
-rw-r--r--src/H5Oefl.c5
-rw-r--r--src/H5Ofill.c10
-rw-r--r--src/H5Oginfo.c5
-rw-r--r--src/H5Olayout.c5
-rw-r--r--src/H5Olinfo.c5
-rw-r--r--src/H5Olink.c5
-rw-r--r--src/H5Omessage.c15
-rw-r--r--src/H5Omtime.c10
-rw-r--r--src/H5Oname.c5
-rw-r--r--src/H5Opkg.h21
-rw-r--r--src/H5Opline.c5
-rw-r--r--src/H5Orefcount.c5
-rw-r--r--src/H5Osdspace.c5
-rw-r--r--src/H5Oshared.c11
-rw-r--r--src/H5Oshared.h15
-rw-r--r--src/H5Oshmesg.c5
-rw-r--r--src/H5Ostab.c5
-rw-r--r--src/H5T.c5
31 files changed, 218 insertions, 100 deletions
diff --git a/src/H5O.c b/src/H5O.c
index d090df0..ddc23ab 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -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 */
diff --git a/src/H5T.c b/src/H5T.c
index 2da5be4..6dc3c68 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -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 */