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)14const 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)23const 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)32extern "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