diff options
35 files changed, 737 insertions, 267 deletions
diff --git a/CMakeInstallation.cmake b/CMakeInstallation.cmake index f5c2dda..1df5311 100644 --- a/CMakeInstallation.cmake +++ b/CMakeInstallation.cmake @@ -363,6 +363,8 @@ if (NOT HDF5_EXTERNALLY_CONFIGURED AND NOT HDF5_NO_PACKAGES) set(CPACK_WIX_PROPERTY_ARPCOMMENTS "HDF5 (Hierarchical Data Format 5) Software Library and Utilities") set(CPACK_WIX_PROPERTY_ARPURLINFOABOUT "${HDF5_PACKAGE_URL}") set(CPACK_WIX_PROPERTY_ARPHELPLINK "${HDF5_PACKAGE_BUGREPORT}") + + set(CPACK_WIX_PATCH_FILE "${HDF_RESOURCES_DIR}/patch.xml") elseif (APPLE) list (APPEND CPACK_GENERATOR "DragNDrop") set (CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE ON) @@ -455,14 +457,10 @@ The HDF5 data model, file format, API, library, and tools are open and distribut if (HDF5_PACKAGE_EXTLIBS) if (HDF5_ALLOW_EXTERNAL_SUPPORT MATCHES "SVN" OR HDF5_ALLOW_EXTERNAL_SUPPORT MATCHES "TGZ") if (ZLIB_FOUND AND ZLIB_USE_EXTERNAL) - set (CPACK_INSTALL_CMAKE_PROJECTS "${CPACK_INSTALL_CMAKE_PROJECTS};${ZLIB_INCLUDE_DIR_GEN};ZLIB;libraries;/") - set (CPACK_INSTALL_CMAKE_PROJECTS "${CPACK_INSTALL_CMAKE_PROJECTS};${ZLIB_INCLUDE_DIR_GEN};ZLIB;headers;/") - set (CPACK_INSTALL_CMAKE_PROJECTS "${CPACK_INSTALL_CMAKE_PROJECTS};${ZLIB_INCLUDE_DIR_GEN};ZLIB;configinstall;/") + set (CPACK_INSTALL_CMAKE_PROJECTS "${CPACK_INSTALL_CMAKE_PROJECTS};${ZLIB_INCLUDE_DIR_GEN};ZLIB;ALL;/") endif (ZLIB_FOUND AND ZLIB_USE_EXTERNAL) if (SZIP_FOUND AND SZIP_USE_EXTERNAL) - set (CPACK_INSTALL_CMAKE_PROJECTS "${CPACK_INSTALL_CMAKE_PROJECTS};${SZIP_INCLUDE_DIR_GEN};SZIP;libraries;/") - set (CPACK_INSTALL_CMAKE_PROJECTS "${CPACK_INSTALL_CMAKE_PROJECTS};${SZIP_INCLUDE_DIR_GEN};SZIP;headers;/") - set (CPACK_INSTALL_CMAKE_PROJECTS "${CPACK_INSTALL_CMAKE_PROJECTS};${SZIP_INCLUDE_DIR_GEN};SZIP;configinstall;/") + set (CPACK_INSTALL_CMAKE_PROJECTS "${CPACK_INSTALL_CMAKE_PROJECTS};${SZIP_INCLUDE_DIR_GEN};SZIP;ALL;/") endif (SZIP_FOUND AND SZIP_USE_EXTERNAL) endif (HDF5_ALLOW_EXTERNAL_SUPPORT MATCHES "SVN" OR HDF5_ALLOW_EXTERNAL_SUPPORT MATCHES "TGZ") endif (HDF5_PACKAGE_EXTLIBS) @@ -474,6 +472,8 @@ The HDF5 data model, file format, API, library, and tools are open and distribut cpack_add_component_group(Runtime) + cpack_add_component_group(Documents) + cpack_add_component_group(Development EXPANDED DESCRIPTION "All of the tools you'll need to develop HDF5 applications" @@ -814,6 +814,7 @@ ./src/H5Ptest.c ./src/H5PL.c ./src/H5PLprivate.h +./src/H5PLpublic.h ./src/H5PLextern.h ./src/H5R.c ./src/H5Rdeprec.c @@ -2335,6 +2336,7 @@ ./config/cmake/HDF5Macros.cmake ./config/cmake/libhdf5.settings.cmake.in ./config/cmake/mccacheinit.cmake +./config/cmake/patch.xml ./config/cmake/PkgInfo.in ./config/cmake/README.txt.cmake.in ./config/cmake/userblockTest.cmake @@ -48,7 +48,7 @@ done]) case $$3 in #( no | unknown) ;; *) AC_DEFINE_UNQUOTED([$1], [$$3], [$4]) - H5_CPPFLAGS="-D$1=$$3 $H5_CPPFLAGS";; + AM_CPPFLAGS="-D$1=$$3 $AM_CPPFLAGS";; esac rm -rf conftest*[]dnl ])# _AC_SYS_LARGEFILE_MACRO_VALUE diff --git a/config/cmake/ConfigureChecks.cmake b/config/cmake/ConfigureChecks.cmake index e2d770c..4dff2c2 100644 --- a/config/cmake/ConfigureChecks.cmake +++ b/config/cmake/ConfigureChecks.cmake @@ -353,10 +353,7 @@ H5ConversionTests (H5_FP_TO_INTEGER_OVERFLOW_WORKS "Checking IF overflows norma # The machine's conversion gets the correct value. We define the macro and disable # this kind of test until we figure out what algorithm they use. # -if (H5_LDOUBLE_TO_LONG_SPECIAL MATCHES ^H5_LDOUBLE_TO_LONG_SPECIAL$) - set (H5_LDOUBLE_TO_LONG_SPECIAL 0 CACHE INTERNAL "Define if your system converts long double to (unsigned) long values with special algorithm") - message (STATUS "Checking IF your system converts long double to (unsigned) long values with special algorithm... no") -endif (H5_LDOUBLE_TO_LONG_SPECIAL MATCHES ^H5_LDOUBLE_TO_LONG_SPECIAL$) +H5ConversionTests (H5_LDOUBLE_TO_LONG_SPECIAL "Checking IF your system converts long double to (unsigned) long values with special algorithm") # ---------------------------------------------------------------------- # Set the flag to indicate that the machine is using a special algorithm # to convert some values of '(unsigned) long' to 'long double' values. @@ -365,10 +362,7 @@ endif (H5_LDOUBLE_TO_LONG_SPECIAL MATCHES ^H5_LDOUBLE_TO_LONG_SPECIAL$) # ..., 7fffff..., the compiler uses a unknown algorithm. We define a # macro and skip the test for now until we know about the algorithm. # -if (H5_LONG_TO_LDOUBLE_SPECIAL MATCHES ^H5_LONG_TO_LDOUBLE_SPECIAL$) - set (H5_LONG_TO_LDOUBLE_SPECIAL 0 CACHE INTERNAL "Define if your system can convert (unsigned) long to long double values with special algorithm") - message (STATUS "Checking IF your system can convert (unsigned) long to long double values with special algorithm... no") -endif (H5_LONG_TO_LDOUBLE_SPECIAL MATCHES ^H5_LONG_TO_LDOUBLE_SPECIAL$) +H5ConversionTests (H5_LONG_TO_LDOUBLE_SPECIAL "Checking IF your system can convert (unsigned) long to long double values with special algorithm") # ---------------------------------------------------------------------- # Set the flag to indicate that the machine can accurately convert # 'long double' to '(unsigned) long long' values. (This flag should be set for diff --git a/config/cmake/ConversionTests.c b/config/cmake/ConversionTests.c index 9c681bc..7238af0 100644 --- a/config/cmake/ConversionTests.c +++ b/config/cmake/ConversionTests.c @@ -61,6 +61,124 @@ done: #endif +#ifdef H5_LDOUBLE_TO_LONG_SPECIAL_TEST + +int main(void) +{ + long double ld = 20041683600089727.779961L; + long ll; + unsigned long ull; + unsigned char s[16]; + unsigned char s2[8]; + int ret = 1; + + if(sizeof(long double) == 16 && sizeof(long) == 8) { + /*make sure the long double type has 16 bytes in size and + * 11 bits of exponent. If it is, + *the bit sequence should be like below. It's not + *a decent way to check but this info isn't available. */ + memcpy(s, &ld, 16); + if(s[0]==0x43 && s[1]==0x51 && s[2]==0xcc && s[3]==0xf3 && + s[4]==0x85 && s[5]==0xeb && s[6]==0xc8 && s[7]==0xa0 && + s[8]==0xbf && s[9]==0xcc && s[10]==0x2a && s[11]==0x3c) { + + /* Assign the hexadecimal value of long double type. */ + s[0]=0x43; s[1]=0x51; s[2]=0xcc; s[3]=0xf3; + s[4]=0x85; s[5]=0xeb; s[6]=0xc8; s[7]=0xa0; + s[8]=0xbf; s[9]=0xcc; s[10]=0x2a; s[11]=0x3c; + s[12]=0x3d; s[13]=0x85; s[14]=0x56; s[15]=0x20; + + memcpy(&ld, s, 16); + + ll = (long)ld; + memcpy(s2, &ll, 8); + + /* The library's algorithm converts it to 0x 00 47 33 ce 17 af 22 82 + * and gets wrong value 20041683600089730 on the IBM Power6 Linux. + * But the IBM Power6 Linux converts it to 0x00 47 33 ce 17 af 22 7f + * and gets the correct value 20041683600089727. It uses some special + * algorithm. We're going to define the macro and skip the test until + * we can figure out how they do it. */ + if(s2[0]==0x00 && s2[1]==0x47 && s2[2]==0x33 && s2[3]==0xce && + s2[4]==0x17 && s2[5]==0xaf && s2[6]==0x22 && s2[7]==0x7f) + ret = 0; + + ull = (unsigned long)ld; + memcpy(s2, &ull, 8); + + /* The unsigned long is the same as signed long. */ + if(s2[0]==0x00 && s2[1]==0x47 && s2[2]==0x33 && s2[3]==0xce && + s2[4]==0x17 && s2[5]==0xaf && s2[6]==0x22 && s2[7]==0x7f) + ret = 0; + } + } + +done: + exit(ret); +} + +#endif + +#ifdef H5_LONG_TO_LDOUBLE_SPECIAL_TEST + +int main(void) +{ + long double ld; + long ll; + unsigned long ull; + unsigned char s[16]; + int flag=0, ret=1; + + /*Determine if long double has 16 byte in size, 11 bit exponent, and + *the bias is 0x3ff */ + if(sizeof(long double) == 16) { + ld = 1.0L; + memcpy(s, &ld, 16); + if(s[0]==0x3f && s[1]==0xf0 && s[2]==0x00 && s[3]==0x00 && + s[4]==0x00 && s[5]==0x00 && s[6]==0x00 && s[7]==0x00) + flag = 1; + } + + if(flag==1 && sizeof(long)==8) { + ll = 0x003fffffffffffffL; + ld = (long double)ll; + memcpy(s, &ld, 16); + /* The library converts the value to 0x434fffffffffffff8000000000000000. + * In decimal it is 18014398509481982.000000, one value short of the original. + * The IBM Power6 Linux converts it to 0x4350000000000000bff0000000000000. + * The value is correct in decimal. It uses some special + * algorithm. We're going to define the macro and skip the test until + * we can figure out how they do it. */ + if(s[0]==0x43 && s[1]==0x50 && s[2]==0x00 && s[3]==0x00 && + s[4]==0x00 && s[5]==0x00 && s[6]==0x00 && s[7]==0x00 && + s[8]==0xbf && s[9]==0xf0 && s[10]==0x00 && s[11]==0x00 && + s[12]==0x00 && s[13]==0x00 && s[14]==0x00 && s[15]==0x00) + ret = 0; + } + if(flag==1 && sizeof(unsigned long)==8) { + ull = 0xffffffffffffffffUL; + ld = (long double)ull; + memcpy(s, &ld, 16); + /* Use a different value from signed long to test. The problem is the same + * for both long and unsigned long. The value is 18446744073709551615. + * The library converts the value to 0x43effffffffffffffe000000000000000. + * In decimal it's 18446744073709548544.000000, very different from the original. + * The IBM Power6 Linux converts it to 0x43f0000000000000bff0000000000000. + * The value is correct in decimal. It uses some special + * algorithm. We're going to define the macro and skip the test until + * we can figure out how they do it. */ + if(s[0]==0x43 && s[1]==0xf0 && s[2]==0x00 && s[3]==0x00 && + s[4]==0x00 && s[5]==0x00 && s[6]==0x00 && s[7]==0x00 && + s[8]==0xbf && s[9]==0xf0 && s[10]==0x00 && s[11]==0x00 && + s[12]==0x00 && s[13]==0x00 && s[14]==0x00 && s[15]==0x00) + ret = 0; + } +done: + exit(ret); +} + +#endif + #ifdef H5_LDOUBLE_TO_LLONG_ACCURATE_TEST int main(void) { diff --git a/config/cmake/patch.xml b/config/cmake/patch.xml new file mode 100644 index 0000000..70571c5 --- /dev/null +++ b/config/cmake/patch.xml @@ -0,0 +1,11 @@ +<CPackWiXPatch> + <CPackWiXFragment Id="CM_CP_libraries.bin.hdf5.dll"> + <Environment Id="PATH" + Name="PATH" + Value="[CM_DP_libraries.bin]" + Permanent="no" + Part="last" + Action="set" + System="yes"/> + </CPackWiXFragment> +</CPackWiXPatch> diff --git a/configure.ac b/configure.ac index b7a005a..eacc078 100644 --- a/configure.ac +++ b/configure.ac @@ -1097,7 +1097,7 @@ case "$host_cpu-$host_vendor-$host_os" in *linux*) ## Make available various LFS-related routines using the following ## _LARGEFILE*_SOURCE macros. - H5_CPPFLAGS="-D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE $H5_CPPFLAGS" + AM_CPPFLAGS="-D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE $AM_CPPFLAGS" ## Add POSIX support on Linux systems, so <features.h> defines ## __USE_POSIX, which is required to get the prototype for fdopen diff --git a/hl/tools/gif2h5/gif.h b/hl/tools/gif2h5/gif.h index 5334919..f34a111 100644 --- a/hl/tools/gif2h5/gif.h +++ b/hl/tools/gif2h5/gif.h @@ -143,7 +143,7 @@ typedef struct _GifToMem { */ /* GIF2MEM.C */ -GIFTOMEM Gif2Mem(BYTE *); +int Gif2Mem(BYTE *, GIFTOMEM *); /* GIFREAD.C */ int ReadGifHeader(GIFHEAD *, BYTE **); diff --git a/hl/tools/gif2h5/gif2hdf.c b/hl/tools/gif2h5/gif2hdf.c index 810be78..8a9e971 100644 --- a/hl/tools/gif2h5/gif2hdf.c +++ b/hl/tools/gif2h5/gif2hdf.c @@ -99,7 +99,7 @@ main(int argv , char *argc[]) * Call Gif2Mem and break the whole file into parts. Gif2Mem also calls * decompresses the images so we don't have to worry about that */ - GifMemoryStruct = Gif2Mem(MemGif); + Gif2Mem(MemGif, &GifMemoryStruct); if (ferror(fpGif)) { printf("File Stream Error\n\n"); diff --git a/hl/tools/gif2h5/gif2mem.c b/hl/tools/gif2h5/gif2mem.c index ac4b0ec..a2e4893 100644 --- a/hl/tools/gif2h5/gif2mem.c +++ b/hl/tools/gif2h5/gif2mem.c @@ -37,8 +37,8 @@ #include "gif.h" -GIFTOMEM -Gif2Mem(BYTE *MemGif) +int +Gif2Mem(BYTE *MemGif, GIFTOMEM *GifMemoryStruct) { /* * The gif structure outline for passing data to memory is given in gif.h. @@ -51,8 +51,6 @@ Gif2Mem(BYTE *MemGif) GIFCOMMENT **gifComment; /* Comment Extension structure */ GIFGRAPHICCONTROL **gifGraphicControl; /* Graphic Control Extension strct */ - GIFTOMEM GifMemoryStruct; - register WORD i; /* Loop counter */ BYTE Identifier; /* Extension block identifier holder */ BYTE Label; /* Extension block label holder */ @@ -133,15 +131,15 @@ Gif2Mem(BYTE *MemGif) gifHead->PlainTextCount = PlainTextCount; /* putting stuff into the gif2mem structure */ - GifMemoryStruct.GifHeader = gifHead; - GifMemoryStruct.GifImageDesc = gifImageDesc; - GifMemoryStruct.GifPlainTextExtension = gifPlainText; - GifMemoryStruct.GifApplicationExtension = gifApplication; - GifMemoryStruct.GifCommentExtension = gifComment; - GifMemoryStruct.GifGraphicControlExtension = gifGraphicControl; + GifMemoryStruct->GifHeader = gifHead; + GifMemoryStruct->GifImageDesc = gifImageDesc; + GifMemoryStruct->GifPlainTextExtension = gifPlainText; + GifMemoryStruct->GifApplicationExtension = gifApplication; + GifMemoryStruct->GifCommentExtension = gifComment; + GifMemoryStruct->GifGraphicControlExtension = gifGraphicControl; /* return the struct */ - return GifMemoryStruct; + return 0; case 0x2C: /* Image Descriptor */ /* diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d9e7195..999420c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -482,6 +482,7 @@ set (H5PL_SRCS set (H5PL_HDRS ${HDF5_SRC_DIR}/H5PLextern.h + ${HDF5_SRC_DIR}/H5PLpublic.h ) IDE_GENERATED_PROPERTIES ("H5PL" "${H5PL_HDRS}" "${H5PL_SRCS}" ) @@ -860,27 +860,109 @@ H5close(void) /*------------------------------------------------------------------------- + * Function: H5allocate_memory + * + * Purpose: Allocate a memory buffer with the semantics of malloc(). + * + * NOTE: This function is intended for use with filter + * plugins so that all allocation and free operations + * use the same memory allocator. It is not intended for + * use as a general memory allocator in applications. + * + * Parameters: + * + * size: The size of the buffer. + * + * clear: Whether or not to memset the buffer to 0. + * + * Return: + * + * Success: A pointer to the allocated buffer. + * + * Failure: NULL + * + *------------------------------------------------------------------------- + */ +void * +H5allocate_memory(size_t size, hbool_t clear) +{ + void *ret_value = NULL; + + FUNC_ENTER_API_NOINIT; + H5TRACE2("*x", "zb", size, clear); + + if(clear) + ret_value = H5MM_calloc(size); + else + ret_value = H5MM_malloc(size); + + FUNC_LEAVE_API(ret_value) + +} /* end H5allocate_memory() */ + + +/*------------------------------------------------------------------------- + * Function: H5resize_memory + * + * Purpose: Resize a memory buffer with the semantics of realloc(). + * + * NOTE: This function is intended for use with filter + * plugins so that all allocation and free operations + * use the same memory allocator. It is not intended for + * use as a general memory allocator in applications. + * + * Parameters: + * + * mem: The buffer to be resized. + * + * size: The size of the buffer. + * + * Return: + * + * Success: A pointer to the resized buffer. + * + * Failure: NULL (the input buffer will be unchanged) + * + *------------------------------------------------------------------------- + */ +void * +H5resize_memory(void *mem, size_t size) +{ + void *ret_value = NULL; + + FUNC_ENTER_API_NOINIT; + H5TRACE2("*x", "*xz", mem, size); + + ret_value = H5MM_realloc(mem, size); + + FUNC_LEAVE_API(ret_value) + +} /* end H5resize_memory() */ + + +/*------------------------------------------------------------------------- * Function: H5free_memory * - * Purpose: Frees memory allocated by the library that it is the user's + * Purpose: Frees memory allocated by the library that it is the user's * responsibility to free. Ensures that the same library * that was used to allocate the memory frees it. Passing * NULL pointers is allowed. * - * Return: SUCCEED/FAIL + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ herr_t H5free_memory(void *mem) { - FUNC_ENTER_API_NOINIT + FUNC_ENTER_API_NOINIT; H5TRACE1("e", "*x", mem); /* At this time, it is impossible for this to fail. */ HDfree(mem); FUNC_LEAVE_API(SUCCEED) + } /* end H5free_memory() */ @@ -944,3 +1026,4 @@ DllMain(_In_ HINSTANCE hinstDLL, _In_ DWORD fdwReason, _In_ LPVOID lpvReserved) return fOkay; } #endif /* H5_HAVE_WIN32_API && H5_BUILT_AS_DYNAMIC_LIB && H5_HAVE_WIN_THREADS && H5_HAVE_THREADSAFE*/ + @@ -182,7 +182,7 @@ HDmemset(heap->chunk, 0, size); * which was always at least H5HG_ALIGNMENT aligned then we could just * align the pointer, but this might not be the case. */ - n = H5HG_ALIGN(p - heap->chunk) - (p - heap->chunk); + n = H5HG_ALIGN(p - heap->chunk) - (size_t)(p - heap->chunk); #ifdef OLD_WAY /* Don't bother zeroing out the rest of the info in the heap -QAK */ HDmemset(p, 0, n); @@ -776,7 +776,7 @@ H5HG_remove (H5F_t *f, hid_t dxpl_id, H5HG_t *hobj) else heap->obj[0].size += need; HDmemmove(obj_start, obj_start + need, - heap->size - ((obj_start + need) - heap->chunk)); + heap->size - (size_t)((obj_start + need) - heap->chunk)); if(heap->obj[0].size >= H5HG_SIZEOF_OBJHDR(f)) { p = heap->obj[0].begin; UINT16ENCODE(p, 0); /*id*/ diff --git a/src/H5HGpkg.h b/src/H5HGpkg.h index 5d4234f..274e0e3 100644 --- a/src/H5HGpkg.h +++ b/src/H5HGpkg.h @@ -77,7 +77,7 @@ H5FL_BLK_EXTERN(gheap_chunk); * largest data type is eight bytes. */ #define H5HG_ALIGNMENT 8 -#define H5HG_ALIGN(X) (H5HG_ALIGNMENT*(((X)+H5HG_ALIGNMENT-1)/ \ +#define H5HG_ALIGN(X) (size_t)(H5HG_ALIGNMENT*(((X)+H5HG_ALIGNMENT-1)/ \ H5HG_ALIGNMENT)) #define H5HG_ISALIGNED(X) ((X)==H5HG_ALIGN(X)) @@ -108,8 +108,8 @@ H5FL_BLK_EXTERN(gheap_chunk); * some overhead and each message has some overhead. The `+2' accounts for * rounding and for the free space object. */ -#define H5HG_NOBJS(f,z) (int)((((z)-H5HG_SIZEOF_HDR(f))/ \ - H5HG_SIZEOF_OBJHDR(f)+2)) +#define H5HG_NOBJS(f,z) ((((z)-H5HG_SIZEOF_HDR(f))/ \ + H5HG_SIZEOF_OBJHDR(f)+2)) /****************************/ @@ -31,93 +31,107 @@ #include "H5Eprivate.h" #include "H5MMprivate.h" -#ifndef NDEBUG /*------------------------------------------------------------------------- - * Function: H5MM_malloc + * Function: H5MM_malloc * - * Purpose: Just like the POSIX version of malloc(3). This routine - * specifically checks for allocations of 0 bytes and fails - * in that case. This routine is not called when NDEBUG is - * defined. + * Purpose: Similar to the C89 version of malloc(). * - * Return: Success: Ptr to new memory + * On size of 0, we return a NULL pointer instead of the + * standard-allowed 'special' pointer since that's more + * difficult to check as a return value. This is still + * considered an error condition since allocations of zero + * bytes usually indicate problems. + * + * Return: Success: Pointer new memory * - * Failure: NULL + * Failure: NULL * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Nov 8 2003 - * - * Modifications: + * Programmer: Quincey Koziol + * Nov 8 2003 * *------------------------------------------------------------------------- */ void * H5MM_malloc(size_t size) { + void *ret_value; + + HDassert(size); + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ FUNC_ENTER_NOAPI_NOINIT_NOERR - HDassert(size); + if(size) + ret_value = HDmalloc(size); + else + ret_value = NULL; - FUNC_LEAVE_NOAPI(HDmalloc(size)); + FUNC_LEAVE_NOAPI(ret_value); } /* end H5MM_malloc() */ /*------------------------------------------------------------------------- - * Function: H5MM_calloc + * Function: H5MM_calloc * - * Purpose: Similar to the POSIX version of calloc(3), except this routine - * just takes a 'size' parameter. This routine - * specifically checks for allocations of 0 bytes and fails - * in that case. This routine is not called when NDEBUG is - * defined. + * Purpose: Similar to the C89 version of calloc(), except this + * routine just takes a 'size' parameter. * - * Return: Success: Ptr to new memory + * On size of 0, we return a NULL pointer instead of the + * standard-allowed 'special' pointer since that's more + * difficult to check as a return value. This is still + * considered an error condition since allocations of zero + * bytes usually indicate problems. * - * Failure: NULL * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Nov 8 2003 + * Return: Success: Pointer new memory * - * Modifications: + * Failure: NULL + * + * Programmer: Quincey Koziol + * Nov 8 2003 * *------------------------------------------------------------------------- */ void * H5MM_calloc(size_t size) { + void *ret_value; + + HDassert(size); + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ FUNC_ENTER_NOAPI_NOINIT_NOERR - HDassert(size); + if(size) + ret_value = HDcalloc((size_t)1, size); + else + ret_value = NULL; - FUNC_LEAVE_NOAPI(HDcalloc(1,size)); + FUNC_LEAVE_NOAPI(ret_value); } /* end H5MM_calloc() */ -#endif /* NDEBUG */ /*------------------------------------------------------------------------- - * Function: H5MM_realloc + * Function: H5MM_realloc * - * Purpose: Just like the POSIX version of realloc(3). Specifically, the - * following calls are equivalent + * Purpose: Similar semantics as C89's realloc(). Specifically, the + * following calls are equivalent: * - * H5MM_realloc (NULL, size) <==> H5MM_malloc (size) - * H5MM_realloc (ptr, 0) <==> H5MM_xfree (ptr) - * H5MM_realloc (NULL, 0) <==> NULL + * H5MM_realloc(NULL, size) <==> H5MM_malloc(size) + * H5MM_realloc(ptr, 0) <==> H5MM_xfree(ptr) + * H5MM_realloc(NULL, 0) <==> NULL * - * Return: Success: Ptr to new memory or NULL if the memory - * was freed or HDrealloc couldn't allocate - * memory. + * Note that the (NULL, 0) combination is undefined behavior + * in the C standard. * - * Failure: NULL + * Return: Success: Ptr to new memory if size > 0 + * NULL if size is zero * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 10 1997 + * Failure: NULL (input buffer is unchanged on failure) + * + * Programmer: Robb Matzke + * Jul 10 1997 * *------------------------------------------------------------------------- */ @@ -129,16 +143,19 @@ H5MM_realloc(void *mem, size_t size) /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ FUNC_ENTER_NOAPI_NOINIT_NOERR - if(NULL == mem) { - if(0 == size) + HDassert(mem || size); + + if(NULL == mem && 0 == size) { + /* Not defined in the standard, return NULL */ + ret_value = NULL; + } + else { + ret_value = HDrealloc(mem, size); + + /* Some platforms do not return NULL if size is zero. */ + if(0 == size) ret_value = NULL; - else - ret_value = H5MM_malloc(size); - } /* end if */ - else if(0 == size) - ret_value = H5MM_xfree(mem); - else - ret_value = HDrealloc(mem, size); + } FUNC_LEAVE_NOAPI(ret_value) } /* end H5MM_realloc() */ diff --git a/src/H5MMprivate.h b/src/H5MMprivate.h index a3c39f0..0d608b2 100644 --- a/src/H5MMprivate.h +++ b/src/H5MMprivate.h @@ -33,19 +33,13 @@ /* Private headers needed by this file */ #include "H5private.h" -#ifdef NDEBUG -#define H5MM_malloc(Z) HDmalloc(Z) -#define H5MM_calloc(Z) HDcalloc((size_t)1,Z) -#endif /* NDEBUG */ #define H5MM_free(Z) HDfree(Z) /* * Library prototypes... */ -#ifndef NDEBUG H5_DLL void *H5MM_malloc(size_t size); H5_DLL void *H5MM_calloc(size_t size); -#endif /* NDEBUG */ H5_DLL void *H5MM_realloc(void *mem, size_t size); H5_DLL char *H5MM_xstrdup(const char *s); H5_DLL char *H5MM_strdup(const char *s); diff --git a/src/H5Oalloc.c b/src/H5Oalloc.c index 5c00fb2..76f392d 100644 --- a/src/H5Oalloc.c +++ b/src/H5Oalloc.c @@ -762,7 +762,7 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size, size_t *new size_t idx; /* Message number */ uint8_t *p = NULL; /*ptr into new chunk */ H5O_cont_t *cont = NULL; /*native continuation message */ - unsigned chunkno; /* Chunk allocated */ + size_t chunkno; /* Chunk allocated */ haddr_t new_chunk_addr; unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ @@ -97,6 +97,7 @@ typedef const void *(__cdecl *H5PL_get_plugin_info_t)(void); typedef const void *(*H5PL_get_plugin_info_t)(void); #endif /* H5_HAVE_WIN32_API */ +/* Whether to preload pathnames for plugin libraries */ #define H5PL_DEFAULT_PATH H5_DEFAULT_PLUGINDIR /* Special symbol to indicate no plugin loading */ @@ -149,8 +150,8 @@ static char *H5PL_path_table_g[H5PL_MAX_PATH_NUM]; static size_t H5PL_num_paths_g = 0; static hbool_t H5PL_path_found_g = FALSE; -/* Whether to preload pathnames for plugin libraries */ -static hbool_t H5PL_no_plugin_g = FALSE; +/* Enable all plugin libraries */ +static unsigned int H5PL_plugin_g = H5PL_ALL_PLUGIN; /*-------------------------------------------------------------------------- @@ -177,7 +178,7 @@ H5PL__init_interface(void) if(NULL != (preload_path = HDgetenv("HDF5_PLUGIN_PRELOAD"))) { /* Special symbal "::" means no plugin during data reading. */ if(!HDstrcmp(preload_path, H5PL_NO_PLUGIN)) - H5PL_no_plugin_g = TRUE; + H5PL_plugin_g = 0; } /* end if */ FUNC_LEAVE_NOAPI(SUCCEED) @@ -185,31 +186,68 @@ H5PL__init_interface(void) /*------------------------------------------------------------------------- - * Function: H5PL_no_plugin + * Function: H5PLset_loading_state * - * Purpose: Quick way for filter module to query whether to load plugin + * Purpose: Control the loading of dynamic plugin types. * - * Return: TRUE: No plugin loading during data reading + * This function will not allow plugin types if the pathname from the HDF5_PLUGIN_PRELOAD + * environment variable is set to the special "::" string. * - * FALSE: Load plugin during data reading + * plugin bit = 0, will prevent the use of that dynamic plugin type. + * plugin bit = 1, will allow the use of that dynamic plugin type. * - * Programmer: Raymond Lu - * 20 February 2013 + * H5PL_TYPE_FILTER changes just dynamic filters + * A H5PL_ALL_PLUGIN will enable all dynamic plugin types + * A zero value will disable all dynamic plugin types + * + * Return: Non-negative or success * *------------------------------------------------------------------------- */ -htri_t -H5PL_no_plugin(void) +herr_t +H5PLset_loading_state(unsigned int plugin_type) { - htri_t ret_value; + char *preload_path; + herr_t ret_value = SUCCEED; /* Return value */ + FUNC_ENTER_API(FAIL) + H5TRACE1("e", "Iu", plugin_type); + /* change the bit value of the requested plugin type(s) */ + H5PL_plugin_g = plugin_type; + /* check if special ENV variable is set and disable all plugin types */ + if(NULL != (preload_path = HDgetenv("HDF5_PLUGIN_PRELOAD"))) { + /* Special symbol "::" means no plugin during data reading. */ + if(!HDstrcmp(preload_path, H5PL_NO_PLUGIN)) + H5PL_plugin_g = 0; + } +done: + FUNC_LEAVE_API(ret_value) +} /* end H5PLset_loading_state() */ - FUNC_ENTER_NOAPI(FAIL) - ret_value = (htri_t)H5PL_no_plugin_g; +/*------------------------------------------------------------------------- + * Function: H5PLget_loading_state + * + * Purpose: Query state of the loading of dynamic plugin types. + * + * This function will return the state of the global flag. + * + * Return: Zero if all plugin types are disabled, negative if all + * plugin types are enabled, positive if one or more of the plugin types are enabled. + * + *------------------------------------------------------------------------- + */ +herr_t +H5PLget_loading_state(unsigned int* plugin_type) +{ + herr_t ret_value = SUCCEED; /* Return value */ + FUNC_ENTER_API(FAIL) + + if(plugin_type) + *plugin_type = H5PL_plugin_g; + done: + FUNC_LEAVE_API(ret_value) +} /* end H5PLget_loading_state() */ -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5PL_no_plugin() */ /*------------------------------------------------------------------------- @@ -285,9 +323,14 @@ H5PL_load(H5PL_type_t type, int id) FUNC_ENTER_NOAPI(NULL) - /* Check for "no plugins" indicated" */ - if(H5PL_no_plugin_g) - HGOTO_ERROR(H5E_PLUGIN, H5E_CANTLOAD, NULL, "required dynamically loaded plugin filter '%d' is not available", id) + switch (type) { + case H5PL_TYPE_FILTER: + if((H5PL_plugin_g & H5PL_FILTER_PLUGIN) == 0) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTLOAD, NULL, "required dynamically loaded plugin filter '%d' is not available", id) + break; + default: + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTLOAD, NULL, "required dynamically loaded plugin '%d' is not valid", id) + } /* Initialize the location paths for dynamic libraries, if they aren't * already set up. diff --git a/src/H5PLextern.h b/src/H5PLextern.h index 8ad19e7..3264435 100644 --- a/src/H5PLextern.h +++ b/src/H5PLextern.h @@ -22,18 +22,6 @@ /* Include HDF5 header */ #include "hdf5.h" -/*******************/ -/* Public Typedefs */ -/*******************/ - -/* Plugin type */ -typedef enum H5PL_type_t { - H5PL_TYPE_ERROR = -1, /*error */ - H5PL_TYPE_FILTER = 0, /*filter */ - H5PL_TYPE_NONE = 1 /*this must be last! */ -} H5PL_type_t; - - /* plugins always export */ #if defined (_MSC_VER) /* MSVC Compiler Case */ #define H5PLUGIN_DLL __declspec(dllexport) diff --git a/src/H5PLprivate.h b/src/H5PLprivate.h index 587a51b..77e115b 100644 --- a/src/H5PLprivate.h +++ b/src/H5PLprivate.h @@ -19,18 +19,8 @@ #ifndef _H5PLprivate_H #define _H5PLprivate_H -/* Keep the following in sync with the package's "external" header */ - -/*******************/ -/* Public Typedefs */ -/*******************/ - -/* Plugin type */ -typedef enum H5PL_type_t { - H5PL_TYPE_ERROR = -1, /*error */ - H5PL_TYPE_FILTER = 0, /*filter */ - H5PL_TYPE_NONE = 1 /*this must be last! */ -} H5PL_type_t; +/* Include package's public header */ +#include "H5PLpublic.h" /* Private headers needed by this file */ #include "H5private.h" /* Generic Functions */ @@ -57,7 +47,6 @@ typedef enum H5PL_type_t { /* Internal API routines */ H5_DLL const void *H5PL_load(H5PL_type_t plugin_type, int type_id); -H5_DLL htri_t H5PL_no_plugin(void); #endif /* _H5PLprivate_H */ diff --git a/src/H5PLpublic.h b/src/H5PLpublic.h new file mode 100644 index 0000000..1dae3b7 --- /dev/null +++ b/src/H5PLpublic.h @@ -0,0 +1,53 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * 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 document set and is * + * linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have access * + * to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* Programmer: Raymond Lu <songyulu@hdfgroup.org> + * 13 February 2013 + */ + +#ifndef _H5PLpublic_H +#define _H5PLpublic_H + +/* Public headers needed by this file */ +#include "H5public.h" /* Generic Functions */ + +/*******************/ +/* Public Typedefs */ +/*******************/ + +/* Plugin type */ +typedef enum H5PL_type_t { + H5PL_TYPE_ERROR = -1, /*error */ + H5PL_TYPE_FILTER = 0, /*filter */ + H5PL_TYPE_NONE = 1 /*this must be last! */ +} H5PL_type_t; + +/* Common dynamic plugin type flags */ +#define H5PL_FILTER_PLUGIN 0x0001 +#define H5PL_ALL_PLUGIN 0xFFFF + +#ifdef __cplusplus +extern "C" { +#endif + +/* plugin state */ +H5_DLL herr_t H5PLset_loading_state(unsigned int plugin_type); +H5_DLL herr_t H5PLget_loading_state(unsigned int* plugin_type/*out*/); + +#ifdef __cplusplus +} +#endif + +#endif /* _H5PLpublic_H */ + @@ -411,6 +411,10 @@ done: 13 July 2011 I added the OAPL_ID parameter for the object being referenced. It only supports dataset access property list currently. + + M. Scot Breitenfeld + 3 March 2015 + Added a check for undefined reference pointer. --------------------------------------------------------------------------*/ hid_t H5R_dereference(H5F_t *file, hid_t oapl_id, hid_t dxpl_id, H5R_type_t ref_type, const void *_ref, hbool_t app_ref) @@ -435,8 +439,10 @@ H5R_dereference(H5F_t *file, hid_t oapl_id, hid_t dxpl_id, H5R_type_t ref_type, switch(ref_type) { case H5R_OBJECT: oloc.addr = *(const hobj_ref_t *)_ref; /* Only object references currently supported */ - break; - + if(!H5F_addr_defined(oloc.addr) || oloc.addr == 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Undefined reference pointer") + break; + case H5R_DATASET_REGION: { H5HG_t hobjid; /* Heap object ID */ @@ -448,6 +454,9 @@ H5R_dereference(H5F_t *file, hid_t oapl_id, hid_t dxpl_id, H5R_type_t ref_type, H5F_addr_decode(oloc.file, &p, &(hobjid.addr)); UINT32DECODE(p, hobjid.idx); + if(!H5F_addr_defined(hobjid.addr) || hobjid.addr == 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Undefined reference pointer") + /* Get the dataset region from the heap (allocate inside routine) */ if(NULL == (buf = (uint8_t *)H5HG_read(oloc.file, dxpl_id, &hobjid, NULL, NULL))) HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, FAIL, "Unable to read dataset region information") diff --git a/src/H5Zfletcher32.c b/src/H5Zfletcher32.c index 7f67015..2ee69d1 100644 --- a/src/H5Zfletcher32.c +++ b/src/H5Zfletcher32.c @@ -137,9 +137,11 @@ H5Z_filter_fletcher32 (unsigned flags, size_t UNUSED cd_nelmts, const unsigned U /* Compute checksum (can't fail) */ fletcher = H5_checksum_fletcher32(src, nbytes); - if (NULL==(dst=outbuf=H5MM_malloc(nbytes+FLETCHER_LEN))) + if (NULL == (outbuf = H5MM_malloc(nbytes + FLETCHER_LEN))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "unable to allocate Fletcher32 checksum destination buffer") + dst = (unsigned char *) outbuf; + /* Copy raw data */ HDmemcpy((void*)dst, (void*)(*buf), nbytes); diff --git a/src/H5detect.c b/src/H5detect.c index b902af4..fc0570c 100644 --- a/src/H5detect.c +++ b/src/H5detect.c @@ -858,6 +858,7 @@ done:\n\ printf("/* signal_handlers tested: %d times */\n", signal_handler_tested_g); printf("/* sigbus_handler called: %d times */\n", sigbus_handler_called_g); printf("/* sigsegv_handler called: %d times */\n", sigsegv_handler_called_g); + printf("/* sigill_handler called: %d times */\n", sigill_handler_called_g); } /* end print_results() */ @@ -1750,13 +1751,17 @@ main(void) #if defined(H5SETJMP) && defined(H5_HAVE_SIGNAL) /* verify the SIGBUS and SIGSEGV handlers work properly */ - if (verify_signal_handlers (SIGBUS, sigbus_handler) != 0){ - fprintf(stderr, "Signal handler %s for signal %d failed\n", - "sigbus_handler", SIGBUS); + if (verify_signal_handlers(SIGBUS, sigbus_handler) != 0) { + fprintf(stderr, "Signal handler %s for signal %d failed\n", + "sigbus_handler", SIGBUS); } - if (verify_signal_handlers (SIGSEGV, sigsegv_handler) != 0){ - fprintf(stderr, "Signal handler %s for signal %d failed\n", - "sigsegv_handler", SIGSEGV); + if (verify_signal_handlers(SIGSEGV, sigsegv_handler) != 0) { + fprintf(stderr, "Signal handler %s for signal %d failed\n", + "sigsegv_handler", SIGSEGV); + } + if (verify_signal_handlers(SIGILL, sigill_handler) != 0) { + fprintf(stderr, "Signal handler %s for signal %d failed\n", + "sigill_handler", SIGILL); } #else align_status_g |= STA_NoHandlerVerify; diff --git a/src/H5public.h b/src/H5public.h index 673aa6f..0e866be 100644 --- a/src/H5public.h +++ b/src/H5public.h @@ -332,6 +332,8 @@ H5_DLL herr_t H5get_libversion(unsigned *majnum, unsigned *minnum, H5_DLL herr_t H5check_version(unsigned majnum, unsigned minnum, unsigned relnum); H5_DLL herr_t H5free_memory(void *mem); +H5_DLL void *H5allocate_memory(size_t size, hbool_t clear); +H5_DLL void *H5resize_memory(void *mem, size_t size); #ifdef __cplusplus } diff --git a/src/Makefile.am b/src/Makefile.am index 4b55144..2df095e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -119,7 +119,7 @@ include_HEADERS = hdf5.h H5api_adpt.h H5overflow.h H5pubconf.h H5public.h H5vers H5FDmulti.h H5FDsec2.h H5FDstdio.h \ H5Gpublic.h H5Ipublic.h H5Lpublic.h \ H5MMpublic.h H5Opublic.h H5Ppublic.h \ - H5PLextern.h \ + H5PLextern.h H5PLpublic.h \ H5Rpublic.h H5Spublic.h \ H5Tpublic.h H5Zpublic.h @@ -33,7 +33,8 @@ #include "H5Lpublic.h" /* Links */ #include "H5MMpublic.h" /* Memory management */ #include "H5Opublic.h" /* Object headers */ -#include "H5Ppublic.h" /* Property lists */ +#include "H5Ppublic.h" /* Property lists */ +#include "H5PLpublic.h" /* Plugins */ #include "H5Rpublic.h" /* References */ #include "H5Spublic.h" /* Dataspaces */ #include "H5Tpublic.h" /* Datatypes */ diff --git a/test/plugin.c b/test/plugin.c index 86bc952..3707411 100644 --- a/test/plugin.c +++ b/test/plugin.c @@ -456,14 +456,14 @@ error: } /*------------------------------------------------------------------------- - * Function: test_read_with_filters + * Function: test_read_with_filters * - * Purpose: Tests reading dataset created with dynamically loaded filters + * Purpose: Tests reading dataset created with dynamically loaded filters * - * Return: Success: 0 - * Failure: -1 + * Return: Success: 0 + * Failure: -1 * - * Programmer: Raymond Lu + * Programmer: Raymond Lu * 14 March 2013 * *------------------------------------------------------------------------- @@ -471,7 +471,7 @@ error: static herr_t test_read_with_filters(hid_t file) { - hid_t dset; /* Dataset ID */ + hid_t dset; /* Dataset ID */ /*---------------------------------------------------------- * STEP 1: Test deflation by itself. @@ -526,6 +526,76 @@ error: } /*------------------------------------------------------------------------- + * Function: test_noread_data + * + * Purpose: Tests not reading data + * + * Return: Success: 0 + * Failure: -1 + * + *------------------------------------------------------------------------- + */ +static herr_t +test_noread_data(hid_t dataset, int *origin_data) +{ + int check[DSET_DIM1][DSET_DIM2]; + const hsize_t size[2] = {DSET_DIM1, DSET_DIM2}; /* Dataspace dimensions */ + int *data_p = origin_data; + size_t i, j; /* Local index variables */ + + /* Read the dataset back */ + if(H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, check) >= 0) + TEST_ERROR; + + PASSED(); + return 0; + +error: + return -1; +} + +/*------------------------------------------------------------------------- + * Function: test_noread_with_filters + * + * Purpose: Tests reading dataset created with dynamically loaded filters disabled + * + * Return: Success: 0 + * Failure: -1 + * + *------------------------------------------------------------------------- + */ +static herr_t +test_noread_with_filters(hid_t file) +{ + hid_t dset; /* Dataset ID */ + int plugin_state; /* status of plugins */ + TESTING("Testing DYNLIB1 filter with plugins disabled"); + + /* disable filter plugin */ + if(H5PLget_loading_state(&plugin_state) < 0) TEST_ERROR + plugin_state = plugin_state & ~H5PL_FILTER_PLUGIN; + if(H5PLset_loading_state(plugin_state) < 0) TEST_ERROR + + if((dset = H5Dopen2(file,DSET_DYNLIB1_NAME,H5P_DEFAULT)) < 0) TEST_ERROR + + if(test_noread_data(dset, (int *)points_dynlib1) < 0) TEST_ERROR + + if(H5Dclose(dset) < 0) TEST_ERROR + + /* re-enable filter plugin */ + plugin_state = plugin_state | H5PL_FILTER_PLUGIN; + if(H5PLset_loading_state(plugin_state) < 0) TEST_ERROR + + return 0; + +error: + /* re-enable filter plugin */ + plugin_state = plugin_state | H5PL_FILTER_PLUGIN; + if(H5PLset_loading_state(plugin_state) < 0) TEST_ERROR + return -1; +} + +/*------------------------------------------------------------------------- * Function: test_filters_for_groups * * Purpose: Tests creating group with dynamically loaded filters @@ -713,6 +783,17 @@ main(void) /* Open the groups with filters */ nerrors += (test_groups_with_filters(file) < 0 ? 1 : 0); + /* Close the library so that all loaded plugin libraries are unloaded */ + h5_reset(); + fapl = h5_fileaccess(); + + /* Reopen the file for testing data reading */ + if((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) + TEST_ERROR + + /* Read the data with disabled filters */ + nerrors += (test_noread_with_filters(file) < 0 ? 1 : 0); + if(H5Fclose(file) < 0) TEST_ERROR diff --git a/test/testhdf5.h b/test/testhdf5.h index 907fce9..62dadde 100644 --- a/test/testhdf5.h +++ b/test/testhdf5.h @@ -68,6 +68,18 @@ } \ } +#define CHECK_PTR_NULL(ret,where) { \ + if (VERBOSE_HI) { \ + print_func(" Call to routine: %15s at line %4d in %s returned %p\n", \ + (where), (int)__LINE__, __FILE__, (ret)); \ + } \ + if (ret) { \ + TestErrPrintf ("*** UNEXPECTED RETURN from %s is not NULL line %4d in %s\n", \ + (where), (int)__LINE__, __FILE__); \ + H5Eprint2(H5E_DEFAULT, stdout); \ + } \ +} + /* Used to make certain a return value _is_ a value */ #define VERIFY(_x, _val, where) do { \ long __x = (long)_x, __val = (long)_val; \ diff --git a/test/tmisc.c b/test/tmisc.c index cffb3df..68a30eb 100644 --- a/test/tmisc.c +++ b/test/tmisc.c @@ -5304,6 +5304,73 @@ test_misc31(void) /**************************************************************** + * + * test_misc32(): Simple test of filter memory allocation + * functions. + * + ***************************************************************/ +static void +test_misc32(void) +{ + void *buffer; + void *resized; + size_t size; + + /* Output message about test being performed */ + MESSAGE(5, ("Edge case test of filter memory allocation functions\n")); + + /* Test that the filter memory allocation functions behave correctly + * at edge cases. + */ + + /* FREE */ + + /* Test freeing a NULL pointer. + * No real confirmation check here, but Valgrind will confirm no + * shenanigans. + */ + buffer = NULL; + H5free_memory(buffer); + + /* ALLOCATE */ + + /* Size zero returns NULL. + * Also checks that a size of zero and setting the buffer clear flag + * to TRUE can be used together. + * + * Note that we have asserts in the code, so only check when NDEBUG + * is defined. + */ +#ifdef NDEBUG + buffer = H5allocate_memory(0, FALSE); + CHECK_PTR_NULL(buffer, "H5allocate_memory"); /*BAD*/ + buffer = H5allocate_memory(0, TRUE); + CHECK_PTR_NULL(buffer, "H5allocate_memory"); /*BAD*/ +#endif /* NDEBUG */ + + /* RESIZE */ + + /* Size zero returns NULL. Valgrind will confirm buffer is freed. */ + size = 1024; + buffer = H5allocate_memory(size, TRUE); + resized = H5resize_memory(buffer, 0); + CHECK_PTR_NULL(resized, "H5resize_memory"); + + /* NULL input pointer returns new buffer */ + resized = H5resize_memory(NULL, 1024); + CHECK_PTR(resized, "H5resize_memory"); + H5free_memory(resized); + + /* NULL input pointer and size zero returns NULL */ +#ifdef NDEBUG + resized = H5resize_memory(NULL, 0); + CHECK_PTR_NULL(resized, "H5resize_memory"); /*BAD*/ +#endif /* NDEBUG */ + +} /* end test_misc32() */ + + +/**************************************************************** ** ** test_misc(): Main misc. test routine. ** @@ -5349,6 +5416,7 @@ test_misc(void) test_misc29(); /* Test that speculative metadata reads are handled correctly */ test_misc30(); /* Exercise local heap loading bug where free lists were getting dropped */ test_misc31(); /* Test Reentering library through deprecated routines after H5close() */ + test_misc32(); /* Test filter memory allocation functions */ } /* test_misc() */ diff --git a/test/trefer.c b/test/trefer.c index 9cb7f26..6d72aee 100644 --- a/test/trefer.c +++ b/test/trefer.c @@ -522,6 +522,12 @@ test_reference_region(void) H5O_type_t obj_type; /* Type of object */ int i, j; /* counting variables */ herr_t ret; /* Generic return value */ + haddr_t addr = HADDR_UNDEF; /* test for undefined reference */ + hid_t dset_NA; /* Dataset id for undefined reference */ + hid_t space_NA; /* Dataspace id for undefined reference */ + hsize_t dims_NA[1] = {1}; /* Dims array for undefined reference */ + hdset_reg_ref_t wdata_NA[1], /* Write buffer */ + rdata_NA[1]; /* Read buffer */ /* Output message about test being performed */ MESSAGE(5, ("Testing Dataset Region Reference Functions\n")); @@ -612,6 +618,31 @@ test_reference_region(void) ret = H5Dwrite(dset1, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); CHECK(ret, FAIL, "H5Dwrite"); + /* + * Store a dataset region reference which will not get written to disk + */ + + /* Create reference to an element in dset1 */ + ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)1, (const hsize_t *)coord1); + CHECK(ret, FAIL, "H5Sselect_elements"); + ret = H5Rcreate(&wdata_NA[0], fid1, "/Dataset1", H5R_DATASET_REGION, sid2); + CHECK(ret, FAIL, "H5Rcreate"); + + /* Create the dataspace of the region references */ + space_NA = H5Screate_simple(1, dims_NA, NULL); + CHECK(space_NA, FAIL, "H5Screate_simple"); + + /* Create the dataset and write the region references to it */ + dset_NA = H5Dcreate2(fid1, "DS_NA", H5T_STD_REF_DSETREG, space_NA, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT); + CHECK(dset_NA, FAIL, "H5Dcreate"); + + /* Close and release resources for undefined region reference tests */ + ret = H5Dclose(dset_NA); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Sclose(space_NA); + CHECK(ret, FAIL, "H5Sclose"); + /* Close disk dataspace */ ret = H5Sclose(sid1); CHECK(ret, FAIL, "H5Sclose"); @@ -632,6 +663,41 @@ test_reference_region(void) fid1 = H5Fopen(FILE2, H5F_ACC_RDWR, H5P_DEFAULT); CHECK(fid1, FAIL, "H5Fopen"); + /* + * Start the test of an undefined reference + */ + + /* Open the dataset of the undefined references */ + dset_NA = H5Dopen2(fid1, "DS_NA", H5P_DEFAULT); + CHECK(dset_NA, FAIL, "H5Dopen2"); + + /* Read the data */ + ret = H5Dread(dset_NA, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata_NA); + CHECK(ret, FAIL, "H5Dread"); + + /* + * Dereference an undefined reference (should fail) + */ + H5E_BEGIN_TRY { + dset2 = H5Rdereference2(dset_NA, H5P_DEFAULT, H5R_DATASET_REGION, &rdata_NA[0]); + } H5E_END_TRY; + VERIFY(dset2, FAIL, "H5Rdereference2"); + + /* Close and release resources. */ + ret = H5Dclose(dset_NA); + CHECK(ret, FAIL, "H5Dclose"); + + /* This close should fail since H5Rdereference2 never created + * the id of the referenced object. */ + H5E_BEGIN_TRY { + ret = H5Dclose(dset2); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Dclose"); + + /* + * End the test of an undefined reference + */ + /* Open the dataset */ dset1 = H5Dopen2(fid1, "/Dataset1", H5P_DEFAULT); CHECK(dset1, FAIL, "H5Dopen2"); @@ -640,6 +706,10 @@ test_reference_region(void) ret = H5Dread(dset1, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf); CHECK(ret, FAIL, "H5Dread"); + /* Try to read an unaddressed dataset */ + dset2 = H5Rdereference2(dset1, dapl_id, H5R_DATASET_REGION, &addr); + VERIFY(dset2, FAIL, "H5Rdereference2 haddr_undef"); + /* Try to open objects */ dset2 = H5Rdereference2(dset1, dapl_id, H5R_DATASET_REGION, &rbuf[0]); CHECK(dset2, FAIL, "H5Rdereference2"); @@ -1070,6 +1140,7 @@ test_reference_obj_deleted(void) hid_t sid1; /* Dataspace ID */ hobj_ref_t oref; /* Object Reference to test */ H5O_type_t obj_type; /* Object type */ + haddr_t addr = HADDR_UNDEF; /* test for undefined reference */ herr_t ret; /* Generic return value */ /* Create file */ @@ -1127,6 +1198,10 @@ test_reference_obj_deleted(void) dataset = H5Dopen2(fid1, "/Dataset2", H5P_DEFAULT); CHECK(ret, FAIL, "H5Dopen2"); + /* Open undefined reference */ + dset2 = H5Rdereference2(dataset, H5P_DEFAULT, H5R_OBJECT, &addr); + VERIFY(dset2, FAIL, "H5Rdereference2"); + /* Read selection from disk */ HDmemset(&oref, 0, sizeof(hobj_ref_t)); ret = H5Dread(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, &oref); diff --git a/tools/h5dump/errfiles/tarray1_big.err b/tools/h5dump/errfiles/tarray1_big.err index 457afdd..7a0fd7b 100644 --- a/tools/h5dump/errfiles/tarray1_big.err +++ b/tools/h5dump/errfiles/tarray1_big.err @@ -2,59 +2,23 @@ HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): #000: (file name) line (number) in H5Rdereference2(): unable to dereference object major: References minor: Unable to initialize object - #001: (file name) line (number) in H5R_dereference(): Unable to read dataset region information - major: References - minor: Read failed - #002: (file name) line (number) in H5HG_read(): unable to protect global heap - major: Heap - minor: Unable to protect metadata - #003: (file name) line (number) in H5HG_protect(): unable to protect global heap - major: Heap - minor: Unable to protect metadata - #004: (file name) line (number) in H5AC_protect(): H5C_protect() failed. - major: Object cache - minor: Unable to protect metadata - #005: (file name) line (number) in H5C_protect(): incorrect cache entry type - major: Object cache - minor: Inappropriate type + #001: (file name) line (number) in H5R_dereference(): Undefined reference pointer + major: Invalid arguments to routine + minor: Bad value HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): #000: (file name) line (number) in H5Rdereference2(): unable to dereference object major: References minor: Unable to initialize object - #001: (file name) line (number) in H5R_dereference(): Unable to read dataset region information - major: References - minor: Read failed - #002: (file name) line (number) in H5HG_read(): unable to protect global heap - major: Heap - minor: Unable to protect metadata - #003: (file name) line (number) in H5HG_protect(): unable to protect global heap - major: Heap - minor: Unable to protect metadata - #004: (file name) line (number) in H5AC_protect(): H5C_protect() failed. - major: Object cache - minor: Unable to protect metadata - #005: (file name) line (number) in H5C_protect(): incorrect cache entry type - major: Object cache - minor: Inappropriate type + #001: (file name) line (number) in H5R_dereference(): Undefined reference pointer + major: Invalid arguments to routine + minor: Bad value HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): #000: (file name) line (number) in H5Rdereference2(): unable to dereference object major: References minor: Unable to initialize object - #001: (file name) line (number) in H5R_dereference(): Unable to read dataset region information - major: References - minor: Read failed - #002: (file name) line (number) in H5HG_read(): unable to protect global heap - major: Heap - minor: Unable to protect metadata - #003: (file name) line (number) in H5HG_protect(): unable to protect global heap - major: Heap - minor: Unable to protect metadata - #004: (file name) line (number) in H5AC_protect(): H5C_protect() failed. - major: Object cache - minor: Unable to protect metadata - #005: (file name) line (number) in H5C_protect(): incorrect cache entry type - major: Object cache - minor: Inappropriate type + #001: (file name) line (number) in H5R_dereference(): Undefined reference pointer + major: Invalid arguments to routine + minor: Bad value H5tools-DIAG: Error detected in HDF5:tools (version (number)) thread (IDs): #000: (file name) line (number) in h5tools_dump_simple_data(): H5Rdereference failed major: Failure in tools library diff --git a/tools/h5dump/errfiles/tattrregR.err b/tools/h5dump/errfiles/tattrregR.err index 7ab9afd..9449a6d 100644 --- a/tools/h5dump/errfiles/tattrregR.err +++ b/tools/h5dump/errfiles/tattrregR.err @@ -2,40 +2,16 @@ HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): #000: (file name) line (number) in H5Rdereference2(): unable to dereference object major: References minor: Unable to initialize object - #001: (file name) line (number) in H5R_dereference(): Unable to read dataset region information - major: References - minor: Read failed - #002: (file name) line (number) in H5HG_read(): unable to protect global heap - major: Heap - minor: Unable to protect metadata - #003: (file name) line (number) in H5HG_protect(): unable to protect global heap - major: Heap - minor: Unable to protect metadata - #004: (file name) line (number) in H5AC_protect(): H5C_protect() failed. - major: Object cache - minor: Unable to protect metadata - #005: (file name) line (number) in H5C_protect(): incorrect cache entry type - major: Object cache - minor: Inappropriate type + #001: (file name) line (number) in H5R_dereference(): Undefined reference pointer + major: Invalid arguments to routine + minor: Bad value HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): #000: (file name) line (number) in H5Rdereference2(): unable to dereference object major: References minor: Unable to initialize object - #001: (file name) line (number) in H5R_dereference(): Unable to read dataset region information - major: References - minor: Read failed - #002: (file name) line (number) in H5HG_read(): unable to protect global heap - major: Heap - minor: Unable to protect metadata - #003: (file name) line (number) in H5HG_protect(): unable to protect global heap - major: Heap - minor: Unable to protect metadata - #004: (file name) line (number) in H5AC_protect(): H5C_protect() failed. - major: Object cache - minor: Unable to protect metadata - #005: (file name) line (number) in H5C_protect(): incorrect cache entry type - major: Object cache - minor: Inappropriate type + #001: (file name) line (number) in H5R_dereference(): Undefined reference pointer + major: Invalid arguments to routine + minor: Bad value H5tools-DIAG: Error detected in HDF5:tools (version (number)) thread (IDs): #000: (file name) line (number) in h5tools_dump_simple_data(): H5Rdereference failed major: Failure in tools library diff --git a/tools/h5dump/errfiles/tdataregR.err b/tools/h5dump/errfiles/tdataregR.err index 7ab9afd..9449a6d 100644 --- a/tools/h5dump/errfiles/tdataregR.err +++ b/tools/h5dump/errfiles/tdataregR.err @@ -2,40 +2,16 @@ HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): #000: (file name) line (number) in H5Rdereference2(): unable to dereference object major: References minor: Unable to initialize object - #001: (file name) line (number) in H5R_dereference(): Unable to read dataset region information - major: References - minor: Read failed - #002: (file name) line (number) in H5HG_read(): unable to protect global heap - major: Heap - minor: Unable to protect metadata - #003: (file name) line (number) in H5HG_protect(): unable to protect global heap - major: Heap - minor: Unable to protect metadata - #004: (file name) line (number) in H5AC_protect(): H5C_protect() failed. - major: Object cache - minor: Unable to protect metadata - #005: (file name) line (number) in H5C_protect(): incorrect cache entry type - major: Object cache - minor: Inappropriate type + #001: (file name) line (number) in H5R_dereference(): Undefined reference pointer + major: Invalid arguments to routine + minor: Bad value HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): #000: (file name) line (number) in H5Rdereference2(): unable to dereference object major: References minor: Unable to initialize object - #001: (file name) line (number) in H5R_dereference(): Unable to read dataset region information - major: References - minor: Read failed - #002: (file name) line (number) in H5HG_read(): unable to protect global heap - major: Heap - minor: Unable to protect metadata - #003: (file name) line (number) in H5HG_protect(): unable to protect global heap - major: Heap - minor: Unable to protect metadata - #004: (file name) line (number) in H5AC_protect(): H5C_protect() failed. - major: Object cache - minor: Unable to protect metadata - #005: (file name) line (number) in H5C_protect(): incorrect cache entry type - major: Object cache - minor: Inappropriate type + #001: (file name) line (number) in H5R_dereference(): Undefined reference pointer + major: Invalid arguments to routine + minor: Bad value H5tools-DIAG: Error detected in HDF5:tools (version (number)) thread (IDs): #000: (file name) line (number) in h5tools_dump_simple_data(): H5Rdereference failed major: Failure in tools library diff --git a/tools/lib/h5trav.c b/tools/lib/h5trav.c index d0a4a76..90e6d3d 100644 --- a/tools/lib/h5trav.c +++ b/tools/lib/h5trav.c @@ -50,6 +50,10 @@ typedef struct { hid_t fid; /* File ID being traversed */ } trav_print_udata_t; +typedef struct trav_path_op_data_t { + const char *path; +} trav_path_op_data_t; + /* format for hsize_t */ #ifdef H5TRAV_PRINT_SPACE #define HSIZE_T_FORMAT "%" H5_PRINTF_LL_WIDTH "u" @@ -899,11 +903,11 @@ trav_attr(hid_t #ifndef H5TRAV_PRINT_SPACE UNUSED #endif /* H5TRAV_PRINT_SPACE */ -obj, const char *attr_name, const H5A_info_t UNUSED *ainfo, void *op_data) +obj, const char *attr_name, const H5A_info_t UNUSED *ainfo, void *_op_data) { - char *buf; + trav_path_op_data_t *op_data = (trav_path_op_data_t *)_op_data; + const char *buf = op_data->path; - buf = (char*)op_data; if((strlen(buf)==1) && (*buf=='/')) printf(" %-10s %s%s", "attribute", buf, attr_name); else @@ -1009,10 +1013,14 @@ trav_print_visit_obj(const char *path, const H5O_info_t *oinfo, /* Check if we've already seen this object */ if(NULL == already_visited) { + trav_path_op_data_t op_data; + + op_data.path = path; /* Finish printing line about object */ printf("\n"); if(trav_verbosity > 0) - H5Aiterate_by_name(print_udata->fid, path, trav_index_by, trav_index_order, NULL, trav_attr, (void *)path, H5P_DEFAULT); + H5Aiterate_by_name(print_udata->fid, path, trav_index_by, trav_index_order, + NULL, trav_attr, &op_data, H5P_DEFAULT); } else /* Print the link's original name */ |