102 lines
3.3 KiB
C++
102 lines
3.3 KiB
C++
// Copyright 2016 The Chromium Authors
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <string>
|
|
|
|
#include <fuzzer/FuzzedDataProvider.h>
|
|
|
|
#include "base/check_op.h"
|
|
#include "net/cookies/parsed_cookie.h"
|
|
|
|
const std::string GetArbitraryNameValueString(
|
|
FuzzedDataProvider* data_provider) {
|
|
// There's no longer an upper bound on the size of a cookie line, but
|
|
// in practice using double kMaxCookieNamePlusValueSize should allow
|
|
// the majority of interesting cases to be covered.
|
|
return data_provider->ConsumeRandomLengthString(
|
|
net::ParsedCookie::kMaxCookieNamePlusValueSize * 2);
|
|
}
|
|
|
|
const std::string GetArbitraryAttributeValueString(
|
|
FuzzedDataProvider* data_provider) {
|
|
// Adding a fudge factor to kMaxCookieAttributeValueSize so that both branches
|
|
// of the bounds detection code will be tested.
|
|
return data_provider->ConsumeRandomLengthString(
|
|
net::ParsedCookie::kMaxCookieAttributeValueSize + 10);
|
|
}
|
|
|
|
// Entry point for LibFuzzer.
|
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
|
FuzzedDataProvider data_provider(data, size);
|
|
const std::string cookie_line = GetArbitraryNameValueString(&data_provider);
|
|
net::ParsedCookie parsed_cookie(cookie_line);
|
|
|
|
// Call zero or one of ParsedCookie's mutator methods. Should not call
|
|
// anything other than SetName/SetValue when !IsValid().
|
|
const uint8_t action = data_provider.ConsumeIntegralInRange(0, 12);
|
|
switch (action) {
|
|
case 1:
|
|
parsed_cookie.SetName(GetArbitraryNameValueString(&data_provider));
|
|
break;
|
|
case 2:
|
|
parsed_cookie.SetValue(GetArbitraryNameValueString(&data_provider));
|
|
break;
|
|
}
|
|
|
|
if (parsed_cookie.IsValid()) {
|
|
switch (action) {
|
|
case 3:
|
|
if (parsed_cookie.IsValid())
|
|
parsed_cookie.SetPath(
|
|
GetArbitraryAttributeValueString(&data_provider));
|
|
break;
|
|
case 4:
|
|
parsed_cookie.SetDomain(
|
|
GetArbitraryAttributeValueString(&data_provider));
|
|
break;
|
|
case 5:
|
|
parsed_cookie.SetExpires(
|
|
GetArbitraryAttributeValueString(&data_provider));
|
|
break;
|
|
case 6:
|
|
parsed_cookie.SetMaxAge(
|
|
GetArbitraryAttributeValueString(&data_provider));
|
|
break;
|
|
case 7:
|
|
parsed_cookie.SetIsSecure(data_provider.ConsumeBool());
|
|
break;
|
|
case 8:
|
|
parsed_cookie.SetIsHttpOnly(data_provider.ConsumeBool());
|
|
break;
|
|
case 9:
|
|
parsed_cookie.SetSameSite(
|
|
GetArbitraryAttributeValueString(&data_provider));
|
|
break;
|
|
case 10:
|
|
parsed_cookie.SetPriority(
|
|
GetArbitraryAttributeValueString(&data_provider));
|
|
break;
|
|
case 11:
|
|
parsed_cookie.SetIsSameParty(data_provider.ConsumeBool());
|
|
break;
|
|
case 12:
|
|
parsed_cookie.SetIsPartitioned(data_provider.ConsumeBool());
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Check that serialize/deserialize inverse property holds for valid cookies.
|
|
if (parsed_cookie.IsValid()) {
|
|
const std::string serialized = parsed_cookie.ToCookieLine();
|
|
net::ParsedCookie reparsed_cookie(serialized);
|
|
const std::string reserialized = reparsed_cookie.ToCookieLine();
|
|
CHECK(reparsed_cookie.IsValid());
|
|
CHECK_EQ(serialized, reserialized);
|
|
}
|
|
|
|
return 0;
|
|
}
|