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.
|
||||
"+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
|
||||
|
@ -8,6 +8,9 @@
|
||||
#include <sstream>
|
||||
|
||||
#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/version.h"
|
||||
#include "content/public/browser/first_party_sets_handler.h"
|
||||
@ -19,6 +22,7 @@
|
||||
#include "net/first_party_sets/sets_mutation.h"
|
||||
#include "testing/gmock/include/gmock/gmock.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "third_party/fuzztest/src/fuzztest/fuzztest.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
using ::testing::ElementsAre;
|
||||
@ -1766,4 +1770,42 @@ TEST(FirstPartySetParser,
|
||||
/*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
|
||||
|
@ -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 = [
|
||||
"BiddingAndAuctionSerializerTargetSizeEstimator.DoesNotCrashForAnyInput",
|
||||
"ActionsParserFuzzTest.ParsesJSONCorrectly",
|
||||
"FirstPartySetFuzzer.ParsesSetsCorrectly",
|
||||
]
|
||||
|
||||
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") {
|
||||
sources = [
|
||||
"../../browser/first_party_sets/test/first_party_set_parser_json_fuzzer.cc",
|
||||
|
Reference in New Issue
Block a user