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