1 // Copyright 2018 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <fuzzer/FuzzedDataProvider.h> 6 7 #include <tuple> 8 9 #include "base/containers/span.h" 10 #include "base/pickle.h" 11 12 namespace { 13 constexpr int kIterations = 16; 14 constexpr int kReadControlBytes = 32; 15 constexpr int kReadDataTypes = 17; 16 constexpr int kMaxReadLength = 1024; 17 constexpr int kMaxSkipBytes = 1024; 18 } // namespace 19 LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)20extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { 21 if (size < kReadControlBytes) { 22 return 0; 23 } 24 // Use the first kReadControlBytes bytes of the fuzzer input to control how 25 // the pickled data is read. 26 FuzzedDataProvider data_provider(data, kReadControlBytes); 27 data += kReadControlBytes; 28 size -= kReadControlBytes; 29 30 base::Pickle pickle = 31 base::Pickle::WithUnownedBuffer(UNSAFE_BUFFERS(base::span(data, size))); 32 base::PickleIterator iter(pickle); 33 for (int i = 0; i < kIterations; i++) { 34 uint8_t read_type = data_provider.ConsumeIntegral<uint8_t>(); 35 switch (read_type % kReadDataTypes) { 36 case 0: { 37 bool result = 0; 38 std::ignore = iter.ReadBool(&result); 39 break; 40 } 41 case 1: { 42 int result = 0; 43 std::ignore = iter.ReadInt(&result); 44 break; 45 } 46 case 2: { 47 long result = 0; 48 std::ignore = iter.ReadLong(&result); 49 break; 50 } 51 case 3: { 52 uint16_t result = 0; 53 std::ignore = iter.ReadUInt16(&result); 54 break; 55 } 56 case 4: { 57 uint32_t result = 0; 58 std::ignore = iter.ReadUInt32(&result); 59 break; 60 } 61 case 5: { 62 int64_t result = 0; 63 std::ignore = iter.ReadInt64(&result); 64 break; 65 } 66 case 6: { 67 uint64_t result = 0; 68 std::ignore = iter.ReadUInt64(&result); 69 break; 70 } 71 case 7: { 72 float result = 0; 73 std::ignore = iter.ReadFloat(&result); 74 break; 75 } 76 case 8: { 77 double result = 0; 78 std::ignore = iter.ReadDouble(&result); 79 break; 80 } 81 case 9: { 82 std::string result; 83 std::ignore = iter.ReadString(&result); 84 break; 85 } 86 case 10: { 87 base::StringPiece result; 88 std::ignore = iter.ReadStringPiece(&result); 89 break; 90 } 91 case 11: { 92 std::u16string result; 93 std::ignore = iter.ReadString16(&result); 94 break; 95 } 96 case 12: { 97 base::StringPiece16 result; 98 std::ignore = iter.ReadStringPiece16(&result); 99 break; 100 } 101 case 13: { 102 const char* data_result = nullptr; 103 size_t length_result = 0; 104 std::ignore = iter.ReadData(&data_result, &length_result); 105 break; 106 } 107 case 14: { 108 const char* data_result = nullptr; 109 int read_length = 110 data_provider.ConsumeIntegralInRange(0, kMaxReadLength); 111 std::ignore = 112 iter.ReadBytes(&data_result, static_cast<size_t>(read_length)); 113 break; 114 } 115 case 15: { 116 size_t result = 0; 117 std::ignore = iter.ReadLength(&result); 118 break; 119 } 120 case 16: { 121 std::ignore = iter.SkipBytes(static_cast<size_t>( 122 data_provider.ConsumeIntegralInRange(0, kMaxSkipBytes))); 123 break; 124 } 125 } 126 } 127 128 return 0; 129 } 130