xref: /aosp_15_r20/external/cronet/net/dns/host_resolver_cache_fuzzer.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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)22 extern "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