• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 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 #include <string>
8 
9 #include <fuzzer/FuzzedDataProvider.h>
10 
11 #include "net/cookies/cookie_partition_key.h"
12 #include "url/origin.h"
13 
14 namespace net {
15 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)16 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
17   FuzzedDataProvider data_provider(data, size);
18 
19   std::string url_str = data_provider.ConsumeRandomLengthString(800);
20   GURL url(url_str);
21 
22   bool has_cross_site_ancestor = data_provider.ConsumeBool();
23   CookiePartitionKey::AncestorChainBit ancestor_chain_bit =
24       has_cross_site_ancestor ? CookiePartitionKey::AncestorChainBit::kCrossSite
25                               : CookiePartitionKey::AncestorChainBit::kSameSite;
26 
27   // Unlike FromURLForTesting and FromUntrustedInput, FromStorage requires the
28   // top_level_site string passed in be formatted exactly as a SchemefulSite
29   // would serialize it. Unlike FromURLForTesting, FromUntrustedInput and
30   // FromStorage require the top_level_site not be opaque.
31   base::expected<std::optional<CookiePartitionKey>, std::string>
32       partition_key_from_string_strict =
33           CookiePartitionKey::FromStorage(url_str, has_cross_site_ancestor);
34   base::expected<CookiePartitionKey, std::string>
35       partition_key_from_string_loose = CookiePartitionKey::FromUntrustedInput(
36           url_str, has_cross_site_ancestor);
37   CookiePartitionKey partition_key_from_url =
38       CookiePartitionKey::FromURLForTesting(url, ancestor_chain_bit);
39 
40   if (partition_key_from_string_strict.has_value() &&
41       partition_key_from_string_strict.value().has_value()) {
42     // If we can deserialize from string while being strict the three keys
43     // should be identical.
44     CHECK_EQ(**partition_key_from_string_strict, partition_key_from_url);
45     CHECK_EQ(**partition_key_from_string_strict,
46              *partition_key_from_string_loose);
47     // This implies we can re-serialize.
48     base::expected<CookiePartitionKey::SerializedCookiePartitionKey,
49                    std::string>
50         serialized_partition_key =
51             CookiePartitionKey::Serialize(**partition_key_from_string_strict);
52     CHECK(serialized_partition_key.has_value());
53     // The serialization should match the initial values.
54     CHECK_EQ(serialized_partition_key->TopLevelSite(), url_str);
55     CHECK_EQ(serialized_partition_key->has_cross_site_ancestor(),
56              has_cross_site_ancestor);
57   } else if (partition_key_from_string_loose.has_value()) {
58     // If we can deserialize from string while being loose then two keys
59     // should be identical.
60     CHECK_EQ(*partition_key_from_string_loose, partition_key_from_url);
61     // This implies we can re-serialize.
62     base::expected<CookiePartitionKey::SerializedCookiePartitionKey,
63                    std::string>
64         serialized_partition_key =
65             CookiePartitionKey::Serialize(*partition_key_from_string_loose);
66     // The serialization should match the initial values.
67     SchemefulSite schemeful_site(url);
68     CHECK_EQ(serialized_partition_key->TopLevelSite(),
69              schemeful_site.GetURL().SchemeIsFile()
70                  ? schemeful_site.SerializeFileSiteWithHost()
71                  : schemeful_site.Serialize());
72     CHECK_EQ(serialized_partition_key->has_cross_site_ancestor(),
73              has_cross_site_ancestor);
74   } else {
75     // If we cannot deserialize from string at all then top_level_site must be
76     // opaque.
77     CHECK(partition_key_from_url.site().opaque());
78   }
79 
80   return 0;
81 }
82 
83 }  // namespace net
84