From bc524d70253a4ab2fe40c3ca3e5666e267c0a4d1 Mon Sep 17 00:00:00 2001 From: Lexi Winter Date: Sun, 29 Jun 2025 19:25:29 +0100 Subject: import catch2 3.8.1 --- fuzzing/CMakeLists.txt | 20 ++++++++++++++++ fuzzing/NullOStream.cpp | 18 ++++++++++++++ fuzzing/NullOStream.h | 28 ++++++++++++++++++++++ fuzzing/build_fuzzers.sh | 33 +++++++++++++++++++++++++ fuzzing/fuzz_TestSpecParser.cpp | 22 +++++++++++++++++ fuzzing/fuzz_XmlWriter.cpp | 22 +++++++++++++++++ fuzzing/fuzz_textflow.cpp | 53 +++++++++++++++++++++++++++++++++++++++++ 7 files changed, 196 insertions(+) create mode 100644 fuzzing/CMakeLists.txt create mode 100644 fuzzing/NullOStream.cpp create mode 100644 fuzzing/NullOStream.h create mode 100755 fuzzing/build_fuzzers.sh create mode 100644 fuzzing/fuzz_TestSpecParser.cpp create mode 100644 fuzzing/fuzz_XmlWriter.cpp create mode 100644 fuzzing/fuzz_textflow.cpp (limited to 'fuzzing') diff --git a/fuzzing/CMakeLists.txt b/fuzzing/CMakeLists.txt new file mode 100644 index 0000000..daba61d --- /dev/null +++ b/fuzzing/CMakeLists.txt @@ -0,0 +1,20 @@ +# License: Boost 1.0 +# By Paul Dreik 2020 + +# add a library that brings in the main() function from libfuzzer +# and has all the dependencies, so the individual fuzzers can be +# added one line each. +add_library(fuzzhelper NullOStream.h NullOStream.cpp) +target_link_libraries(fuzzhelper PUBLIC Catch2::Catch2) + +# use C++17 so we can get string_view +target_compile_features(fuzzhelper PUBLIC cxx_std_17) + +# This should be possible to set from the outside to be oss-fuzz compatible, +# fix later. For now, target libFuzzer only. +target_link_options(fuzzhelper PUBLIC "-fsanitize=fuzzer") + +foreach(fuzzer TestSpecParser XmlWriter textflow) +add_executable(fuzz_${fuzzer} fuzz_${fuzzer}.cpp) +target_link_libraries(fuzz_${fuzzer} PRIVATE fuzzhelper) +endforeach() diff --git a/fuzzing/NullOStream.cpp b/fuzzing/NullOStream.cpp new file mode 100644 index 0000000..e3a181e --- /dev/null +++ b/fuzzing/NullOStream.cpp @@ -0,0 +1,18 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 + +#include "NullOStream.h" + +void NullOStream::avoidOutOfLineVirtualCompilerWarning() +{ +} + +int NullStreambuf::overflow(int c){ + setp(dummyBuffer, dummyBuffer + sizeof(dummyBuffer)); + return (c == traits_type::eof()) ? '\0' : c; +} diff --git a/fuzzing/NullOStream.h b/fuzzing/NullOStream.h new file mode 100644 index 0000000..abbec09 --- /dev/null +++ b/fuzzing/NullOStream.h @@ -0,0 +1,28 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 + +#pragma once + +#include +#include + +// from https://stackoverflow.com/a/8244052 +class NullStreambuf : public std::streambuf { + char dummyBuffer[64]; + +protected: + virtual int overflow(int c) override final; +}; + +class NullOStream final : private NullStreambuf, public std::ostream { +public: + NullOStream() : std::ostream(this) {} + NullStreambuf *rdbuf() { return this; } + virtual void avoidOutOfLineVirtualCompilerWarning(); +}; + diff --git a/fuzzing/build_fuzzers.sh b/fuzzing/build_fuzzers.sh new file mode 100755 index 0000000..9788c68 --- /dev/null +++ b/fuzzing/build_fuzzers.sh @@ -0,0 +1,33 @@ +#!/bin/sh +# +# Builds the fuzzers +# +# By Paul Dreik 20200923 +set -exu + +CATCHROOT=$(readlink -f $(dirname $0)/..) + + +BUILDDIR=$CATCHROOT/build-fuzzers +mkdir -p $BUILDDIR +cd $BUILDDIR + +if which /usr/lib/ccache/clang++ >/dev/null 2>&1 ; then + CXX=/usr/lib/ccache/clang++ +else + CXX=clang++ +fi + +cmake $CATCHROOT \ + -DCMAKE_CXX_COMPILER=$CXX \ + -DCMAKE_CXX_FLAGS="-fsanitize=fuzzer-no-link,address,undefined -O3 -g" \ + -DCATCH_DEVELOPMENT_BUILD=On \ + -DCATCH_BUILD_EXAMPLES=Off \ + -DCATCH_BUILD_EXTRA_TESTS=Off \ + -DCATCH_BUILD_TESTING=Off \ + -DBUILD_TESTING=Off \ + -DCATCH_ENABLE_WERROR=Off \ + -DCATCH_BUILD_FUZZERS=On + +cmake --build . -j $(nproc) + diff --git a/fuzzing/fuzz_TestSpecParser.cpp b/fuzzing/fuzz_TestSpecParser.cpp new file mode 100644 index 0000000..3aba8c8 --- /dev/null +++ b/fuzzing/fuzz_TestSpecParser.cpp @@ -0,0 +1,22 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 +//By Paul Dreik 2020 + +#include +#include + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + + Catch::TagAliasRegistry tar; + Catch::TestSpecParser tsp(tar); + + std::string buf(Data,Data+Size); + tsp.parse(buf); + + return 0; +} diff --git a/fuzzing/fuzz_XmlWriter.cpp b/fuzzing/fuzz_XmlWriter.cpp new file mode 100644 index 0000000..70c4ed8 --- /dev/null +++ b/fuzzing/fuzz_XmlWriter.cpp @@ -0,0 +1,22 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 +//By Paul Dreik 2020 + +#include + +#include "NullOStream.h" + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + + std::string buf(Data,Data+Size); + NullOStream nul; + Catch::XmlEncode encode(buf); + encode.encodeTo(nul); + return 0; +} + diff --git a/fuzzing/fuzz_textflow.cpp b/fuzzing/fuzz_textflow.cpp new file mode 100644 index 0000000..7000f42 --- /dev/null +++ b/fuzzing/fuzz_textflow.cpp @@ -0,0 +1,53 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 +//By Paul Dreik 2020 + +#include + +#include "NullOStream.h" + +#include +#include + + +template +void split(const char *Data, size_t Size, Callback callback) { + + using namespace std::literals; + constexpr auto sep="\n~~~\n"sv; + + std::string_view remainder(Data,Size); + for (;;) { + auto pos=remainder.find(sep); + if(pos==std::string_view::npos) { + //not found. use the remainder and exit + callback(remainder); + return; + } else { + //found. invoke callback on the first part, then proceed with the rest. + callback(remainder.substr(0,pos)); + remainder=remainder.substr(pos+sep.size()); + } + } +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + + Catch::TextFlow::Columns columns; + + // break the input on separator + split((const char*)Data,Size,[&](std::string_view word) { + columns+=Catch::TextFlow::Column(std::string(word)); + }); + + NullOStream nul; + nul << columns; + + return 0; +} + -- cgit v1.2.3