xref: /aosp_15_r20/external/cronet/net/cookies/parse_cookie_line_fuzzer.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2016 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 "base/check_op.h"
12 #include "net/cookies/parsed_cookie.h"
13 
GetArbitraryNameValueString(FuzzedDataProvider * data_provider)14 const std::string GetArbitraryNameValueString(
15     FuzzedDataProvider* data_provider) {
16   // There's no longer an upper bound on the size of a cookie line, but
17   // in practice using double kMaxCookieNamePlusValueSize should allow
18   // the majority of interesting cases to be covered.
19   return data_provider->ConsumeRandomLengthString(
20       net::ParsedCookie::kMaxCookieNamePlusValueSize * 2);
21 }
22 
GetArbitraryAttributeValueString(FuzzedDataProvider * data_provider)23 const std::string GetArbitraryAttributeValueString(
24     FuzzedDataProvider* data_provider) {
25   // Adding a fudge factor to kMaxCookieAttributeValueSize so that both branches
26   // of the bounds detection code will be tested.
27   return data_provider->ConsumeRandomLengthString(
28       net::ParsedCookie::kMaxCookieAttributeValueSize + 10);
29 }
30 
31 // Entry point for LibFuzzer.
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)32 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
33   FuzzedDataProvider data_provider(data, size);
34   const std::string cookie_line = GetArbitraryNameValueString(&data_provider);
35   net::ParsedCookie parsed_cookie(cookie_line);
36 
37   // Call zero or one of ParsedCookie's mutator methods.  Should not call
38   // anything other than SetName/SetValue when !IsValid().
39   const uint8_t action = data_provider.ConsumeIntegralInRange(0, 11);
40   switch (action) {
41     case 1:
42       parsed_cookie.SetName(GetArbitraryNameValueString(&data_provider));
43       break;
44     case 2:
45       parsed_cookie.SetValue(GetArbitraryNameValueString(&data_provider));
46       break;
47   }
48 
49   if (parsed_cookie.IsValid()) {
50     switch (action) {
51       case 3:
52         if (parsed_cookie.IsValid())
53           parsed_cookie.SetPath(
54               GetArbitraryAttributeValueString(&data_provider));
55         break;
56       case 4:
57         parsed_cookie.SetDomain(
58             GetArbitraryAttributeValueString(&data_provider));
59         break;
60       case 5:
61         parsed_cookie.SetExpires(
62             GetArbitraryAttributeValueString(&data_provider));
63         break;
64       case 6:
65         parsed_cookie.SetMaxAge(
66             GetArbitraryAttributeValueString(&data_provider));
67         break;
68       case 7:
69         parsed_cookie.SetIsSecure(data_provider.ConsumeBool());
70         break;
71       case 8:
72         parsed_cookie.SetIsHttpOnly(data_provider.ConsumeBool());
73         break;
74       case 9:
75         parsed_cookie.SetSameSite(
76             GetArbitraryAttributeValueString(&data_provider));
77         break;
78       case 10:
79         parsed_cookie.SetPriority(
80             GetArbitraryAttributeValueString(&data_provider));
81         break;
82       case 11:
83         parsed_cookie.SetIsPartitioned(data_provider.ConsumeBool());
84         break;
85     }
86   }
87 
88   // Check that serialize/deserialize inverse property holds for valid cookies.
89   if (parsed_cookie.IsValid()) {
90     const std::string serialized = parsed_cookie.ToCookieLine();
91     net::ParsedCookie reparsed_cookie(serialized);
92     const std::string reserialized = reparsed_cookie.ToCookieLine();
93     CHECK(reparsed_cookie.IsValid());
94     CHECK_EQ(serialized, reserialized);
95   }
96 
97   return 0;
98 }
99