diff options
-rw-r--r-- | MANIFEST | 1 | ||||
-rwxr-xr-x | configure | 55 | ||||
-rw-r--r-- | configure.in | 38 | ||||
-rw-r--r-- | src/H5O.c | 4 | ||||
-rw-r--r-- | src/H5Ocache.c | 21 | ||||
-rw-r--r-- | src/H5Opkg.h | 1 | ||||
-rw-r--r-- | src/H5config.h.in | 3 | ||||
-rw-r--r-- | test/tbad_msg_count.h5 | bin | 0 -> 1984 bytes | |||
-rw-r--r-- | test/tmisc.c | 63 |
9 files changed, 176 insertions, 10 deletions
@@ -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 @@ -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" @@ -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 Binary files differnew file mode 100644 index 0000000..ca5eb65 --- /dev/null +++ b/test/tbad_msg_count.h5 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() */ |