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