From c254b0bc27536c91c7bb0ffa4269aba76f00fbff Mon Sep 17 00:00:00 2001 From: Neil Fortner Date: Thu, 18 Sep 2008 15:53:30 -0500 Subject: [svn-r15656] Purpose: fix bug 1286 Description: Added configure test to see if pointer alignment restrictions are enforced (as in dereferencing an unaligned pointer causes an error). Added code in H5Tvlen.c to avoid dereferencing unaligned pointers, conditionally compiled based on the configure test. Added test case in dtypes.c which would previously cause such machines to fail. Tested: kagiso, smirom, linew (h5committest); linew64 --- configure | 110 +++++++++++++++ configure.in | 47 ++++++ release_docs/RELEASE.txt | 2 + src/H5Tvlen.c | 203 +++++++++++++++++++------- src/H5config.h.in | 3 + test/dtypes.c | 361 ++++++++++++++++++++++++++++++++++++++++++++++- vms/src/h5pubconf.h | 9 +- windows/src/H5pubconf.h | 3 + 8 files changed, 685 insertions(+), 53 deletions(-) diff --git a/configure b/configure index c483a1e..f14f93b 100755 --- a/configure +++ b/configure @@ -50770,6 +50770,116 @@ echo "${ECHO_T}no" >&6; } esac +{ echo "$as_me:$LINENO: checking if alignment restrictions are strictly enforced" >&5 +echo $ECHO_N "checking if alignment restrictions are strictly enforced... $ECHO_C" >&6; } +if test "$cross_compiling" = yes; then + + { echo "$as_me:$LINENO: result: unknown, assuming yes" >&5 +echo "${ECHO_T}unknown, assuming yes" >&6; } + +else + cat >conftest.$ac_ext <<_ACEOF + + /* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + #include + #include + + typedef struct { + size_t len; + void *p; + } hvl_t; + +#ifdef FC_DUMMY_MAIN +#ifndef FC_DUMMY_MAIN_EQ_F77 +# ifdef __cplusplus + extern "C" +# endif + int FC_DUMMY_MAIN() { return 1; } +#endif +#endif +int +main () +{ + + char *chp = "beefs"; + char **chpp = malloc (2 * sizeof (char *)); + char **chpp2; + hvl_t vl = { 12345, (void *) chp }; + hvl_t *vlp; + hvl_t *vlp2; + + memcpy ((void *) ((char *) chpp + 1), &chp, sizeof (char *)); + chpp2 = (char **) ((char *) chpp + 1); + if (strcmp (*chpp2, chp)) { + free (chpp); + return 1; + } + free (chpp); + + vlp = malloc (2 * sizeof (hvl_t)); + memcpy ((void *) ((char *) vlp + 1), &vl, sizeof (hvl_t)); + vlp2 = (hvl_t *) ((char *) vlp + 1); + if (vlp2->len != vl.len || vlp2->p != vl.p) { + free (vlp); + return 1; + } + free (vlp); + + ; + return 0; +} + +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + +cat >>confdefs.h <<\_ACEOF +#define NO_ALIGNMENT_RESTRICTIONS 1 +_ACEOF + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) + + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + + if test "X$HDF_CXX" = "Xyes"; then BUILD_CXX_CONDITIONAL_TRUE= diff --git a/configure.in b/configure.in index 6e2a4e1..e03be0a 100644 --- a/configure.in +++ b/configure.in @@ -3814,6 +3814,53 @@ esac dnl ---------------------------------------------------------------------- +dnl Check if pointer alignments are enforced +dnl +AC_MSG_CHECKING([if alignment restrictions are strictly enforced]) +AC_RUN_IFELSE([ + AC_LANG_PROGRAM([ + #include + #include + + typedef struct { + size_t len; + void *p; + } hvl_t; + ], [ + char *chp = "beefs"; + char **chpp = malloc (2 * sizeof (char *)); + char **chpp2; + hvl_t vl = { 12345, (void *) chp }; + hvl_t *vlp; + hvl_t *vlp2; + + memcpy ((void *) ((char *) chpp + 1), &chp, sizeof (char *)); + chpp2 = (char **) ((char *) chpp + 1); + if (strcmp (*chpp2, chp)) { + free (chpp); + return 1; + } + free (chpp); + + vlp = malloc (2 * sizeof (hvl_t)); + memcpy ((void *) ((char *) vlp + 1), &vl, sizeof (hvl_t)); + vlp2 = (hvl_t *) ((char *) vlp + 1); + if (vlp2->len != vl.len || vlp2->p != vl.p) { + free (vlp); + return 1; + } + free (vlp); + ]) + ], [ + AC_DEFINE([NO_ALIGNMENT_RESTRICTIONS], [1], [Define if we can violate pointer alignment restrictions]) + AC_MSG_RESULT([no]) + ], [ + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([unknown, assuming yes]) + ]) + +dnl ---------------------------------------------------------------------- dnl Create automake conditionals to tell automake makefiles which directories dnl need to be compiled diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 8e56878..3577da2 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -107,6 +107,8 @@ Bug Fixes since HDF5-1.8.0 release Library ------- + - Fixed pointer alignment violations that could occur during vlen + conversion. (NAF - 2008/09/16) - Fixed problem where library could cause a segmentation fault when an invalid location ID was given to H5Giterate(). (QAK - 2008/08/19) - Fixed improper shutdown when objects have reference count > 1. The diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c index d80bd94..27eb0f6 100644 --- a/src/H5Tvlen.c +++ b/src/H5Tvlen.c @@ -248,7 +248,7 @@ H5T_vlen_set_loc(const H5T_t *dt, H5F_t *f, H5T_loc_t loc) dt->shared->u.vlen.write = H5T_vlen_str_mem_write; dt->shared->u.vlen.setnull = H5T_vlen_str_mem_setnull; } else { - assert(0 && "Invalid VL type"); + HDassert(0 && "Invalid VL type"); } /* Reset file ID (since this VL is in memory) */ @@ -304,21 +304,35 @@ done: * Programmer: Quincey Koziol * Wednesday, June 2, 1999 * - * Modifications: + * Modifications: Neil Fortner + * Friday, August 22, 2008 + * Changed function to be tolerant of an hvl_t that is not aligned + * properly in _vl. * *------------------------------------------------------------------------- */ static ssize_t H5T_vlen_seq_mem_getlen(const void *_vl) { +#ifdef H5_NO_ALIGNMENT_RESTRICTIONS const hvl_t *vl=(const hvl_t *)_vl; /* Pointer to the user's hvl_t information */ +#else + hvl_t vl; /* User's hvl_t information */ +#endif FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_vlen_seq_mem_getlen) - /* check parameters */ - assert(vl); + /* check parameters, return result */ +#ifdef H5_NO_ALIGNMENT_RESTRICTIONS + HDassert(vl); FUNC_LEAVE_NOAPI((ssize_t)vl->len) +#else + HDassert(_vl); + HDmemcpy(&vl, _vl, sizeof(hvl_t)); + + FUNC_LEAVE_NOAPI((ssize_t)vl.len) +#endif } /* end H5T_vlen_seq_mem_getlen() */ @@ -332,21 +346,35 @@ H5T_vlen_seq_mem_getlen(const void *_vl) * Programmer: Quincey Koziol * Saturday, June 12, 2004 * - * Modifications: + * Modifications: Neil Fortner + * Friday, August 22, 2008 + * Changed function to be tolerant of an hvl_t that is not aligned + * properly in _vl. * *------------------------------------------------------------------------- */ static void * H5T_vlen_seq_mem_getptr(void *_vl) { - hvl_t *vl=(hvl_t *)_vl; /* Pointer to the user's hvl_t information */ +#ifdef H5_NO_ALIGNMENT_RESTRICTIONS + const hvl_t *vl=(const hvl_t *)_vl; /* Pointer to the user's hvl_t information */ +#else + hvl_t vl; /* User's hvl_t information */ +#endif FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_vlen_seq_mem_getptr) - /* check parameters */ - assert(vl); + /* check parameters, return result */ +#ifdef H5_NO_ALIGNMENT_RESTRICTIONS + HDassert(vl); FUNC_LEAVE_NOAPI(vl->p) +#else + HDassert(_vl); + HDmemcpy(&vl, _vl, sizeof(hvl_t)); + + FUNC_LEAVE_NOAPI(vl.p) +#endif } /* end H5T_vlen_seq_mem_getptr() */ @@ -360,7 +388,10 @@ H5T_vlen_seq_mem_getptr(void *_vl) * Programmer: Quincey Koziol * Saturday, November 8, 2003 * - * Modifications: + * Modifications: Neil Fortner + * Friday, August 22, 2008 + * Changed function to be tolerant of an hvl_t that is not aligned + * properly in _vl. * *------------------------------------------------------------------------- */ @@ -368,14 +399,25 @@ H5T_vlen_seq_mem_getptr(void *_vl) static htri_t H5T_vlen_seq_mem_isnull(const H5F_t UNUSED *f, void *_vl) { - hvl_t *vl=(hvl_t *)_vl; /* Pointer to the user's hvl_t information */ +#ifdef H5_NO_ALIGNMENT_RESTRICTIONS + const hvl_t *vl=(const hvl_t *)_vl; /* Pointer to the user's hvl_t information */ +#else + hvl_t vl; /* User's hvl_t information */ +#endif FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_vlen_seq_mem_isnull) - /* check parameters */ - assert(vl); + /* check parameters, return result */ +#ifdef H5_NO_ALIGNMENT_RESTRICTIONS + HDassert(vl); FUNC_LEAVE_NOAPI((vl->len==0 || vl->p==NULL) ? TRUE : FALSE) +#else + HDassert(_vl); + HDmemcpy(&vl, _vl, sizeof(hvl_t)); + + FUNC_LEAVE_NOAPI((vl.len==0 || vl.p==NULL) ? TRUE : FALSE) +#endif } /* end H5T_vlen_seq_mem_isnull() */ @@ -389,7 +431,10 @@ H5T_vlen_seq_mem_isnull(const H5F_t UNUSED *f, void *_vl) * Programmer: Quincey Koziol * Wednesday, June 2, 1999 * - * Modifications: + * Modifications: Neil Fortner + * Friday, August 22, 2008 + * Changed function to be tolerant of an hvl_t that is not aligned + * properly in _vl. * *------------------------------------------------------------------------- */ @@ -397,15 +442,27 @@ H5T_vlen_seq_mem_isnull(const H5F_t UNUSED *f, void *_vl) static herr_t H5T_vlen_seq_mem_read(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_vl, void *buf, size_t len) { - hvl_t *vl=(hvl_t *)_vl; /* Pointer to the user's hvl_t information */ +#ifdef H5_NO_ALIGNMENT_RESTRICTIONS + const hvl_t *vl=(const hvl_t *)_vl; /* Pointer to the user's hvl_t information */ +#else + hvl_t vl; /* User's hvl_t information */ +#endif FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_vlen_seq_mem_read) - /* check parameters */ - assert(vl && vl->p); - assert(buf); + /* check parameters, copy data */ + HDassert(buf); +#ifdef H5_NO_ALIGNMENT_RESTRICTIONS + HDassert(vl && vl->p); HDmemcpy(buf,vl->p,len); +#else + HDassert(_vl); + HDmemcpy(&vl, _vl, sizeof(hvl_t)); + HDassert(vl.p); + + HDmemcpy(buf,vl.p,len); +#endif FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5T_vlen_seq_mem_read() */ @@ -436,8 +493,8 @@ H5T_vlen_seq_mem_write(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const H5T_vlen_all FUNC_ENTER_NOAPI_NOINIT(H5T_vlen_seq_mem_write) /* check parameters */ - assert(_vl); - assert(buf); + HDassert(_vl); + HDassert(buf); if(seq_len!=0) { len=seq_len*base_size; @@ -493,7 +550,7 @@ H5T_vlen_seq_mem_setnull(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_vl, void FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_vlen_seq_mem_setnull) /* check parameters */ - assert(_vl); + HDassert(_vl); /* Set the "nil" hvl_t */ vl.len=0; @@ -516,19 +573,31 @@ H5T_vlen_seq_mem_setnull(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_vl, void * Programmer: Quincey Koziol * Wednesday, June 2, 1999 * - * Modifications: + * Modifications: Neil Fortner + * Friday, August 22, 2008 + * Changed function to be tolerant of a char * that is not aligned + * properly in _vl. * *------------------------------------------------------------------------- */ static ssize_t H5T_vlen_str_mem_getlen(const void *_vl) { +#ifdef H5_NO_ALIGNMENT_RESTRICTIONS const char *s=*(const char * const *)_vl; /* Pointer to the user's string information */ +#else + const char *s; /* Pointer to the user's string information */ +#endif FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_vlen_str_mem_getlen) /* check parameters */ - assert(s); +#ifdef H5_NO_ALIGNMENT_RESTRICTIONS + HDassert(s); +#else + HDassert(_vl); + HDmemcpy(&s, _vl, sizeof(char *)); +#endif FUNC_LEAVE_NOAPI((ssize_t)HDstrlen(s)) } /* end H5T_vlen_str_mem_getlen() */ @@ -544,19 +613,32 @@ H5T_vlen_str_mem_getlen(const void *_vl) * Programmer: Quincey Koziol * Saturday, June 12, 2004 * - * Modifications: + * Modifications: Neil Fortner + * Friday, August 22, 2008 + * Changed function to be tolerant of a char * that is not aligned + * properly in _vl. + * Added assertion on _vl. * *------------------------------------------------------------------------- */ static void * H5T_vlen_str_mem_getptr(void *_vl) { +#ifdef H5_NO_ALIGNMENT_RESTRICTIONS char *s=*(char **)_vl; /* Pointer to the user's string information */ +#else + char *s; /* Pointer to the user's string information */ +#endif FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_vlen_str_mem_getptr) /* check parameters */ - assert(s); +#ifdef H5_NO_ALIGNMENT_RESTRICTIONS + HDassert(s); +#else + HDassert(_vl); + HDmemcpy(&s, _vl, sizeof(char *)); +#endif FUNC_LEAVE_NOAPI(s) } /* end H5T_vlen_str_mem_getptr() */ @@ -572,7 +654,10 @@ H5T_vlen_str_mem_getptr(void *_vl) * Programmer: Quincey Koziol * Saturday, November 8, 2003 * - * Modifications: + * Modifications: Neil Fortner + * Friday, August 22, 2008 + * Changed function to be tolerant of a char * that is not aligned + * properly in _vl. * *------------------------------------------------------------------------- */ @@ -580,10 +665,18 @@ H5T_vlen_str_mem_getptr(void *_vl) static htri_t H5T_vlen_str_mem_isnull(const H5F_t UNUSED *f, void *_vl) { +#ifdef H5_NO_ALIGNMENT_RESTRICTIONS char *s=*(char **)_vl; /* Pointer to the user's string information */ +#else + char *s; /* Pointer to the user's string information */ +#endif FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_vlen_str_mem_isnull) +#ifndef H5_NO_ALIGNMENT_RESTRICTIONS + HDmemcpy(&s, _vl, sizeof(char *)); +#endif + FUNC_LEAVE_NOAPI(s==NULL ? TRUE : FALSE) } /* end H5T_vlen_str_mem_isnull() */ @@ -598,7 +691,10 @@ H5T_vlen_str_mem_isnull(const H5F_t UNUSED *f, void *_vl) * Programmer: Quincey Koziol * Wednesday, June 2, 1999 * - * Modifications: + * Modifications: Neil Fortner + * Friday, August 22, 2008 + * Changed function to be tolerant of a char * that is not aligned + * properly in _vl. * *------------------------------------------------------------------------- */ @@ -606,14 +702,23 @@ H5T_vlen_str_mem_isnull(const H5F_t UNUSED *f, void *_vl) static herr_t H5T_vlen_str_mem_read(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_vl, void *buf, size_t len) { - char *s=*(char **)_vl; /* Pointer to the user's hvl_t information */ +#ifdef H5_NO_ALIGNMENT_RESTRICTIONS + char *s=*(char **)_vl; /* Pointer to the user's string information */ +#else + char *s; /* Pointer to the user's string information */ +#endif FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_vlen_str_mem_read) if(len>0) { /* check parameters */ - assert(s); - assert(buf); + HDassert(buf); +#ifdef H5_NO_ALIGNMENT_RESTRICTIONS + HDassert(s); +#else + HDassert(_vl); + HDmemcpy(&s, _vl, sizeof(char *)); +#endif HDmemcpy(buf,s,len); } /* end if */ @@ -647,7 +752,7 @@ H5T_vlen_str_mem_write(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const H5T_vlen_all FUNC_ENTER_NOAPI_NOINIT(H5T_vlen_str_mem_write) /* check parameters */ - assert(buf); + HDassert(buf); /* Use the user's memory allocation routine if one is defined */ if(vl_alloc_info->alloc_func!=NULL) { @@ -723,7 +828,7 @@ H5T_vlen_disk_getlen(const void *_vl) FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_vlen_disk_getlen) /* check parameters */ - assert(vl); + HDassert(vl); UINT32DECODE(vl, seq_len); @@ -752,7 +857,7 @@ H5T_vlen_disk_getptr(void UNUSED *vl) FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_vlen_disk_getptr) /* check parameters */ - assert(vl); + HDassert(vl); FUNC_LEAVE_NOAPI(NULL) } /* end H5T_vlen_disk_getptr() */ @@ -781,7 +886,7 @@ H5T_vlen_disk_isnull(const H5F_t *f, void *_vl) FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_vlen_disk_isnull) /* check parameters */ - assert(vl); + HDassert(vl); /* Skip the sequence's length */ vl+=4; @@ -818,9 +923,9 @@ H5T_vlen_disk_read(H5F_t *f, hid_t dxpl_id, void *_vl, void *buf, size_t UNUSED FUNC_ENTER_NOAPI_NOINIT(H5T_vlen_disk_read) /* check parameters */ - assert(vl); - assert(buf); - assert(f); + HDassert(vl); + HDassert(buf); + HDassert(f); /* Skip the length of the sequence */ vl += 4; @@ -872,9 +977,9 @@ H5T_vlen_disk_write(H5F_t *f, hid_t dxpl_id, const H5T_vlen_alloc_info_t UNUSED FUNC_ENTER_NOAPI_NOINIT(H5T_vlen_disk_write) /* check parameters */ - assert(vl); - assert(seq_len==0 || buf); - assert(f); + HDassert(vl); + HDassert(seq_len==0 || buf); + HDassert(f); /* Free heap object for old data. */ if(bg!=NULL) { @@ -937,8 +1042,8 @@ H5T_vlen_disk_setnull(H5F_t *f, hid_t dxpl_id, void *_vl, void *_bg) FUNC_ENTER_NOAPI_NOINIT(H5T_vlen_disk_setnull) /* check parameters */ - assert(f); - assert(vl); + HDassert(f); + HDassert(vl); /* Free heap object for old data. */ if(bg!=NULL) { @@ -1000,8 +1105,8 @@ H5T_vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, voi FUNC_ENTER_NOAPI_NOINIT(H5T_vlen_reclaim_recurse) - assert(elem); - assert(dt); + HDassert(elem); + HDassert(dt); /* Check the datatype of this element */ switch(dt->shared->type) { @@ -1067,7 +1172,7 @@ H5T_vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, voi else H5MM_xfree(*(char **)elem); } else { - assert(0 && "Invalid VL type"); + HDassert(0 && "Invalid VL type"); } /* end else */ break; @@ -1114,9 +1219,9 @@ H5T_vlen_reclaim(void *elem, hid_t type_id, unsigned UNUSED ndim, const hsize_t FUNC_ENTER_NOAPI(H5T_vlen_reclaim, FAIL) - assert(elem); - assert(vl_alloc_info); - assert(H5I_DATATYPE == H5I_get_type(type_id)); + HDassert(elem); + HDassert(vl_alloc_info); + HDassert(H5I_DATATYPE == H5I_get_type(type_id)); /* Check args */ if (NULL==(dt=H5I_object_verify(type_id,H5I_DATATYPE))) @@ -1161,8 +1266,8 @@ H5T_vlen_get_alloc_info(hid_t dxpl_id, H5T_vlen_alloc_info_t **vl_alloc_info) FUNC_ENTER_NOAPI(H5T_vlen_get_alloc_info, FAIL) - assert(H5I_GENPROP_LST == H5I_get_type(dxpl_id)); - assert(vl_alloc_info); + HDassert(H5I_GENPROP_LST == H5I_get_type(dxpl_id)); + HDassert(vl_alloc_info); /* Check for the default DXPL */ if(dxpl_id==H5P_DATASET_XFER_DEFAULT) diff --git a/src/H5config.h.in b/src/H5config.h.in index a12f3bc..efa3469 100644 --- a/src/H5config.h.in +++ b/src/H5config.h.in @@ -436,6 +436,9 @@ /* Define if your system can handle special collective IO properly. */ #undef MPI_SPECIAL_COLLECTIVE_IO_WORKS +/* Define if we can violate pointer alignment restrictions */ +#undef NO_ALIGNMENT_RESTRICTIONS + /* Define if deprecated public API symbols are disabled */ #undef NO_DEPRECATED_SYMBOLS diff --git a/test/dtypes.c b/test/dtypes.c index 4009d8c..f688371 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -2277,7 +2277,7 @@ test_compound_12(void) /*------------------------------------------------------------------------- - * Function: test_compound_12 + * Function: test_compound_13 * * Purpose: Tests compound datatypes whose size is at the boundary for * needing 2 bytes for the datatype size and "use the latest @@ -2378,6 +2378,364 @@ error: /*------------------------------------------------------------------------- + * Function: test_compound_14 + * + * Purpose: Tests compound type conversions where a vlen string will + be misaligned in the conversion buffer and the file. The + two compound types are meant to trigger two different + conversion routines. + * + * Return: Success: 0 + * + * Failure: number of errors + * + * Programmer: Neil Fortner + * Monday, August 25, 2008 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +test_compound_14(void) +{ + typedef struct cmpd_struct_1 { + char c1; + char c2; + char* str; + } cmpd_struct_1; + + typedef struct cmpd_struct_2 { + char c1; + char c2; + char* str; + long l1; + long l2; + long l3; + long l4; + } cmpd_struct_2; + + cmpd_struct_1 wdata1 = {'A', 'B', "variable-length string"}; + + cmpd_struct_1 rdata1; + cmpd_struct_2 wdata2 = {'C', 'D', "another vlen!", 1, 2, -1, 9001}; + cmpd_struct_2 rdata2; + hid_t file; + hid_t cmpd_m1_tid, cmpd_f1_tid, cmpd_m2_tid, cmpd_f2_tid, str_id; + hid_t space_id; + hid_t dset1_id, dset2_id; + hsize_t dim1[1]; + char filename[1024]; + + TESTING("unaligned VL strings in compound"); + + /* Create File */ + h5_fixname(FILENAME[3], H5P_DEFAULT, filename, sizeof filename); + if((file=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); AT(); + printf("Can't create file!\n"); + goto error; + } /* end if */ + + /* Create memory compound datatype 1 */ + if((cmpd_m1_tid = H5Tcreate( H5T_COMPOUND, sizeof(struct cmpd_struct_1))) < 0) { + H5_FAILED(); AT(); + printf("Can't create datatype!\n"); + goto error; + } /* end if */ + + if(H5Tinsert(cmpd_m1_tid,"c1",HOFFSET(struct cmpd_struct_1,c1),H5T_NATIVE_CHAR) < 0) { + H5_FAILED(); AT(); + printf("Can't insert field 'c1'\n"); + goto error; + } /* end if */ + + if(H5Tinsert(cmpd_m1_tid,"c2",HOFFSET(struct cmpd_struct_1,c2),H5T_NATIVE_CHAR) < 0) { + H5_FAILED(); AT(); + printf("Can't insert field 'c2'\n"); + goto error; + } /* end if */ + + str_id = H5Tcopy(H5T_C_S1); + if(H5Tset_size(str_id,H5T_VARIABLE) < 0) { + H5_FAILED(); AT(); + printf("Can't set size for VL string\n"); + goto error; + } /* end if */ + + if(H5Tinsert(cmpd_m1_tid, "vl_string", HOFFSET(cmpd_struct_1, str), str_id) < 0) { + H5_FAILED(); AT(); + printf("Can't insert field 'vl_string'\n"); + goto error; + } /* end if */ + + /* Create file compound datatype 1 */ + if((cmpd_f1_tid = H5Tcreate( H5T_COMPOUND, 8 + 1 + sizeof(hvl_t))) < 0) { + H5_FAILED(); AT(); + printf("Can't create datatype!\n"); + goto error; + } /* end if */ + + if(H5Tinsert(cmpd_f1_tid,"c1",0,H5T_STD_I64BE) < 0) { + H5_FAILED(); AT(); + printf("Can't insert field 'c1'\n"); + goto error; + } /* end if */ + + if(H5Tinsert(cmpd_f1_tid,"c2",8,H5T_NATIVE_CHAR) < 0) { + H5_FAILED(); AT(); + printf("Can't insert field 'c2'\n"); + goto error; + } /* end if */ + + if(H5Tinsert(cmpd_f1_tid, "vl_string",8 + 1, str_id) < 0) { + H5_FAILED(); AT(); + printf("Can't insert field 'vl_string'\n"); + goto error; + } /* end if */ + + /* Create memory compound datatype 2 */ + if((cmpd_m2_tid = H5Tcreate( H5T_COMPOUND, sizeof(struct cmpd_struct_2))) < 0) { + H5_FAILED(); AT(); + printf("Can't create datatype!\n"); + goto error; + } /* end if */ + + if(H5Tinsert(cmpd_m2_tid,"c1",HOFFSET(struct cmpd_struct_2,c1),H5T_NATIVE_CHAR) < 0) { + H5_FAILED(); AT(); + printf("Can't insert field 'c1'\n"); + goto error; + } /* end if */ + + if(H5Tinsert(cmpd_m2_tid,"c2",HOFFSET(struct cmpd_struct_2,c2),H5T_NATIVE_CHAR) < 0) { + H5_FAILED(); AT(); + printf("Can't insert field 'c2'\n"); + goto error; + } /* end if */ + + if(H5Tinsert(cmpd_m2_tid, "vl_string", HOFFSET(cmpd_struct_2, str), str_id) < 0) { + H5_FAILED(); AT(); + printf("Can't insert field 'vl_string'\n"); + goto error; + } /* end if */ + + if(H5Tinsert(cmpd_m2_tid,"l1",HOFFSET(struct cmpd_struct_2,l1),H5T_NATIVE_LONG) < 0) { + H5_FAILED(); AT(); + printf("Can't insert field 'l1'\n"); + goto error; + } /* end if */ + + if(H5Tinsert(cmpd_m2_tid,"l2",HOFFSET(struct cmpd_struct_2,l2),H5T_NATIVE_LONG) < 0) { + H5_FAILED(); AT(); + printf("Can't insert field 'l2'\n"); + goto error; + } /* end if */ + + if(H5Tinsert(cmpd_m2_tid,"l3",HOFFSET(struct cmpd_struct_2,l3),H5T_NATIVE_LONG) < 0) { + H5_FAILED(); AT(); + printf("Can't insert field 'l3'\n"); + goto error; + } /* end if */ + + if(H5Tinsert(cmpd_m2_tid,"l4",HOFFSET(struct cmpd_struct_2,l4),H5T_NATIVE_LONG) < 0) { + H5_FAILED(); AT(); + printf("Can't insert field 'l4'\n"); + goto error; + } /* end if */ + + /* Create file compound datatype 2 */ + if((cmpd_f2_tid = H5Tcreate( H5T_COMPOUND, 8 + 1 + sizeof(hvl_t) + 4*sizeof(long))) < 0) { + H5_FAILED(); AT(); + printf("Can't create datatype!\n"); + goto error; + } /* end if */ + + if(H5Tinsert(cmpd_f2_tid,"c1",0,H5T_STD_I64BE) < 0) { + H5_FAILED(); AT(); + printf("Can't insert field 'c1'\n"); + goto error; + } /* end if */ + + if(H5Tinsert(cmpd_f2_tid,"c2",8,H5T_NATIVE_CHAR) < 0) { + H5_FAILED(); AT(); + printf("Can't insert field 'c2'\n"); + goto error; + } /* end if */ + + if(H5Tinsert(cmpd_f2_tid, "vl_string", 8 + 1, str_id) < 0) { + H5_FAILED(); AT(); + printf("Can't insert field 'vl_string'\n"); + goto error; + } /* end if */ + + if(H5Tinsert(cmpd_f2_tid,"l1",8 + 1 + sizeof(hvl_t),H5T_NATIVE_LONG) < 0) { + H5_FAILED(); AT(); + printf("Can't insert field 'l1'\n"); + goto error; + } /* end if */ + + if(H5Tinsert(cmpd_f2_tid,"l2",8 + 1 + sizeof(hvl_t) + sizeof(long),H5T_NATIVE_LONG) < 0) { + H5_FAILED(); AT(); + printf("Can't insert field 'l2'\n"); + goto error; + } /* end if */ + + if(H5Tinsert(cmpd_f2_tid,"l3",8 + 1 + sizeof(hvl_t) + 2*sizeof(long),H5T_NATIVE_LONG) < 0) { + H5_FAILED(); AT(); + printf("Can't insert field 'l3'\n"); + goto error; + } /* end if */ + + if(H5Tinsert(cmpd_f2_tid,"l4",8 + 1 + sizeof(hvl_t) + 3*sizeof(long),H5T_NATIVE_LONG) < 0) { + H5_FAILED(); AT(); + printf("Can't insert field 'l4'\n"); + goto error; + } /* end if */ + + dim1[0] = 1; + if((space_id = H5Screate_simple(1, dim1, NULL)) < 0) { + H5_FAILED(); AT(); + printf("Can't create space\n"); + goto error; + } /* end if */ + + if((dset1_id = H5Dcreate2(file, "Dataset1", cmpd_f1_tid, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); AT(); + printf("Can't create dataset\n"); + goto error; + } /* end if */ + + if((dset2_id = H5Dcreate2(file, "Dataset2", cmpd_f2_tid, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); AT(); + printf("Can't create dataset\n"); + goto error; + } /* end if */ + + if(H5Dwrite(dset1_id, cmpd_m1_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wdata1) < 0) { + H5_FAILED(); AT(); + printf("Can't write data\n"); + goto error; + } /* end if */ + + if(H5Dwrite(dset2_id, cmpd_m2_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wdata2) < 0) { + H5_FAILED(); AT(); + printf("Can't write data\n"); + goto error; + } /* end if */ + + if(H5Dread(dset1_id, cmpd_m1_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rdata1) < 0) { + H5_FAILED(); AT(); + printf("Can't read data\n"); + goto error; + } /* end if */ + + if(H5Dread(dset2_id, cmpd_m2_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rdata2) < 0) { + H5_FAILED(); AT(); + printf("Can't read data\n"); + goto error; + } /* end if */ + + if(rdata1.c1 != wdata1.c1 || rdata1.c2 != wdata1.c2 || HDstrcmp(rdata1.str, wdata1.str)) { + H5_FAILED(); AT(); + printf("incorrect read data\n"); + goto error; + } /* end if */ + + if(rdata2.c1 != wdata2.c1 || rdata2.c2 != wdata2.c2 || HDstrcmp(rdata2.str, wdata2.str) || + rdata2.l1 != wdata2.l1 || rdata2.l2 != wdata2.l2 || rdata2.l3 != wdata2.l3 || rdata2.l4 != wdata2.l4) { + H5_FAILED(); AT(); + printf("incorrect read data\n"); + goto error; + } /* end if */ + + if(H5Dclose(dset1_id) < 0) + goto error; + if(H5Dclose(dset2_id) < 0) + goto error; + if(H5Tclose(cmpd_f1_tid) < 0) + goto error; + if(H5Tclose(cmpd_f2_tid) < 0) + goto error; + if(H5Tclose(str_id) < 0) + goto error; + if(H5Sclose(space_id) < 0) + goto error; + if(H5Fclose(file) < 0) + goto error; + + + if((file = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) { + H5_FAILED(); AT(); + printf("cannot open file\n"); + goto error; + } /* end if */ + + if((dset1_id = H5Dopen2(file, "Dataset1", H5P_DEFAULT)) < 0) { + H5_FAILED(); AT(); + printf("cannot open dataset\n"); + goto error; + } /* end if */ + + if((dset2_id = H5Dopen2(file, "Dataset2", H5P_DEFAULT)) < 0) { + H5_FAILED(); AT(); + printf("cannot open dataset\n"); + goto error; + } /* end if */ + + rdata1.c1 = rdata1.c2 = 0; + if(rdata1.str) free(rdata1.str); + + rdata2.c1 = rdata2.c2 = rdata2.l1 = rdata2.l2 = rdata2.l3 = rdata2.l4 = 0; + if(rdata2.str) free(rdata2.str); + + if(H5Dread(dset1_id, cmpd_m1_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rdata1) < 0) { + H5_FAILED(); AT(); + printf("Can't read data\n"); + goto error; + } /* end if */ + + if(H5Dread(dset2_id, cmpd_m2_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rdata2) < 0) { + H5_FAILED(); AT(); + printf("Can't read data\n"); + goto error; + } /* end if */ + + if(rdata1.c1!=wdata1.c1 || rdata1.c2!=wdata1.c2 || strcmp(rdata1.str, wdata1.str)) { + H5_FAILED(); AT(); + printf("incorrect read data\n"); + goto error; + } /* end if */ + + if(rdata2.c1 != wdata2.c1 || rdata2.c2 != wdata2.c2 || HDstrcmp(rdata2.str, wdata2.str) || + rdata2.l1 != wdata2.l1 || rdata2.l2 != wdata2.l2 || rdata2.l3 != wdata2.l3 || rdata2.l4 != wdata2.l4) { + H5_FAILED(); AT(); + printf("incorrect read data\n"); + goto error; + } /* end if */ + + if(rdata1.str) free(rdata1.str); + if(rdata2.str) free(rdata2.str); + + if(H5Dclose(dset1_id) < 0) + goto error; + if(H5Dclose(dset2_id) < 0) + goto error; + if(H5Tclose(cmpd_m1_tid) < 0) + goto error; + if(H5Tclose(cmpd_m2_tid) < 0) + goto error; + if(H5Fclose(file) < 0) + goto error; + + PASSED(); + return 0; + + error: + return 1; +} + + +/*------------------------------------------------------------------------- * Function: test_query * * Purpose: Tests query functions of compound and enumeration types. @@ -5068,6 +5426,7 @@ main(void) nerrors += test_compound_11(); nerrors += test_compound_12(); nerrors += test_compound_13(); + nerrors += test_compound_14(); nerrors += test_conv_enum_1(); nerrors += test_conv_enum_2(); nerrors += test_conv_bitfield(); diff --git a/vms/src/h5pubconf.h b/vms/src/h5pubconf.h index 62bb0a9..a6501df 100644 --- a/vms/src/h5pubconf.h +++ b/vms/src/h5pubconf.h @@ -378,6 +378,9 @@ 2GB. */ /* #undef H5_MPI_FILE_SET_SIZE_BIG */ +/* Define if we can violate pointer alignment restrictions */ +/* #undef H5_NO_ALIGNMENT_RESTRICTIONS */ + /* Define if shared writing must be disabled (CodeWarrior only) */ #define H5_NO_SHARED_WRITING @@ -385,19 +388,19 @@ #define H5_PACKAGE "hdf5" /* Define to the address where bug reports for this package should be sent. */ -#define H5_PACKAGE_BUGREPORT "hdfhelp@ncsa.uiuc.edu" +#define H5_PACKAGE_BUGREPORT "help@hdfgroup.org" /* Define to the full name of this package. */ #define H5_PACKAGE_NAME "HDF5" /* Define to the full name and version of this package. */ -#define H5_PACKAGE_STRING "HDF5 1.7.58" +#define H5_PACKAGE_STRING "HDF5 1.9.17" /* Define to the one symbol short name of this package. */ #define H5_PACKAGE_TARNAME "hdf5" /* Define to the version of this package. */ -#define H5_PACKAGE_VERSION "1.7.58" +#define H5_PACKAGE_VERSION "1.9.17" /* Width for printf() for type `long long' or `__int64', use `ll' */ #define H5_PRINTF_LL_WIDTH "ll" diff --git a/windows/src/H5pubconf.h b/windows/src/H5pubconf.h index 8b7330d..0633aea 100755 --- a/windows/src/H5pubconf.h +++ b/windows/src/H5pubconf.h @@ -456,6 +456,9 @@ /* Define if your system can handle special collective IO properly. */ #define H5_MPI_SPECIAL_COLLECTIVE_IO_WORKS 1 +/* Define if we can violate pointer alignment restrictions */ +#define H5_NO_ALIGNMENT_RESTRICTIONS 1 + /* Define if deprecated public API symbols are disabled */ /* #undef H5_NO_DEPRECATED_SYMBOLS */ -- cgit v0.12