1 // Copyright 2023 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 "net/dns/host_resolver_cache.h" 6 7 #include <fuzzer/FuzzedDataProvider.h> 8 #include <stddef.h> 9 #include <stdint.h> 10 11 #include <optional> 12 13 #include "base/check_op.h" 14 #include "base/json/json_reader.h" 15 #include "base/values.h" 16 #include "testing/libfuzzer/proto/json.pb.h" 17 #include "testing/libfuzzer/proto/json_proto_converter.h" 18 #include "testing/libfuzzer/proto/lpm_interface.h" 19 20 namespace net { 21 LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)22extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { 23 FuzzedDataProvider data_provider(data, size); 24 25 size_t cache_size = data_provider.ConsumeIntegral<size_t>(); 26 if (cache_size == 0) { 27 return 0; 28 } 29 30 // Either consume a JSON proto string to maximize base::Value compatibility or 31 // a bare string to maximize fuzzing. 32 std::string json_string; 33 if (data_provider.ConsumeBool()) { 34 std::vector<uint8_t> bytes = data_provider.ConsumeRemainingBytes<uint8_t>(); 35 36 json_proto::JsonValue proto; 37 if (!protobuf_mutator::libfuzzer::LoadProtoInput( 38 /*binary=*/false, bytes.data(), bytes.size(), &proto)) { 39 return 0; 40 } 41 42 json_string = json_proto::JsonProtoConverter().Convert(proto); 43 } else { 44 json_string = data_provider.ConsumeRemainingBytesAsString(); 45 } 46 47 std::optional<base::Value> value = base::JSONReader::Read(json_string); 48 if (!value.has_value()) { 49 return 0; 50 } 51 52 HostResolverCache cache(cache_size); 53 if (!cache.RestoreFromValue(value.value())) { 54 return 0; 55 } 56 57 base::Value reserialized = cache.Serialize(); 58 59 // If at max size, may not have deserialized all data out of the fuzzed input. 60 if (cache.AtMaxSizeForTesting()) { 61 return 0; 62 } 63 64 CHECK_EQ(reserialized, value.value()); 65 66 return 0; 67 } 68 69 } // namespace net 70