https_record_rdata_fuzzer.cc 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "net/dns/https_record_rdata.h"
  5. #include <fuzzer/FuzzedDataProvider.h>
  6. #include <stdint.h>
  7. #include <memory>
  8. #include <set>
  9. #include <string>
  10. #include <vector>
  11. #include "base/check.h"
  12. #include "base/strings/string_piece.h"
  13. #include "net/base/ip_address.h"
  14. #include "net/dns/public/dns_protocol.h"
  15. namespace net {
  16. namespace {
  17. void ParseAndExercise(FuzzedDataProvider& data_provider) {
  18. std::string data1 = data_provider.ConsumeRandomLengthString();
  19. std::unique_ptr<HttpsRecordRdata> parsed = HttpsRecordRdata::Parse(data1);
  20. std::unique_ptr<HttpsRecordRdata> parsed2 = HttpsRecordRdata::Parse(data1);
  21. std::unique_ptr<HttpsRecordRdata> parsed3 =
  22. HttpsRecordRdata::Parse(data_provider.ConsumeRemainingBytesAsString());
  23. CHECK_EQ(!!parsed, !!parsed2);
  24. if (!parsed)
  25. return;
  26. // `parsed` and `parsed2` parsed from the same data, so they should always be
  27. // equal.
  28. CHECK(parsed->IsEqual(parsed.get()));
  29. CHECK(parsed->IsEqual(parsed2.get()));
  30. CHECK(parsed2->IsEqual(parsed.get()));
  31. // Attempt comparison with an rdata parsed from separate data. IsEqual() will
  32. // probably return false most of the time, but easily could be true if the
  33. // input data is similar enough.
  34. if (parsed3)
  35. CHECK_EQ(parsed->IsEqual(parsed3.get()), parsed3->IsEqual(parsed.get()));
  36. CHECK_EQ(parsed->Type(), dns_protocol::kTypeHttps);
  37. if (parsed->IsAlias()) {
  38. AliasFormHttpsRecordRdata* alias = parsed->AsAliasForm();
  39. alias->alias_name();
  40. } else {
  41. ServiceFormHttpsRecordRdata* service = parsed->AsServiceForm();
  42. CHECK_GT(service->priority(), 0);
  43. service->service_name();
  44. service->alpn_ids();
  45. service->default_alpn();
  46. service->port();
  47. service->ech_config();
  48. service->unparsed_params();
  49. service->IsCompatible();
  50. std::set<uint16_t> mandatory_keys = service->mandatory_keys();
  51. CHECK(mandatory_keys.find(dns_protocol::kHttpsServiceParamKeyMandatory) ==
  52. mandatory_keys.end());
  53. std::vector<IPAddress> ipv4_hint = service->ipv4_hint();
  54. for (const IPAddress& address : ipv4_hint) {
  55. CHECK(address.IsIPv4());
  56. }
  57. std::vector<IPAddress> ipv6_hint = service->ipv6_hint();
  58. for (const IPAddress& address : ipv6_hint) {
  59. CHECK(address.IsIPv6());
  60. }
  61. }
  62. }
  63. } // namespace
  64. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  65. FuzzedDataProvider data_provider(data, size);
  66. ParseAndExercise(data_provider);
  67. return 0;
  68. }
  69. } // namespace net