diff --git a/CMakeLists.txt b/CMakeLists.txt index c5249bc54a..7a3102ec01 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,10 +93,6 @@ if( EXIV2_BUILD_UNIT_TESTS ) endif() if( EXIV2_BUILD_FUZZ_TESTS ) - if ((NOT COMPILER_IS_CLANG) OR (NOT EXIV2_TEAM_USE_SANITIZERS)) - message(FATAL_ERROR "You need to build with Clang and sanitizers for the fuzzers to work. " - "Use Clang and -DEXIV2_TEAM_USE_SANITIZERS=ON") - endif() add_subdirectory ( fuzz ) endif() diff --git a/cmake/compilerFlags.cmake b/cmake/compilerFlags.cmake index f70bb92494..e45a5e3f9e 100644 --- a/cmake/compilerFlags.cmake +++ b/cmake/compilerFlags.cmake @@ -70,6 +70,17 @@ if ( MINGW OR UNIX OR MSYS ) # MINGW, Linux, APPLE, CYGWIN # This seems to be causing issues in the Fedora_MinGW GitLab job #add_compile_options(-fasynchronous-unwind-tables) + if( EXIV2_BUILD_FUZZ_TESTS ) + if (NOT COMPILER_IS_CLANG) + message(FATAL_ERROR "You need to build with Clang for the fuzzers to work. " + "Use Clang") + endif() + set(FUZZER_FLAGS "-fsanitize=fuzzer-no-link") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FUZZER_FLAGS}") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FUZZER_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FUZZER_FLAGS}") + set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${FUZZER_FLAGS}") + endif() if ( EXIV2_TEAM_USE_SANITIZERS ) # ASAN is available in gcc from 4.8 and UBSAN from 4.9 @@ -84,9 +95,7 @@ if ( MINGW OR UNIX OR MSYS ) # MINGW, Linux, APPLE, CYGWIN set(SANITIZER_FLAGS "-fno-omit-frame-pointer -fsanitize=address") endif() elseif( COMPILER_IS_CLANG ) - if ( EXIV2_BUILD_FUZZ_TESTS ) - set(SANITIZER_FLAGS "-fsanitize=fuzzer-no-link,address,undefined") - elseif ( CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.9 ) + if ( CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.9 ) set(SANITIZER_FLAGS "-fno-omit-frame-pointer -fsanitize=address,undefined -fno-sanitize-recover=all") elseif ( CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 3.4 ) set(SANITIZER_FLAGS "-fno-omit-frame-pointer -fsanitize=address,undefined") diff --git a/src/basicio.cpp b/src/basicio.cpp index 553dbde610..9e9cc8f228 100644 --- a/src/basicio.cpp +++ b/src/basicio.cpp @@ -1357,7 +1357,9 @@ namespace Exiv2 { { long avail = std::max(p_->size_ - p_->idx_, 0L); long allow = std::min(rcount, avail); - std::memcpy(buf, &p_->data_[p_->idx_], allow); + if (allow > 0) { + std::memcpy(buf, &p_->data_[p_->idx_], allow); + } p_->idx_ += allow; if (rcount > avail) p_->eof_ = true; return allow; diff --git a/src/jpgimage.cpp b/src/jpgimage.cpp index 2ab22e5911..6462f221bf 100644 --- a/src/jpgimage.cpp +++ b/src/jpgimage.cpp @@ -948,8 +948,10 @@ namespace Exiv2 { memcmp(buf.pData_ + 2, exifId_, 6) == 0) { skipApp1Exif = count; ++search; - rawExif.alloc(size - 8); - memcpy(rawExif.pData_, buf.pData_ + 8, size - 8); + if (size > 8) { + rawExif.alloc(size - 8); + memcpy(rawExif.pData_, buf.pData_ + 8, size - 8); + } } else if (skipApp1Xmp == notfound && marker == app1_ && size >= 31 && // prevent out-of-bounds read in memcmp on next line diff --git a/src/pngimage.cpp b/src/pngimage.cpp index a86c154aa2..3097742660 100644 --- a/src/pngimage.cpp +++ b/src/pngimage.cpp @@ -62,7 +62,11 @@ namespace inline bool compare(const char* str, const Exiv2::DataBuf& buf, size_t length) { assert(strlen(str) <= length); - return memcmp(str, buf.pData_, std::min(static_cast(length), buf.size_)) == 0; + const long minlen = std::min(static_cast(length), buf.size_); + if (minlen == 0) { + return true; + } + return memcmp(str, buf.pData_, minlen) == 0; } } // namespace diff --git a/src/tiffvisitor_int.cpp b/src/tiffvisitor_int.cpp index 69a90f1199..854f336984 100644 --- a/src/tiffvisitor_int.cpp +++ b/src/tiffvisitor_int.cpp @@ -744,8 +744,10 @@ namespace Exiv2 { << " to offset area.\n"; #endif memset(buf + 8, 0x0, 4); - memcpy(buf + 8, pTiffEntry->pData(), pTiffEntry->size()); - memset(const_cast(pTiffEntry->pData()), 0x0, pTiffEntry->size()); + if (pTiffEntry->size() > 0) { + memcpy(buf + 8, pTiffEntry->pData(), pTiffEntry->size()); + memset(const_cast(pTiffEntry->pData()), 0x0, pTiffEntry->size()); + } } return 12; }