Index: lib/Fuzzer/test/AdapterUnittest.cpp =================================================================== --- /dev/null +++ lib/Fuzzer/test/AdapterUnittest.cpp @@ -0,0 +1,167 @@ +#include "gtest/gtest.h" +#include "gtest/gtest-spi.h" + +namespace fuzzer { + +template +size_t UnpackPrimitive(const uint8_t *Data, size_t Size, T* Value) { + if (Size < sizeof(T)) + return Size; + *Value = *reinterpret_cast(Data); + return Size - sizeof(T); +} + +template +size_t UnpackSingle(const uint8_t *Data, size_t Size, T* Value); + +template<> +size_t UnpackSingle(const uint8_t *Data, size_t Size, bool* Value) { + return UnpackPrimitive(Data, Size, Value); +} + +template<> +size_t UnpackSingle(const uint8_t *Data, size_t Size, int* Value) { + return UnpackPrimitive(Data, Size, Value); +} + +template +typename std::enable_if::value, bool>::type +UnpackImpl(const uint8_t *Data, size_t Size, TupleT* Tuple) { + return true; +} + +template +typename std::enable_if::value, bool>::type +UnpackImpl(const uint8_t *Data, size_t Size, TupleT* Tuple) { + size_t NewSize = UnpackSingle(Data, Size, &std::get(*Tuple)); + if (NewSize == Size) { + return false; + } + + return UnpackImpl(Data + (Size - NewSize), NewSize, Tuple); +} + +template +bool Unpack(const uint8_t *Data, size_t Size, std::tuple* Tuple) { + return UnpackImpl<0, std::tuple>(Data, Size, Tuple); +} + +template +bool Unpack(std::tuple* Tuple, std::initializer_list data) { + std::vector v(data); + return Unpack(v.data(), v.size(), Tuple); +} + +TEST(Unpack, Bool) { + std::tuple T; + EXPECT_TRUE(Unpack(&T, {1})); + EXPECT_TRUE(std::get<0>(T)); + + EXPECT_TRUE(Unpack(&T, {0})); + EXPECT_FALSE(std::get<0>(T)); + + EXPECT_FALSE(Unpack(&T, {})); +} + +TEST(Unpack, BoolBool) { + std::tuple T; + EXPECT_TRUE(Unpack(&T, {1, 0})); + EXPECT_TRUE(std::get<0>(T)); + EXPECT_FALSE(std::get<1>(T)); + + EXPECT_TRUE(Unpack(&T, {0, 1})); + EXPECT_FALSE(std::get<0>(T)); + EXPECT_TRUE(std::get<1>(T)); + + EXPECT_FALSE(Unpack(&T, {})); + EXPECT_FALSE(Unpack(&T, {10})); +} + +TEST(Unpack, BoolInt) { + std::tuple T; + EXPECT_TRUE(Unpack(&T, {1, 16, 2, 0, 0})); + EXPECT_TRUE(std::get<0>(T)); + EXPECT_EQ(528, std::get<1>(T)); + + EXPECT_FALSE(Unpack(&T, {1, 2})); +} + +template +struct function_traits {}; + +template +struct function_traits { + enum { Arity = sizeof...(Args) }; + typedef std::tuple ArgsTupleT; +}; + +template +bool UnpackArguments(Fn F, const uint8_t *Data, size_t Size, typename function_traits::ArgsTupleT* Tuple) { + return Unpack(Data, Size, Tuple); +} + +template +bool UnpackArguments(Fn F, typename function_traits::ArgsTupleT* Tuple, + std::initializer_list Data) { + std::vector V(Data); + return UnpackArguments(F, V.data(), V.size(), Tuple); +} + +void fnBool(bool b) { +} + +TEST(UnpackArguments, Bool) { + std::tuple T; + EXPECT_TRUE(UnpackArguments(fnBool, &T, {1})); + EXPECT_TRUE(std::get<0>(T)); +} + +template +struct seq { }; + +template +struct gens : gens { }; + +template +struct gens<0, S...> { + typedef seq type; +}; + + +template +void ApplyImpl(Fn F, const typename function_traits::ArgsTupleT& Params, seq) { + F(std::get(Params)...); +} + +template +void Apply(Fn F, const typename function_traits::ArgsTupleT& Params) { + ApplyImpl(F, Params, typename gens::Arity>::type()); +} + +template +bool UnpackAndApply(Fn F, const uint8_t *Data, size_t Size) { + typename function_traits::ArgsTupleT Tuple; + if (!UnpackArguments(F, Data, Size, &Tuple)) + return false; + + Apply(F, Tuple); + return true; +} + +template +bool UnpackAndApply(Fn F, std::initializer_list Data) { + std::vector V(Data); + return UnpackAndApply(F, V.data(), V.size()); +} + +void fnInt(int i) { + EXPECT_EQ(42, i); +} + +TEST(Apply, Int) { + EXPECT_FALSE(UnpackAndApply(fnInt, {})); + EXPECT_TRUE(UnpackAndApply(fnInt, {42, 0, 0, 0})); + EXPECT_NONFATAL_FAILURE(UnpackAndApply(fnInt, {10, 0, 0, 0}), "Expected: 42"); +} + +} // namespace fuzzer Index: lib/Fuzzer/test/CMakeLists.txt =================================================================== --- lib/Fuzzer/test/CMakeLists.txt +++ lib/Fuzzer/test/CMakeLists.txt @@ -90,6 +90,7 @@ add_executable(LLVMFuzzer-Unittest FuzzerUnittest.cpp + AdapterUnittest.cpp $ )