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