// Copyright 2023 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "net/dns/host_resolver_cache.h" #include #include #include #include #include "base/check_op.h" #include "base/json/json_reader.h" #include "base/values.h" #include "testing/libfuzzer/proto/json.pb.h" #include "testing/libfuzzer/proto/json_proto_converter.h" #include "testing/libfuzzer/proto/lpm_interface.h" namespace net { extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { FuzzedDataProvider data_provider(data, size); size_t cache_size = data_provider.ConsumeIntegral(); if (cache_size == 0) { return 0; } // Either consume a JSON proto string to maximize base::Value compatibility or // a bare string to maximize fuzzing. std::string json_string; if (data_provider.ConsumeBool()) { std::vector bytes = data_provider.ConsumeRemainingBytes(); json_proto::JsonValue proto; if (!protobuf_mutator::libfuzzer::LoadProtoInput( /*binary=*/false, bytes.data(), bytes.size(), &proto)) { return 0; } json_string = json_proto::JsonProtoConverter().Convert(proto); } else { json_string = data_provider.ConsumeRemainingBytesAsString(); } std::optional value = base::JSONReader::Read(json_string); if (!value.has_value()) { return 0; } HostResolverCache cache(cache_size); if (!cache.RestoreFromValue(value.value())) { return 0; } base::Value reserialized = cache.Serialize(); // If at max size, may not have deserialized all data out of the fuzzed input. if (cache.AtMaxSizeForTesting()) { return 0; } CHECK_EQ(reserialized, value.value()); return 0; } } // namespace net