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