diff --git a/CMakeLists.txt b/CMakeLists.txt index 97aad9d6131..2d75a07aa36 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,10 @@ -cmake_minimum_required(VERSION 3.15.0) +cmake_minimum_required(VERSION 3.22.0) # For MSVC RUNTIME LIBRARY, need CMP0091=NEW and cmake 3.15+ cmake_policy(SET CMP0091 NEW) +include(CMakeDependentOption) + # Version info set(QUANTLIB_VERSION_MAJOR 1) set(QUANTLIB_VERSION_MINOR 32) @@ -42,6 +44,7 @@ set(QL_INSTALL_CMAKEDIR "lib/cmake/${PACKAGE_NAME}" CACHE STRING option(QL_BUILD_BENCHMARK "Build benchmark" ON) option(QL_BUILD_EXAMPLES "Build examples" ON) option(QL_BUILD_TEST_SUITE "Build test suite" ON) +cmake_dependent_option(QL_BUILD_FUZZ_TEST_SUITE "Build fuzz test suite" ON "'${CMAKE_CXX_COMPILER_ID}' MATCHES 'Clang'" OFF) option(QL_ENABLE_OPENMP "Detect and use OpenMP" OFF) option(QL_ENABLE_PARALLEL_UNIT_TEST_RUNNER "Enable the parallel unit test runner" OFF) option(QL_ENABLE_SESSIONS "Singletons return different instances for different sessions" OFF) @@ -269,6 +272,10 @@ if (QL_BUILD_TEST_SUITE OR QL_BUILD_BENCHMARK) add_subdirectory(test-suite) endif() +if (QL_BUILD_FUZZ_TEST_SUITE) + add_subdirectory(fuzz-test-suite) +endif() + # CPack support (make package, make package_source) set(CPACK_PACKAGE_VERSION_MAJOR ${QUANTLIB_VERSION_MAJOR}) set(CPACK_PACKAGE_VERSION_MINOR ${QUANTLIB_VERSION_MINOR}) diff --git a/fuzz-test-suite/CMakeLists.txt b/fuzz-test-suite/CMakeLists.txt new file mode 100644 index 00000000000..aaddcbfefd4 --- /dev/null +++ b/fuzz-test-suite/CMakeLists.txt @@ -0,0 +1,21 @@ +# Determine the flags for fuzzing. Use OSS-Fuzz's configuration if available, otherwise fall back to defaults. +if(DEFINED ENV{LIB_FUZZING_ENGINE}) + set(FUZZING_ENGINE $ENV{LIB_FUZZING_ENGINE}) + set(FUZZING_COMPILE_FLAGS "") + set(FUZZING_LINK_FLAGS "${FUZZING_ENGINE}") +else() + set(FUZZING_COMPILE_FLAGS "-fsanitize=fuzzer") + set(FUZZING_LINK_FLAGS "-fsanitize=fuzzer") +endif() + +# Define the fuzz target +add_executable(DateParserFuzzer dateparserfuzzer.cpp) + +# Apply the determined flags +set_target_properties(DateParserFuzzer PROPERTIES + COMPILE_FLAGS "${FUZZING_COMPILE_FLAGS}" + LINK_FLAGS "${FUZZING_LINK_FLAGS}" +) + +# Link QuantLib and any other necessary libraries +target_link_libraries(DateParserFuzzer ql_library ${QL_THREAD_LIBRARIES}) diff --git a/fuzz-test-suite/dateparserfuzzer.cpp b/fuzz-test-suite/dateparserfuzzer.cpp new file mode 100644 index 00000000000..7c6f6423fdd --- /dev/null +++ b/fuzz-test-suite/dateparserfuzzer.cpp @@ -0,0 +1,24 @@ +#include +#include +#include +#include +#include +#include +#include + +#ifndef __clang__ +#pragma message("Fuzzer headers are available from clang, other compilers have not been tested.") +#endif +#include + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + FuzzedDataProvider fdp(data, size); + constexpr int kMaxString = 100; + try { + (void)QuantLib::DateParser::parseFormatted(fdp.ConsumeRandomLengthString(kMaxString), "%Y-%m-%d"); + (void)QuantLib::DateParser::parseISO(fdp.ConsumeRandomLengthString(kMaxString)); + } catch (const std::exception& e) { + // Handle or ignore exceptions + } + return 0; +}