1*60b67249SAndroid Build Coastguard Worker // Copyright 2021 Google LLC
2*60b67249SAndroid Build Coastguard Worker //
3*60b67249SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4*60b67249SAndroid Build Coastguard Worker // use this file except in compliance with the License. You may obtain a copy of
5*60b67249SAndroid Build Coastguard Worker // the License at
6*60b67249SAndroid Build Coastguard Worker //
7*60b67249SAndroid Build Coastguard Worker // https://www.apache.org/licenses/LICENSE-2.0
8*60b67249SAndroid Build Coastguard Worker //
9*60b67249SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*60b67249SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11*60b67249SAndroid Build Coastguard Worker // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12*60b67249SAndroid Build Coastguard Worker // License for the specific language governing permissions and limitations under
13*60b67249SAndroid Build Coastguard Worker // the License.
14*60b67249SAndroid Build Coastguard Worker
15*60b67249SAndroid Build Coastguard Worker #include "dice/cbor_writer.h"
16*60b67249SAndroid Build Coastguard Worker #include "fuzzer/FuzzedDataProvider.h"
17*60b67249SAndroid Build Coastguard Worker
18*60b67249SAndroid Build Coastguard Worker namespace {
19*60b67249SAndroid Build Coastguard Worker
20*60b67249SAndroid Build Coastguard Worker enum CborWriterFunction {
21*60b67249SAndroid Build Coastguard Worker WriteInt,
22*60b67249SAndroid Build Coastguard Worker WriteUint,
23*60b67249SAndroid Build Coastguard Worker WriteBstr,
24*60b67249SAndroid Build Coastguard Worker AllocBstr,
25*60b67249SAndroid Build Coastguard Worker WriteTstr,
26*60b67249SAndroid Build Coastguard Worker AllocTstr,
27*60b67249SAndroid Build Coastguard Worker WriteArray,
28*60b67249SAndroid Build Coastguard Worker WriteMap,
29*60b67249SAndroid Build Coastguard Worker WriteTag,
30*60b67249SAndroid Build Coastguard Worker WriteFalse,
31*60b67249SAndroid Build Coastguard Worker WriteTrue,
32*60b67249SAndroid Build Coastguard Worker WriteNull,
33*60b67249SAndroid Build Coastguard Worker kMaxValue = WriteNull,
34*60b67249SAndroid Build Coastguard Worker };
35*60b67249SAndroid Build Coastguard Worker
36*60b67249SAndroid Build Coastguard Worker // Use data sizes that exceed the 16-bit range without being excessive.
37*60b67249SAndroid Build Coastguard Worker constexpr size_t kMaxDataSize = 0xffff + 0x5000;
38*60b67249SAndroid Build Coastguard Worker constexpr size_t kMaxBufferSize = kMaxDataSize * 3;
39*60b67249SAndroid Build Coastguard Worker constexpr size_t kIterations = CborWriterFunction::kMaxValue * 2;
40*60b67249SAndroid Build Coastguard Worker
41*60b67249SAndroid Build Coastguard Worker } // namespace
42*60b67249SAndroid Build Coastguard Worker
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)43*60b67249SAndroid Build Coastguard Worker extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
44*60b67249SAndroid Build Coastguard Worker FuzzedDataProvider fdp(data, size);
45*60b67249SAndroid Build Coastguard Worker
46*60b67249SAndroid Build Coastguard Worker auto buffer_size = fdp.ConsumeIntegralInRange<size_t>(0, kMaxBufferSize);
47*60b67249SAndroid Build Coastguard Worker std::vector<uint8_t> buffer(buffer_size);
48*60b67249SAndroid Build Coastguard Worker CborOut out;
49*60b67249SAndroid Build Coastguard Worker CborOutInit(buffer.data(), buffer.size(), &out);
50*60b67249SAndroid Build Coastguard Worker
51*60b67249SAndroid Build Coastguard Worker for (size_t i = 0; i < kIterations; i++) {
52*60b67249SAndroid Build Coastguard Worker switch (fdp.ConsumeEnum<CborWriterFunction>()) {
53*60b67249SAndroid Build Coastguard Worker case WriteInt:
54*60b67249SAndroid Build Coastguard Worker CborWriteInt(fdp.ConsumeIntegral<int64_t>(), &out);
55*60b67249SAndroid Build Coastguard Worker break;
56*60b67249SAndroid Build Coastguard Worker case WriteUint:
57*60b67249SAndroid Build Coastguard Worker CborWriteUint(fdp.ConsumeIntegral<uint64_t>(), &out);
58*60b67249SAndroid Build Coastguard Worker break;
59*60b67249SAndroid Build Coastguard Worker case WriteBstr: {
60*60b67249SAndroid Build Coastguard Worker auto bstr_data_size =
61*60b67249SAndroid Build Coastguard Worker fdp.ConsumeIntegralInRange<size_t>(0, kMaxDataSize);
62*60b67249SAndroid Build Coastguard Worker std::vector<uint8_t> bstr_data(bstr_data_size);
63*60b67249SAndroid Build Coastguard Worker CborWriteBstr(bstr_data.size(), bstr_data.data(), &out);
64*60b67249SAndroid Build Coastguard Worker break;
65*60b67249SAndroid Build Coastguard Worker }
66*60b67249SAndroid Build Coastguard Worker case AllocBstr: {
67*60b67249SAndroid Build Coastguard Worker auto bstr_data_size =
68*60b67249SAndroid Build Coastguard Worker fdp.ConsumeIntegralInRange<size_t>(0, kMaxDataSize);
69*60b67249SAndroid Build Coastguard Worker uint8_t* ptr = CborAllocBstr(bstr_data_size, &out);
70*60b67249SAndroid Build Coastguard Worker if (ptr) {
71*60b67249SAndroid Build Coastguard Worker memset(ptr, 0x5a, bstr_data_size);
72*60b67249SAndroid Build Coastguard Worker }
73*60b67249SAndroid Build Coastguard Worker break;
74*60b67249SAndroid Build Coastguard Worker }
75*60b67249SAndroid Build Coastguard Worker case WriteTstr: {
76*60b67249SAndroid Build Coastguard Worker auto tstr_data_size =
77*60b67249SAndroid Build Coastguard Worker fdp.ConsumeIntegralInRange<size_t>(0, kMaxDataSize);
78*60b67249SAndroid Build Coastguard Worker std::string str(tstr_data_size, 'a');
79*60b67249SAndroid Build Coastguard Worker CborWriteTstr(str.c_str(), &out);
80*60b67249SAndroid Build Coastguard Worker break;
81*60b67249SAndroid Build Coastguard Worker }
82*60b67249SAndroid Build Coastguard Worker case AllocTstr: {
83*60b67249SAndroid Build Coastguard Worker auto tstr_data_size =
84*60b67249SAndroid Build Coastguard Worker fdp.ConsumeIntegralInRange<size_t>(0, kMaxDataSize);
85*60b67249SAndroid Build Coastguard Worker char* str = CborAllocTstr(tstr_data_size, &out);
86*60b67249SAndroid Build Coastguard Worker if (str) {
87*60b67249SAndroid Build Coastguard Worker memset(str, 'q', tstr_data_size);
88*60b67249SAndroid Build Coastguard Worker }
89*60b67249SAndroid Build Coastguard Worker break;
90*60b67249SAndroid Build Coastguard Worker }
91*60b67249SAndroid Build Coastguard Worker case WriteArray: {
92*60b67249SAndroid Build Coastguard Worker auto num_elements = fdp.ConsumeIntegral<size_t>();
93*60b67249SAndroid Build Coastguard Worker CborWriteArray(num_elements, &out);
94*60b67249SAndroid Build Coastguard Worker break;
95*60b67249SAndroid Build Coastguard Worker }
96*60b67249SAndroid Build Coastguard Worker case WriteMap: {
97*60b67249SAndroid Build Coastguard Worker auto num_pairs = fdp.ConsumeIntegral<size_t>();
98*60b67249SAndroid Build Coastguard Worker CborWriteMap(num_pairs, &out);
99*60b67249SAndroid Build Coastguard Worker break;
100*60b67249SAndroid Build Coastguard Worker }
101*60b67249SAndroid Build Coastguard Worker case WriteTag: {
102*60b67249SAndroid Build Coastguard Worker auto tag = fdp.ConsumeIntegral<uint64_t>();
103*60b67249SAndroid Build Coastguard Worker CborWriteTag(tag, &out);
104*60b67249SAndroid Build Coastguard Worker break;
105*60b67249SAndroid Build Coastguard Worker }
106*60b67249SAndroid Build Coastguard Worker case WriteFalse:
107*60b67249SAndroid Build Coastguard Worker CborWriteNull(&out);
108*60b67249SAndroid Build Coastguard Worker break;
109*60b67249SAndroid Build Coastguard Worker case WriteTrue:
110*60b67249SAndroid Build Coastguard Worker CborWriteNull(&out);
111*60b67249SAndroid Build Coastguard Worker break;
112*60b67249SAndroid Build Coastguard Worker case WriteNull:
113*60b67249SAndroid Build Coastguard Worker CborWriteNull(&out);
114*60b67249SAndroid Build Coastguard Worker break;
115*60b67249SAndroid Build Coastguard Worker }
116*60b67249SAndroid Build Coastguard Worker }
117*60b67249SAndroid Build Coastguard Worker
118*60b67249SAndroid Build Coastguard Worker return 0;
119*60b67249SAndroid Build Coastguard Worker }
120