fuzzing: rewrite FirstPartySetFuzzer to avoid gRPC dependency
Since we cannot depend on the gRPC corpus anymore, it's a good idea to start using FuzzTest so that we ensure the generated strings are valid JSON. Here, we're using a particular domain that'll both create valid and invalid JSON. This actually mimics the old corpus, because at every fuzzer start, we are feeding the string mutator with a valid JSON. This helps go deeper with a simple string mutator, while still testing for invalid cases. Bug: 399449169 Change-Id: I2e81d87323728b933a28fd84de95cb86a63281e6 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6308902 Commit-Queue: Paul Semel <paulsemel@chromium.org> Reviewed-by: Nasko Oskov <nasko@chromium.org> Cr-Commit-Position: refs/heads/main@{#1428401}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
cd08b67eed
commit
f0ffa8f6c4
content
@ -146,6 +146,11 @@ specific_include_rules = {
|
|||||||
# content -> tools dependency is disallowed, except buildflags for switches.
|
# content -> tools dependency is disallowed, except buildflags for switches.
|
||||||
"+tools/v8_context_snapshot/buildflags.h",
|
"+tools/v8_context_snapshot/buildflags.h",
|
||||||
],
|
],
|
||||||
|
".*_unittest\.(cc|h|m)": [
|
||||||
|
# unittests can now embed fuzzing tests, and this dependency is needed to
|
||||||
|
# access FUZZ_TEST macro and various domain generators.
|
||||||
|
"+third_party/fuzztest",
|
||||||
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
new_usages_require_review = True
|
new_usages_require_review = True
|
||||||
|
@ -8,6 +8,9 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include "base/json/json_reader.h"
|
#include "base/json/json_reader.h"
|
||||||
|
#include "base/json/json_writer.h"
|
||||||
|
#include "base/rand_util.h"
|
||||||
|
#include "base/test/fuzztest_support.h"
|
||||||
#include "base/test/metrics/histogram_tester.h"
|
#include "base/test/metrics/histogram_tester.h"
|
||||||
#include "base/version.h"
|
#include "base/version.h"
|
||||||
#include "content/public/browser/first_party_sets_handler.h"
|
#include "content/public/browser/first_party_sets_handler.h"
|
||||||
@ -19,6 +22,7 @@
|
|||||||
#include "net/first_party_sets/sets_mutation.h"
|
#include "net/first_party_sets/sets_mutation.h"
|
||||||
#include "testing/gmock/include/gmock/gmock.h"
|
#include "testing/gmock/include/gmock/gmock.h"
|
||||||
#include "testing/gtest/include/gtest/gtest.h"
|
#include "testing/gtest/include/gtest/gtest.h"
|
||||||
|
#include "third_party/fuzztest/src/fuzztest/fuzztest.h"
|
||||||
#include "url/gurl.h"
|
#include "url/gurl.h"
|
||||||
|
|
||||||
using ::testing::ElementsAre;
|
using ::testing::ElementsAre;
|
||||||
@ -1766,4 +1770,42 @@ TEST(FirstPartySetParser,
|
|||||||
/*aliases=*/{{associated2_cctld, associated2}}));
|
/*aliases=*/{{associated2_cctld, associated2}}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ParsesSetsCorrectly(std::string input) {
|
||||||
|
std::istringstream stream(input);
|
||||||
|
FirstPartySetParser::ParseSetsFromStream(stream, base::Version("1.0"), false,
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto JsonDomain() {
|
||||||
|
return fuzztest::ReversibleMap(
|
||||||
|
// The mapping function maps a base::Value to its JSON string
|
||||||
|
// representation.
|
||||||
|
[](base::Value value) {
|
||||||
|
std::string res;
|
||||||
|
base::JSONWriter::Write(std::move(value), &res);
|
||||||
|
return res;
|
||||||
|
},
|
||||||
|
// The inverse mapping function maps the JSON string representation to
|
||||||
|
// a tuple of base::Value. The return value is additionally wrapped in
|
||||||
|
// std::optional.
|
||||||
|
[](const std::string& value) -> std::optional<std::tuple<base::Value>> {
|
||||||
|
auto res = base::JSONReader::Read(value);
|
||||||
|
if (!res) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
// We use a tuple because the FuzzTest API requires it, since the
|
||||||
|
// inverse mapping can map one input value to multiple output values.
|
||||||
|
return std::tuple{std::move(*res)};
|
||||||
|
},
|
||||||
|
fuzztest::Arbitrary<base::Value>());
|
||||||
|
}
|
||||||
|
|
||||||
|
FUZZ_TEST(FirstPartySetFuzzer, ParsesSetsCorrectly)
|
||||||
|
.WithDomains(fuzztest::OneOf(JsonDomain(),
|
||||||
|
fuzztest::Arbitrary<std::string>().WithSeeds(
|
||||||
|
[]() -> std::vector<std::string> {
|
||||||
|
auto domain = JsonDomain();
|
||||||
|
return {domain.GetRandomValue(
|
||||||
|
base::RandomBitGenerator())};
|
||||||
|
})));
|
||||||
} // namespace content
|
} // namespace content
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
// Copyright 2020 The Chromium Authors
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#include "content/browser/first_party_sets/first_party_set_parser.h"
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <memory>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
#include "base/version.h"
|
|
||||||
|
|
||||||
namespace content {
|
|
||||||
|
|
||||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
|
||||||
std::string string_input(reinterpret_cast<const char*>(data), size);
|
|
||||||
std::istringstream stream(string_input);
|
|
||||||
FirstPartySetParser::ParseSetsFromStream(stream, base::Version("1.0"), false,
|
|
||||||
false);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace content
|
|
@ -1,35 +0,0 @@
|
|||||||
# Copyright 2020 The Chromium Authors
|
|
||||||
# Use of this source code is governed by a BSD-style license that can be
|
|
||||||
# found in the LICENSE file.
|
|
||||||
|
|
||||||
"{"
|
|
||||||
"}"
|
|
||||||
"["
|
|
||||||
"]"
|
|
||||||
"\""
|
|
||||||
"'"
|
|
||||||
"\\"
|
|
||||||
"//"
|
|
||||||
":"
|
|
||||||
","
|
|
||||||
" "
|
|
||||||
"\\n"
|
|
||||||
"\\r"
|
|
||||||
"/*"
|
|
||||||
"*/"
|
|
||||||
"true"
|
|
||||||
"false"
|
|
||||||
"null"
|
|
||||||
"\\u"
|
|
||||||
"\\b"
|
|
||||||
"\\f"
|
|
||||||
"\\t"
|
|
||||||
"."
|
|
||||||
"e"
|
|
||||||
"e+"
|
|
||||||
"e-"
|
|
||||||
"E"
|
|
||||||
"E+"
|
|
||||||
"E-"
|
|
||||||
"owner"
|
|
||||||
"members"
|
|
@ -2962,6 +2962,7 @@ test("content_unittests") {
|
|||||||
fuzztests = [
|
fuzztests = [
|
||||||
"BiddingAndAuctionSerializerTargetSizeEstimator.DoesNotCrashForAnyInput",
|
"BiddingAndAuctionSerializerTargetSizeEstimator.DoesNotCrashForAnyInput",
|
||||||
"ActionsParserFuzzTest.ParsesJSONCorrectly",
|
"ActionsParserFuzzTest.ParsesJSONCorrectly",
|
||||||
|
"FirstPartySetFuzzer.ParsesSetsCorrectly",
|
||||||
]
|
]
|
||||||
|
|
||||||
if (is_mac) {
|
if (is_mac) {
|
||||||
|
@ -332,15 +332,6 @@ if (use_fuzzing_engine) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fuzzer_test("first_party_set_parser_fuzzer") {
|
|
||||||
sources =
|
|
||||||
[ "../../browser/first_party_sets/test/first_party_set_parser_fuzzer.cc" ]
|
|
||||||
deps = [ ":first_party_set_parser_fuzzer_support" ]
|
|
||||||
dict =
|
|
||||||
"../../browser/first_party_sets/test/first_party_set_parser_fuzzer.dict"
|
|
||||||
seed_corpus = "//third_party/grpc/source/test/core/json/corpus/"
|
|
||||||
}
|
|
||||||
|
|
||||||
fuzzer_test("first_party_set_parser_json_fuzzer") {
|
fuzzer_test("first_party_set_parser_json_fuzzer") {
|
||||||
sources = [
|
sources = [
|
||||||
"../../browser/first_party_sets/test/first_party_set_parser_json_fuzzer.cc",
|
"../../browser/first_party_sets/test/first_party_set_parser_json_fuzzer.cc",
|
||||||
|
Reference in New Issue
Block a user