summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5D.c8
-rw-r--r--src/H5O.c120
-rw-r--r--src/H5Obogus.c222
-rw-r--r--src/H5Oprivate.h20
-rw-r--r--src/Makefile.in16
-rw-r--r--test/ohdr.c31
-rw-r--r--test/tbogus.h5bin0 -> 2052 bytes
7 files changed, 406 insertions, 11 deletions
diff --git a/src/H5D.c b/src/H5D.c
index 8b312df..7bdef97 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -1671,6 +1671,14 @@ H5D_update_entry_info(H5F_t *file, H5D_t *dset, H5P_genplist_t *plist)
if (H5D_COMPACT != layout->type && H5O_append(file, oh, H5O_LAYOUT, 0, layout) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout");
+#ifdef H5O_ENABLE_BOGUS
+ /*
+ * Add a "bogus" message.
+ */
+ if (H5O_bogus_oh(file, oh))<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to update 'bogus' message");
+#endif /* H5O_ENABLE_BOGUS */
+
/* Add a modification time message. */
if (H5O_touch_oh(file, oh, TRUE) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update modification time message");
diff --git a/src/H5O.c b/src/H5O.c
index 886a130..741438c 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -67,7 +67,11 @@ static const H5O_class_t *const message_type_g[] = {
NULL, /*0x0006 Data storage -- compact object */
H5O_EFL, /*0x0007 Data storage -- external data files */
H5O_LAYOUT, /*0x0008 Data Layout */
- NULL, /*0x0009 Not assigned */
+#ifdef H5O_ENABLE_BOGUS
+ H5O_BOGUS, /*0x0009 "Bogus" */
+#else /* H5O_ENABLE_BOGUS */
+ NULL, /*0x0009 "Bogus" */
+#endif /* H5O_ENABLE_BOGUS */
NULL, /*0x000A Not assigned */
H5O_PLINE, /*0x000B Data storage -- filter pipeline */
H5O_ATTR, /*0x000C Attribute list */
@@ -502,10 +506,15 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void * UNUSED _udata1,
flags = *p++;
p += 3; /*reserved*/
- if (id >= NELMTS(message_type_g) || NULL == message_type_g[id])
- HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, NULL, "corrupt object header");
+ /* Try to detect invalidly formatted object header messages */
if (p + mesg_size > oh->chunk[chunkno].image + chunk_size)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "corrupt object header");
+
+ /* Skip header messages we don't know about */
+ /* (Usually from future versions of the library */
+ if (id >= NELMTS(message_type_g) || NULL == message_type_g[id])
+ continue;
+
if (H5O_NULL_ID == id && oh->nmesgs > 0 &&
H5O_NULL_ID == oh->mesg[oh->nmesgs - 1].type->id &&
oh->mesg[oh->nmesgs - 1].chunkno == chunkno) {
@@ -1719,6 +1728,111 @@ done:
FUNC_LEAVE_NOAPI(ret_value);
}
+#ifdef H5O_ENABLE_BOGUS
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_bogus_oh
+ *
+ * Purpose: Create a "bogus" message unless one already exists.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * <koziol@ncsa.uiuc.edu>
+ * Tuesday, January 21, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_bogus_oh(H5F_t *f, H5O_t *oh)
+{
+ int idx;
+ size_t size;
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER(H5O_bogus_oh, FAIL);
+
+ assert(f);
+ assert(oh);
+
+ /* Look for existing message */
+ for (idx=0; idx<oh->nmesgs; idx++)
+ if (H5O_BOGUS==oh->mesg[idx].type)
+ break;
+
+ /* Create a new message */
+ if (idx==oh->nmesgs) {
+ size = (H5O_BOGUS->raw_size)(f, NULL);
+ if ((idx=H5O_alloc(f, oh, H5O_BOGUS, size))<0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to allocate space for 'bogus' message");
+
+ /* Allocate the native message in memory */
+ if (NULL==(oh->mesg[idx].native = H5MM_malloc(sizeof(H5O_bogus_t))))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "memory allocation failed for 'bogus' message");
+
+ /* Update the native part */
+ ((H5O_bogus_t *)(oh->mesg[idx].native))->u = H5O_BOGUS_VALUE;
+
+ /* Mark the message and object header as dirty */
+ oh->mesg[idx].dirty = TRUE;
+ oh->dirty = TRUE;
+ } /* end if */
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5O_bogus_oh() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_bogus
+ *
+ * Purpose: Create a "bogus" message in an object.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * <koziol@ncsa.uiuc.edu>
+ * Tuesday, January 21, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_bogus(H5G_entry_t *ent)
+{
+ H5O_t *oh = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER(H5O_bogus, FAIL);
+
+ /* check args */
+ assert(ent);
+ assert(ent->file);
+ assert(H5F_addr_defined(ent->header));
+
+ /* Verify write access to the file */
+ if (0==(ent->file->intent & H5F_ACC_RDWR))
+ HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "no write intent on file");
+
+ /* Get the object header */
+ if (NULL==(oh=H5AC_protect(ent->file, H5AC_OHDR, ent->header, NULL, NULL)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header");
+
+ /* Create the "bogus" message */
+ if (H5O_bogus_oh(ent->file, oh)<0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to update object 'bogus' message");
+
+done:
+ if (oh && H5AC_unprotect(ent->file, H5AC_OHDR, ent->header, oh)<0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
+
+ FUNC_LEAVE(ret_value);
+} /* end H5O_bogus() */
+#endif /* H5O_ENABLE_BOGUS */
+
/*-------------------------------------------------------------------------
* Function: H5O_remove
diff --git a/src/H5Obogus.c b/src/H5Obogus.c
new file mode 100644
index 0000000..b25e006
--- /dev/null
+++ b/src/H5Obogus.c
@@ -0,0 +1,222 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*-------------------------------------------------------------------------
+ *
+ * Created: H5Obogus.c
+ * Jan 21 2003
+ * Quincey Koziol <koziol@ncsa.uiuc.edu>
+ *
+ * Purpose: "bogus" message. This message is guaranteed to never
+ * be found in a valid HDF5 file and is only used to
+ * generate a test file which verifies the library's
+ * correct operation when parsing unknown object header
+ * messages.
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "H5private.h"
+#include "H5Eprivate.h"
+#include "H5MMprivate.h"
+#include "H5Oprivate.h"
+
+#ifdef H5O_ENABLE_BOGUS
+#define PABLO_MASK H5O_bogus_mask
+
+/* PRIVATE PROTOTYPES */
+static void *H5O_bogus_decode(H5F_t *f, const uint8_t *p, H5O_shared_t *sh);
+static herr_t H5O_bogus_encode(H5F_t *f, uint8_t *p, const void *_mesg);
+static size_t H5O_bogus_size(H5F_t *f, const void *_mesg);
+static herr_t H5O_bogus_debug(H5F_t *f, const void *_mesg, FILE * stream,
+ int indent, int fwidth);
+
+/* This message derives from H5O */
+const H5O_class_t H5O_BOGUS[1] = {{
+ H5O_BOGUS_ID, /*message id number */
+ "bogus", /*message name for debugging */
+ 0, /*native message size */
+ H5O_bogus_decode, /*decode message */
+ H5O_bogus_encode, /*encode message */
+ NULL, /*copy the native value */
+ H5O_bogus_size, /*raw message size */
+ NULL, /*free internal memory */
+ NULL, /*free method */
+ NULL, /*get share method */
+ NULL, /*set share method */
+ H5O_bogus_debug, /*debug the message */
+}};
+
+/* Interface initialization */
+static int interface_initialize_g = 0;
+#define INTERFACE_INIT NULL
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_bogus_decode
+ *
+ * Purpose: Decode a "bogus" message and return a pointer to a new
+ * native message struct.
+ *
+ * Return: Success: Ptr to new message in native struct.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Jan 21 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_bogus_decode(H5F_t UNUSED *f, const uint8_t *p,
+ H5O_shared_t UNUSED *sh)
+{
+ H5O_bogus_t *mesg=NULL;
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER(H5O_bogus_decode, NULL);
+
+ /* check args */
+ assert(f);
+ assert(p);
+ assert(!sh);
+
+ /* Allocate the bogus message */
+ if (NULL==(mesg = H5MM_calloc(sizeof(H5O_bogus_t))))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+
+ /* decode */
+ UINT32DECODE(p, mesg->u);
+
+ /* Validate the bogus info */
+ if(mesg->u!=H5O_BOGUS_VALUE)
+ HGOTO_ERROR (H5E_OHDR, H5E_BADVALUE, NULL, "invalid bogus value :-)");
+
+ /* Set return value */
+ ret_value=mesg;
+
+done:
+ if(ret_value==NULL && mesg!=NULL)
+ H5MM_xfree(mesg);
+
+ FUNC_LEAVE(ret_value);
+} /* end H5O_bogus_decode() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_bogus_encode
+ *
+ * Purpose: Encodes a "bogus" message.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Jan 21 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_bogus_encode(H5F_t UNUSED *f, uint8_t *p, const void UNUSED *mesg)
+{
+ FUNC_ENTER(H5O_bogus_encode, FAIL);
+
+ /* check args */
+ assert(f);
+ assert(p);
+ assert(mesg);
+
+ /* encode */
+ UINT32ENCODE(p, H5O_BOGUS_VALUE);
+
+ FUNC_LEAVE(SUCCEED);
+} /* end H5O_bogus_encode() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_bogus_size
+ *
+ * Purpose: Returns the size of the raw message in bytes not
+ * counting the message typ or size fields, but only the data
+ * fields. This function doesn't take into account
+ * alignment.
+ *
+ * Return: Success: Message data size in bytes w/o alignment.
+ *
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Jan 21 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static size_t
+H5O_bogus_size(H5F_t UNUSED *f, const void UNUSED *mesg)
+{
+ FUNC_ENTER(H5O_bogus_size, 0);
+
+ /* check args */
+ assert(f);
+
+ FUNC_LEAVE(4);
+} /* end H5O_bogus_size() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_bogus_debug
+ *
+ * Purpose: Prints debugging info for the message.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Jan 21 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_bogus_debug(H5F_t UNUSED *f, const void *_mesg, FILE *stream,
+ int indent, int fwidth)
+{
+ const H5O_bogus_t *mesg = (const H5O_bogus_t *)_mesg;
+
+ FUNC_ENTER(H5O_name_debug, FAIL);
+
+ /* check args */
+ assert(f);
+ assert(mesg);
+ assert(stream);
+ assert(indent >= 0);
+ assert(fwidth >= 0);
+
+ fprintf(stream, "%*s%-*s `%u'\n", indent, "", fwidth,
+ "Bogus Value:", mesg->u);
+
+ FUNC_LEAVE(SUCCEED);
+}
+#endif /* H5O_ENABLE_BOGUS */
+
+
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 651dbca..c384362 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -216,6 +216,22 @@ typedef struct H5O_layout_t {
void *buf; /*buffer for compact dataset */
} H5O_layout_t;
+/* Enable reading/writing "bogus" messages */
+/* #define H5O_ENABLE_BOGUS */
+
+#ifdef H5O_ENABLE_BOGUS
+/*
+ * "Bogus" Message.
+ */
+#define H5O_BOGUS_ID 0x0009
+H5_DLLVAR const H5O_class_t H5O_BOGUS[1];
+
+#define H5O_BOGUS_VALUE 0xdeadbeef
+typedef struct H5O_bogus_t {
+ unsigned u; /* Hold the bogus info */
+} H5O_bogus_t;
+#endif /* H5O_ENABLE_BOGUS */
+
/*
* Filter pipeline message.
*/
@@ -362,6 +378,10 @@ H5_DLL int H5O_append(H5F_t *f, H5O_t *oh, const H5O_class_t *type,
unsigned flags, const void *mesg);
H5_DLL herr_t H5O_touch(H5G_entry_t *ent, hbool_t force);
H5_DLL herr_t H5O_touch_oh(H5F_t *f, H5O_t *oh, hbool_t force);
+#ifdef H5O_ENABLE_BOGUS
+H5_DLL herr_t H5O_bogus(H5G_entry_t *ent);
+H5_DLL herr_t H5O_bogus_oh(H5F_t *f, H5O_t *oh);
+#endif /* H5O_ENABLE_BOGUS */
H5_DLL herr_t H5O_remove(H5G_entry_t *ent, const H5O_class_t *type,
int sequence);
H5_DLL herr_t H5O_reset(const H5O_class_t *type, void *native);
diff --git a/src/Makefile.in b/src/Makefile.in
index cb9927b..95a0fc5 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -32,14 +32,14 @@ LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5D.c H5E.c H5F.c H5Farray.c H5Fcontig.c \
H5Fcompact.c H5Fistore.c H5Fseq.c H5FD.c H5FDcore.c H5FDfamily.c \
H5FDgass.c H5FDlog.c H5FDmpio.c H5FDmpiposix.c H5FDmulti.c H5FDsec2.c \
H5FDsrb.c H5FDstdio.c H5FDstream.c H5FL.c H5FO.c H5FP.c H5FPclient.c \
- H5FPserver.c H5G.c H5Gent.c H5Gnode.c H5Gstab.c H5HG.c H5HL.c \
- H5I.c H5MF.c H5MM.c H5O.c H5Oattr.c H5Ocont.c H5Odtype.c H5Oefl.c \
- H5Ofill.c H5Ofphdf5.c H5Olayout.c H5Omtime.c H5Oname.c H5Onull.c \
- H5Opline.c H5Oplist.c H5Osdspace.c H5Oshared.c H5Ostab.c H5P.c \
- H5Pdcpl.c H5Pdxpl.c H5Pfapl.c H5Pfcpl.c H5R.c H5RS.c H5S.c H5Sall.c \
- H5Shyper.c H5Smpio.c H5Snone.c H5Spoint.c H5Sselect.c H5ST.c H5T.c \
- H5Tbit.c H5Tconv.c H5Tinit.c H5Tvlen.c H5TB.c H5TS.c H5V.c H5Z.c \
- H5Zdeflate.c H5Zshuffle.c
+ H5FPserver.c H5G.c H5Gent.c H5Gnode.c H5Gstab.c H5HG.c H5HL.c \
+ H5I.c H5MF.c H5MM.c H5O.c H5Oattr.c H5Obogus.c H5Ocont.c H5Odtype.c \
+ H5Oefl.c H5Ofill.c H5Ofphdf5.c H5Olayout.c H5Omtime.c H5Oname.c \
+ H5Onull.c H5Opline.c H5Oplist.c H5Osdspace.c H5Oshared.c H5Ostab.c \
+ H5P.c H5Pdcpl.c H5Pdxpl.c H5Pfapl.c H5Pfcpl.c H5R.c H5RS.c H5S.c \
+ H5Sall.c H5Shyper.c H5Smpio.c H5Snone.c H5Spoint.c H5Sselect.c H5ST.c \
+ H5T.c H5Tbit.c H5Tconv.c H5Tinit.c H5Tvlen.c H5TB.c H5TS.c H5V.c \
+ H5Z.c H5Zdeflate.c H5Zshuffle.c
LIB_OBJ=$(LIB_SRC:.c=.lo)
diff --git a/test/ohdr.c b/test/ohdr.c
index ddd4ed6..3884e1a 100644
--- a/test/ohdr.c
+++ b/test/ohdr.c
@@ -20,6 +20,11 @@ const char *FILENAME[] = {
NULL
};
+/* The tbogus.h5 is generated from gen_bogus.c in HDF5 'test' directory.
+ * To get this data file, define H5O_ENABLE_BOGUS in src/H5Oprivate, rebuild
+ * the library and simply compile gen_bogus.c with that HDF5 library and run it. */
+#define FILE_BOGUS "tbogus.h5"
+
/*-------------------------------------------------------------------------
* Function: main
@@ -41,6 +46,7 @@ int
main(void)
{
hid_t fapl=-1, file=-1;
+ hid_t dset=-1;
H5F_t *f=NULL;
char filename[1024];
H5G_entry_t oh_ent;
@@ -267,6 +273,31 @@ main(void)
if (H5Fclose(file)<0) goto error;
PASSED();
+ /* Test reading dataset with undefined object header message */
+ TESTING("reading object with unknown header message");
+ {
+ char testfile[512]="";
+ char *srcdir = getenv("srcdir");
+
+ /* Build path to test file */
+ if (srcdir && ((HDstrlen(srcdir) + HDstrlen(FILE_BOGUS) + 1) < sizeof(testfile))){
+ HDstrcpy(testfile, srcdir);
+ HDstrcat(testfile, "/");
+ }
+ HDstrcat(testfile, FILE_BOGUS);
+
+ if ((file=H5Fopen(testfile, H5F_ACC_RDONLY, fapl))<0)
+ goto error;
+
+ /* Open the dataset with the unknown header message (generated with gen_bogus.c) */
+ if((dset=H5Dopen(file,"/Dataset1"))<0)
+ goto error;
+ if (H5Dclose(dset)<0) goto error;
+
+ if (H5Fclose(file)<0) goto error;
+ }
+ PASSED();
+
puts("All object header tests passed.");
h5_cleanup(FILENAME, fapl);
return 0;
diff --git a/test/tbogus.h5 b/test/tbogus.h5
new file mode 100644
index 0000000..ddc3b65
--- /dev/null
+++ b/test/tbogus.h5
Binary files differ