• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)21 extern "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