blob: 12d161393fd4b44c9bb60eacf360e0498587424f [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/subresource_filter/core/common/indexed_ruleset.h"
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <vector>
#include "base/at_exit.h"
#include "base/i18n/icu_util.h"
#include "base/strings/string_piece.h"
#include "base/test/fuzzed_data_provider.h"
#include "components/subresource_filter/core/common/first_party_origin.h"
#include "components/subresource_filter/core/common/unindexed_ruleset.h"
#include "components/url_pattern_index/url_pattern_index.h"
#include "third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.h"
#include "url/gurl.h"
#include "url/origin.h"
struct TestCase {
TestCase() { CHECK(base::i18n::InitializeICU()); }
base::AtExitManager at_exit_manager;
};
TestCase* test_case = new TestCase();
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
base::FuzzedDataProvider fuzzed_data(data, size);
// Split the input into two sections, the URL to check, and the ruleset
// itself.
std::string url_string = fuzzed_data.ConsumeRandomLengthString(1024);
const GURL url_to_check = GURL(url_string);
// Error out early if the URL isn't valid, since we early-return in the
// IndexedRulesetMatcher pretty early if this is the case.
if (!url_to_check.is_valid())
return 0;
std::vector<uint8_t> remaining_bytes = fuzzed_data.ConsumeRemainingBytes();
// First, interpret the remaining fuzzed data as an unindexed ruleset.
google::protobuf::io::ArrayInputStream input_stream(remaining_bytes.data(),
remaining_bytes.size());
subresource_filter::UnindexedRulesetReader reader(&input_stream);
// Use the unindexed ruleset to build a flat indexed ruleset.
subresource_filter::RulesetIndexer indexer;
url_pattern_index::proto::FilteringRules ruleset_chunk;
while (reader.ReadNextChunk(&ruleset_chunk)) {
for (const auto& rule : ruleset_chunk.url_rules())
indexer.AddUrlRule(rule);
}
indexer.Finish();
// Error out if we were unable to fully read the unindexed version.
if (reader.num_bytes_read() != static_cast<int64_t>(remaining_bytes.size()))
return 0;
CHECK(subresource_filter::IndexedRulesetMatcher::Verify(
indexer.data(), indexer.size(), indexer.GetChecksum()));
// Lastly, read into the indexed ruleset by matching the URL from the
// beginning of the fuzzed data.
subresource_filter::IndexedRulesetMatcher matcher(indexer.data(),
indexer.size());
// TODO(csharrison): Consider fuzzing things like the parent origin, the
// activation type, and the element type.
matcher.ShouldDisableFilteringForDocument(
url_to_check, url::Origin(),
url_pattern_index::proto::ACTIVATION_TYPE_DOCUMENT);
matcher.ShouldDisallowResourceLoad(
url_to_check, subresource_filter::FirstPartyOrigin(url::Origin()),
url_pattern_index::proto::ELEMENT_TYPE_SCRIPT,
false /* disable_generic_rules */);
return 0;
}