1 // Copyright 2020 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 15 // Simply forwards to <fuzzer/FuzzedDataProvider.h> when available from clang, 16 // or provides a simple stub implementation. 17 #pragma once 18 19 #if defined(__clang__) 20 #include <fuzzer/FuzzedDataProvider.h> 21 #else // !defined(__clang__) 22 23 // If a fuzzer wants to use FuzzedDataProvider to build a fuzz target unit 24 // test without clang, it can use this trivial class with the same signature. 25 // The behavior will NOT be the same as a fuzzer unit test built by clang for 26 // non-trivial inputs. This means non-clang fuzzer unit tests will not be 27 // effective regression tests if given a seed corpus. These non-clang tests are 28 // still useful, however, as they will guarantee the fuzzer code can compile and 29 // link. 30 // 31 // The methods of this class are intentionally undocumented. To see the 32 // documentation for each, consult the real header file, e.g. in 33 // .cipd/pigweed/lib/clang/11.0.0/include/fuzzer/FuzzedDataProvider.h 34 #include <cstddef> 35 #include <cstdint> 36 #include <string> 37 #include <vector> 38 39 #include "pw_log/log.h" 40 41 class FuzzedDataProvider { 42 public: FuzzedDataProvider(const uint8_t *,size_t)43 FuzzedDataProvider(const uint8_t* /* data */, size_t /* size */) { 44 PW_LOG_INFO("Fuzzing is disabled for the current compiler."); 45 PW_LOG_INFO("Using trivial stub implementation for FuzzedDataProvider."); 46 } 47 48 ~FuzzedDataProvider() = default; 49 50 template <typename T> ConsumeBytes(size_t)51 std::vector<T> ConsumeBytes(size_t /* num_bytes */) { 52 return std::vector<T>{}; 53 } 54 55 template <typename T> 56 std::vector<T> ConsumeBytesWithTerminator(size_t /* num_bytes */, 57 T terminator = 0) { 58 return std::vector<T>{terminator}; 59 } 60 61 template <typename T> ConsumeRemainingBytes()62 std::vector<T> ConsumeRemainingBytes() { 63 return std::vector<T>{}; 64 } 65 ConsumeBytesAsString(size_t)66 std::string ConsumeBytesAsString(size_t /* num_bytes */) { 67 return std::string{}; 68 } 69 ConsumeRandomLengthString(size_t)70 std::string ConsumeRandomLengthString(size_t /* max_length */) { 71 return std::string{}; 72 } 73 ConsumeRandomLengthString()74 std::string ConsumeRandomLengthString() { return std::string{}; } 75 ConsumeRemainingBytesAsString()76 std::string ConsumeRemainingBytesAsString() { return std::string{}; } 77 78 template <typename T> ConsumeIntegral()79 T ConsumeIntegral() { 80 return T(0); 81 } 82 83 template <typename T> ConsumeIntegralInRange(T min,T)84 T ConsumeIntegralInRange(T min, T /* max */) { 85 return T(min); 86 } 87 88 template <typename T> ConsumeFloatingPoint()89 T ConsumeFloatingPoint() { 90 return T(0.0); 91 } 92 93 template <typename T> ConsumeFloatingPointInRange(T min,T)94 T ConsumeFloatingPointInRange(T min, T /* max */) { 95 return T(min); 96 } 97 98 template <typename T> ConsumeProbability()99 T ConsumeProbability() { 100 return T(0.0); 101 } 102 ConsumeBool()103 bool ConsumeBool() { return false; } 104 105 template <typename T> ConsumeEnum()106 T ConsumeEnum() { 107 return static_cast<T>(0); 108 } 109 110 template <typename T, size_t kSize> PickValueInArray(const T (& array)[kSize])111 T PickValueInArray(const T (&array)[kSize]) { 112 static_assert(kSize > 0, "The array must be non empty."); 113 return array[0]; 114 } 115 116 template <typename T> PickValueInArray(std::initializer_list<const T> list)117 T PickValueInArray(std::initializer_list<const T> list) { 118 static_assert(list.size() > 0, "The list must be non empty."); 119 return *list.begin(); 120 } 121 ConsumeData(void *,size_t)122 size_t ConsumeData(void* /* destination */, size_t /* num_bytes */) { 123 return 0; 124 } 125 remaining_bytes()126 size_t remaining_bytes() { return 0; } 127 }; 128 129 #endif // defined(__clang__) 130