// Copyright 2021 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy of // the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations under // the License. #include "dice/cbor_writer.h" #include "fuzzer/FuzzedDataProvider.h" namespace { enum CborWriterFunction { WriteInt, WriteUint, WriteBstr, AllocBstr, WriteTstr, AllocTstr, WriteArray, WriteMap, WriteTag, WriteFalse, WriteTrue, WriteNull, kMaxValue = WriteNull, }; // Use data sizes that exceed the 16-bit range without being excessive. constexpr size_t kMaxDataSize = 0xffff + 0x5000; constexpr size_t kMaxBufferSize = kMaxDataSize * 3; constexpr size_t kIterations = CborWriterFunction::kMaxValue * 2; } // namespace extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { FuzzedDataProvider fdp(data, size); auto buffer_size = fdp.ConsumeIntegralInRange(0, kMaxBufferSize); std::vector buffer(buffer_size); CborOut out; CborOutInit(buffer.data(), buffer.size(), &out); for (size_t i = 0; i < kIterations; i++) { switch (fdp.ConsumeEnum()) { case WriteInt: CborWriteInt(fdp.ConsumeIntegral(), &out); break; case WriteUint: CborWriteUint(fdp.ConsumeIntegral(), &out); break; case WriteBstr: { auto bstr_data_size = fdp.ConsumeIntegralInRange(0, kMaxDataSize); std::vector bstr_data(bstr_data_size); CborWriteBstr(bstr_data.size(), bstr_data.data(), &out); break; } case AllocBstr: { auto bstr_data_size = fdp.ConsumeIntegralInRange(0, kMaxDataSize); uint8_t* ptr = CborAllocBstr(bstr_data_size, &out); if (ptr) { memset(ptr, 0x5a, bstr_data_size); } break; } case WriteTstr: { auto tstr_data_size = fdp.ConsumeIntegralInRange(0, kMaxDataSize); std::string str(tstr_data_size, 'a'); CborWriteTstr(str.c_str(), &out); break; } case AllocTstr: { auto tstr_data_size = fdp.ConsumeIntegralInRange(0, kMaxDataSize); char* str = CborAllocTstr(tstr_data_size, &out); if (str) { memset(str, 'q', tstr_data_size); } break; } case WriteArray: { auto num_elements = fdp.ConsumeIntegral(); CborWriteArray(num_elements, &out); break; } case WriteMap: { auto num_pairs = fdp.ConsumeIntegral(); CborWriteMap(num_pairs, &out); break; } case WriteTag: { auto tag = fdp.ConsumeIntegral(); CborWriteTag(tag, &out); break; } case WriteFalse: CborWriteNull(&out); break; case WriteTrue: CborWriteNull(&out); break; case WriteNull: CborWriteNull(&out); break; } } return 0; }