summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MANIFEST1
-rwxr-xr-xconfigure55
-rw-r--r--configure.in38
-rw-r--r--src/H5O.c4
-rw-r--r--src/H5Ocache.c21
-rw-r--r--src/H5Opkg.h1
-rw-r--r--src/H5config.h.in3
-rw-r--r--test/tbad_msg_count.h5bin0 -> 1984 bytes
-rw-r--r--test/tmisc.c63
9 files changed, 176 insertions, 10 deletions
diff --git a/MANIFEST b/MANIFEST
index c992f64..a715e8f 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1391,6 +1391,7 @@
./test/tarray.c
./test/tarrold.h5
./test/tattr.c
+./test/tbad_msg_count.h5
./test/tbogus.h5
./test/tconfig.c
./test/tcoords.c
diff --git a/configure b/configure
index 17f700b..002d856 100755
--- a/configure
+++ b/configure
@@ -882,6 +882,7 @@ CC_VERSION
ROOT
DYNAMIC_DIRS
HL
+STRICT_FORMAT_CHECKS
SEARCH
SETX
LIBOBJS
@@ -1512,6 +1513,9 @@ Optional Features:
specify a comma-separated list of filters or the
word no. The default is all internal I/O filters.
--enable-hl Enable the high level library [default=yes]
+ --enable-strict-format-checks
+ Enable strict file format checks, default=yes if
+ debug flag is enabled, no otherwise
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@@ -5289,7 +5293,7 @@ test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
case $host in
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 5292 "configure"' > conftest.$ac_ext
+ echo '#line 5296 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -5846,7 +5850,7 @@ chmod -w .
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -o out/conftest2.$ac_objext"
compiler_c_o=no
-if { (eval echo configure:5849: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
+if { (eval echo configure:5853: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
if test -s out/conftest.err; then
@@ -7721,7 +7725,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 7724 "configure"
+#line 7728 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -7819,7 +7823,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 7822 "configure"
+#line 7826 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -36316,6 +36320,43 @@ else
echo "no"
fi
+
+
+{ echo "$as_me:$LINENO: checking Whether to perform strict file format checks" >&5
+echo $ECHO_N "checking Whether to perform strict file format checks... $ECHO_C" >&6; };
+# Check whether --enable-strict-format-checks was given.
+if test "${enable_strict_format_checks+set}" = set; then
+ enableval=$enable_strict_format_checks; STRICT_CHECKS=$enableval
+fi
+
+
+if test "X-$STRICT_CHECKS" = X- ; then
+ if test -z "$DEBUG_PKG" ; then
+ STRICT_CHECKS=no
+ else
+ STRICT_CHECKS=yes
+ fi
+fi
+
+case "X-$STRICT_CHECKS" in
+ X-yes)
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+ STRICT_FORMAT_CHECKS=yes
+
+cat >>confdefs.h <<\_ACEOF
+#define STRICT_FORMAT_CHECKS 1
+_ACEOF
+
+ ;;
+ X-no|*)
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+ STRICT_FORMAT_CHECKS=no
+ ;;
+esac
+
+
COMMENCE=config/commence
CONCLUDE=config/conclude
@@ -37201,13 +37242,14 @@ CC_VERSION!$CC_VERSION$ac_delim
ROOT!$ROOT$ac_delim
DYNAMIC_DIRS!$DYNAMIC_DIRS$ac_delim
HL!$HL$ac_delim
+STRICT_FORMAT_CHECKS!$STRICT_FORMAT_CHECKS$ac_delim
SEARCH!$SEARCH$ac_delim
SETX!$SETX$ac_delim
LIBOBJS!$LIBOBJS$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 22; then
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 23; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
@@ -38000,6 +38042,9 @@ IF_YES_NO "$GASS"
PRINT_N " GPFS"
IF_YES_NO "$GPFS"
+PRINT_N " Strict File Format Checks"
+IF_ENABLED_DISABLED "$STRICT_FORMAT_CHECKS"
+
PRINT_N " HDF5 v1.4 Compatibility"
IF_YES_NO "$HDF5_V1_4_COMPAT"
diff --git a/configure.in b/configure.in
index 43401ef..8014b90 100644
--- a/configure.in
+++ b/configure.in
@@ -2390,6 +2390,41 @@ else
echo "no"
fi
+
+dnl ----------------------------------------------------------------------
+dnl Enable strict file format checks
+dnl
+AC_SUBST([STRICT_FORMAT_CHECKS])
+AC_MSG_CHECKING([Whether to perform strict file format checks]);
+AC_ARG_ENABLE([strict-format-checks],
+ [AC_HELP_STRING([--enable-strict-format-checks],
+ [Enable strict file format checks, default=yes if
+ debug flag is enabled, no otherwise])],
+ [STRICT_CHECKS=$enableval])
+
+dnl Default to yes if debug is enabled
+if test "X-$STRICT_CHECKS" = X- ; then
+ if test -z "$DEBUG_PKG" ; then
+ STRICT_CHECKS=no
+ else
+ STRICT_CHECKS=yes
+ fi
+fi
+
+case "X-$STRICT_CHECKS" in
+ X-yes)
+ AC_MSG_RESULT([yes])
+ STRICT_FORMAT_CHECKS=yes
+ AC_DEFINE([STRICT_FORMAT_CHECKS], [1],
+ [Define if strict file format checks are enabled])
+ ;;
+ X-no|*)
+ AC_MSG_RESULT([no])
+ STRICT_FORMAT_CHECKS=no
+ ;;
+esac
+
+
dnl ----------------------------------------------------------------------
dnl Build the Makefiles. Almost every Makefile.in will begin with the line
dnl `@COMMENCE@' and end with the line `@CONCLUDE@'. These lines insert
@@ -2672,6 +2707,9 @@ IF_YES_NO "$GASS"
PRINT_N " GPFS"
IF_YES_NO "$GPFS"
+PRINT_N " Strict File Format Checks"
+IF_ENABLED_DISABLED "$STRICT_FORMAT_CHECKS"
+
PRINT_N " HDF5 v1.4 Compatibility"
IF_YES_NO "$HDF5_V1_4_COMPAT"
diff --git a/src/H5O.c b/src/H5O.c
index 764f2c4..b02ebbb 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -2175,7 +2175,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-static herr_t
+herr_t
H5O_alloc_msgs(H5O_t *oh, size_t min_alloc)
{
size_t old_alloc; /* Old number of messages allocated */
@@ -2183,7 +2183,7 @@ H5O_alloc_msgs(H5O_t *oh, size_t min_alloc)
H5O_mesg_t *new_mesg; /* Pointer to new message array */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5O_alloc_msgs)
+ FUNC_ENTER_NOAPI(H5O_alloc_msgs, FAIL)
/* check args */
HDassert(oh);
diff --git a/src/H5Ocache.c b/src/H5Ocache.c
index 5e12fdc..c507a6a 100644
--- a/src/H5Ocache.c
+++ b/src/H5Ocache.c
@@ -312,9 +312,10 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
oh->mesg[mesgno].dirty = TRUE;
merged_null_msgs++;
} else {
- /* new message */
- if (oh->nmesgs >= nmesgs)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "corrupt object header - too many messages");
+ /* Check if we need to extend message table to hold the new message */
+ if(oh->nmesgs >= oh->alloc_nmesgs)
+ if(H5O_alloc_msgs(oh, (size_t)1) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate more space for messages")
mesgno = oh->nmesgs++;
oh->mesg[mesgno].type = H5O_msg_class_g[id];
oh->mesg[mesgno].dirty = FALSE;
@@ -346,9 +347,23 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
if(merged_null_msgs)
oh->cache_info.is_dirty = TRUE;
+/* Don't check for the incorrect # of object header messages bug unless we've
+ * enabled strict format checking. This allows for older files, created with
+ * a version of the library that had a bug in tracking the correct # of header
+ * messages to be read in without the library fussing about things. -QAK
+ */
+#ifdef H5_STRICT_FORMAT_CHECKS
/* Sanity check for the correct # of messages in object header */
if((oh->nmesgs + skipped_msgs + merged_null_msgs) != nmesgs)
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "corrupt object header - too few messages")
+#else /* H5_STRICT_FORMAT_CHECKS */
+ /* Check for incorrect # of messages in object header and if we have write
+ * access on the file, flag the object header as dirty, so it gets fixed.
+ */
+ if((oh->nmesgs + skipped_msgs + merged_null_msgs) != nmesgs &&
+ (H5F_get_intent(f) & H5F_ACC_RDWR))
+ oh->cache_info.is_dirty = TRUE;
+#endif /* H5_STRICT_FORMAT_CHECKS */
/* Set return value */
ret_value = oh;
diff --git a/src/H5Opkg.h b/src/H5Opkg.h
index 80bf320..43b06a7 100644
--- a/src/H5Opkg.h
+++ b/src/H5Opkg.h
@@ -204,6 +204,7 @@ H5_DLL herr_t H5O_free_mesg(H5O_mesg_t *mesg);
H5_DLL void * H5O_read_real(const H5G_entry_t *ent, const H5O_msg_class_t *type,
int sequence, void *mesg, hid_t dxpl_id);
H5_DLL void * H5O_free_real(const H5O_msg_class_t *type, void *mesg);
+H5_DLL herr_t H5O_alloc_msgs(H5O_t *oh, size_t min_alloc);
/* Shared object operators */
H5_DLL void * H5O_shared_read(H5F_t *f, hid_t dxpl_id, H5O_shared_t *shared,
diff --git a/src/H5config.h.in b/src/H5config.h.in
index 56794cd..85456f5 100644
--- a/src/H5config.h.in
+++ b/src/H5config.h.in
@@ -505,6 +505,9 @@
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
+/* Define if strict file format checks are enabled */
+#undef STRICT_FORMAT_CHECKS
+
/* Define if your system supports pthread_attr_setscope(&attribute,
PTHREAD_SCOPE_SYSTEM) call. */
#undef SYSTEM_SCOPE_THREADS
diff --git a/test/tbad_msg_count.h5 b/test/tbad_msg_count.h5
new file mode 100644
index 0000000..ca5eb65
--- /dev/null
+++ b/test/tbad_msg_count.h5
Binary files differ
diff --git a/test/tmisc.c b/test/tmisc.c
index 88c9ea2..3e38b8f 100644
--- a/test/tmisc.c
+++ b/test/tmisc.c
@@ -279,6 +279,13 @@ unsigned m13_rdata[MISC13_DIM1][MISC13_DIM2]; /* Data read from dataset
#define MISC25B_FILE "mergemsg.h5"
#define MISC25B_GROUP "grp1"
+/* Definitions for misc. test #27 */
+/* (Note that this test file is generated by the "gen_bad_ohdr.c" code in
+ * the 1.8 branch/trunk)
+ */
+#define MISC27_FILE "tbad_msg_count.h5"
+#define MISC27_GROUP "Group"
+
/****************************************************************
**
** test_misc1(): test unlinking a dataset from a group and immediately
@@ -4186,6 +4193,60 @@ test_misc25b(void)
CHECK(ret, FAIL, "H5Fclose");
} /* end test_misc25a() */
+
+/****************************************************************
+**
+** test_misc27(): Ensure that objects with incorrect # of object
+** header messages are handled appropriately.
+**
+** (Note that this test file is generated by the "gen_bad_ohdr.c" code,
+** in the 1.8 branch/trunk)
+**
+****************************************************************/
+static void
+test_misc27(void)
+{
+ hid_t fid; /* File ID */
+ hid_t gid; /* Group ID */
+ char testfile[512]=""; /* Character buffer for corrected test file name */
+ char *srcdir = HDgetenv("srcdir"); /* Pointer to the directory the source code is located within */
+ herr_t ret; /* Generic return value */
+
+ /* Output message about test being performed */
+ MESSAGE(5, ("Corrupt object header handling\n"));
+
+ /* Generate the correct name for the test file, by prepending the source path */
+ if(srcdir && ((HDstrlen(srcdir) + HDstrlen(MISC27_FILE) + 1) < sizeof(testfile))) {
+ HDstrcpy(testfile, srcdir);
+ HDstrcat(testfile, "/");
+ }
+ HDstrcat(testfile, MISC27_FILE);
+
+ /* Open the file */
+ fid = H5Fopen(testfile, H5F_ACC_RDONLY, H5P_DEFAULT);
+ CHECK(fid, FAIL, "H5Fopen");
+
+#ifdef H5_STRICT_FORMAT_CHECKS
+ /* Open group with incorrect # of object header messages (should fail) */
+ H5E_BEGIN_TRY {
+ gid = H5Gopen(fid, MISC27_GROUP);
+ } H5E_END_TRY;
+ VERIFY(gid, FAIL, "H5Gopen");
+#else /* H5_STRICT_FORMAT_CHECKS */
+ /* Open group with incorrect # of object header messages */
+ gid = H5Gopen(fid, MISC27_GROUP);
+ CHECK(gid, FAIL, "H5Gopen");
+
+ /* Close group */
+ ret = H5Gclose(gid);
+ CHECK(ret, FAIL, "H5Gclose");
+#endif /* H5_STRICT_FORMAT_CHECKS */
+
+ /* Close file */
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+} /* end test_misc27() */
+
/****************************************************************
**
** test_misc(): Main misc. test routine.
@@ -4225,6 +4286,8 @@ test_misc(void)
test_misc24(); /* Test inappropriate API opens of objects */
test_misc25a(); /* Exercise null object header message merge bug */
test_misc25b(); /* Exercise null object header message merge bug on existing file */
+ /* misc. test #26 only in 1.8 branch/trunk */
+ test_misc27(); /* Test opening file with object that has bad # of object header messages */
} /* test_misc() */