• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 Google LLC
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 #include "dice/cbor_writer.h"
16 #include "fuzzer/FuzzedDataProvider.h"
17 
18 namespace {
19 
20 enum CborWriterFunction {
21   WriteInt,
22   WriteUint,
23   WriteBstr,
24   AllocBstr,
25   WriteTstr,
26   AllocTstr,
27   WriteArray,
28   WriteMap,
29   WriteFalse,
30   WriteTrue,
31   WriteNull,
32   kMaxValue = WriteNull,
33 };
34 
35 // Use data sizes that exceed the 16-bit range without being excessive.
36 constexpr size_t kMaxDataSize = 0xffff + 0x5000;
37 constexpr size_t kMaxBufferSize = kMaxDataSize * 3;
38 constexpr size_t kIterations = CborWriterFunction::kMaxValue * 2;
39 
40 }  // namespace
41 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)42 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
43   FuzzedDataProvider fdp(data, size);
44 
45   auto buffer_size = fdp.ConsumeIntegralInRange<size_t>(0, kMaxBufferSize);
46   std::vector<uint8_t> buffer(buffer_size);
47   CborOut out;
48   CborOutInit(buffer.data(), buffer.size(), &out);
49 
50   for (size_t i = 0; i < kIterations; i++) {
51     switch (fdp.ConsumeEnum<CborWriterFunction>()) {
52       case WriteInt:
53         CborWriteInt(fdp.ConsumeIntegral<int64_t>(), &out);
54         break;
55       case WriteUint:
56         CborWriteUint(fdp.ConsumeIntegral<uint64_t>(), &out);
57         break;
58       case WriteBstr: {
59         auto bstr_data_size =
60             fdp.ConsumeIntegralInRange<size_t>(0, kMaxDataSize);
61         std::vector<uint8_t> bstr_data(bstr_data_size);
62         CborWriteBstr(bstr_data.size(), bstr_data.data(), &out);
63         break;
64       }
65       case AllocBstr: {
66         auto bstr_data_size =
67             fdp.ConsumeIntegralInRange<size_t>(0, kMaxDataSize);
68         uint8_t* ptr = CborAllocBstr(bstr_data_size, &out);
69         if (ptr) {
70           memset(ptr, 0x5a, bstr_data_size);
71         }
72         break;
73       }
74       case WriteTstr: {
75         auto tstr_data_size =
76             fdp.ConsumeIntegralInRange<size_t>(0, kMaxDataSize);
77         std::string str(tstr_data_size, 'a');
78         CborWriteTstr(str.c_str(), &out);
79         break;
80       }
81       case AllocTstr: {
82         auto tstr_data_size =
83             fdp.ConsumeIntegralInRange<size_t>(0, kMaxDataSize);
84         char* str = CborAllocTstr(tstr_data_size, &out);
85         if (str) {
86           memset(str, 'q', tstr_data_size);
87         }
88         break;
89       }
90       case WriteArray: {
91         auto num_elements = fdp.ConsumeIntegral<size_t>();
92         CborWriteArray(num_elements, &out);
93         break;
94       }
95       case WriteMap: {
96         auto num_pairs = fdp.ConsumeIntegral<size_t>();
97         CborWriteMap(num_pairs, &out);
98         break;
99       }
100       case WriteFalse:
101         CborWriteNull(&out);
102         break;
103       case WriteTrue:
104         CborWriteNull(&out);
105         break;
106       case WriteNull:
107         CborWriteNull(&out);
108         break;
109     }
110   }
111 
112   return 0;
113 }
114