Skip to content
This repository has been archived by the owner on May 12, 2020. It is now read-only.

Add support for getting matched filter info in matches #181

Merged
merged 1 commit into from
Feb 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 27 additions & 13 deletions ad_block_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -734,8 +734,15 @@ bool isHostAnchoredHashSetMiss(const char *input, int inputLen,
return result;
}

bool AdBlockClient::matches(const char *input, FilterOption contextOption,
const char *contextDomain) {
bool AdBlockClient::matches(const char* input, FilterOption contextOption,
const char* contextDomain, Filter** matchedFilter,
Filter** matchedExceptionFilter) {
if (matchedFilter) {
*matchedFilter = nullptr;
}
if (matchedExceptionFilter) {
*matchedExceptionFilter = nullptr;
}
int inputLen = static_cast<int>(strlen(input));

if (!isBlockableProtocol(input, inputLen)) {
Expand Down Expand Up @@ -776,19 +783,22 @@ bool AdBlockClient::matches(const char *input, FilterOption contextOption,
noFingerprintDomainHashSet, contextDomain, contextDomainLen)) {
hasMatch = hasMatch || hasMatchingFilters(noFingerprintDomainOnlyFilters,
numNoFingerprintDomainOnlyFilters, input, inputLen, contextOption,
contextDomain, &inputBloomFilter, inputHost, inputHostLen);
contextDomain, &inputBloomFilter, inputHost, inputHostLen,
matchedFilter);
}
if (isNoFingerprintDomainHashSetMiss(
noFingerprintAntiDomainHashSet, contextDomain, contextDomainLen)) {
hasMatch = hasMatch ||
hasMatchingFilters(noFingerprintAntiDomainOnlyFilters,
numNoFingerprintAntiDomainOnlyFilters, input, inputLen, contextOption,
contextDomain, &inputBloomFilter, inputHost, inputHostLen);
contextDomain, &inputBloomFilter, inputHost, inputHostLen,
matchedFilter);
}

hasMatch = hasMatch || hasMatchingFilters(noFingerprintFilters,
numNoFingerprintFilters, input, inputLen, contextOption,
contextDomain, &inputBloomFilter, inputHost, inputHostLen);
contextDomain, &inputBloomFilter, inputHost, inputHostLen,
matchedFilter);

// If no noFingerprintFilters were hit, check the bloom filter substring
// fingerprint for the normal
Expand All @@ -801,7 +811,7 @@ bool AdBlockClient::matches(const char *input, FilterOption contextOption,
&& !bloomFilter->substringExists(input, AdBlockClient::kFingerprintSize);
hostAnchoredHashSetMiss = isHostAnchoredHashSetMiss(input, inputLen,
hostAnchoredHashSet, inputHost, inputHostLen,
contextOption, contextDomain);
contextOption, contextDomain, matchedFilter);
if (bloomFilterMiss && hostAnchoredHashSetMiss) {
if (bloomFilterMiss) {
numBloomFilterSaves++;
Expand All @@ -820,7 +830,7 @@ bool AdBlockClient::matches(const char *input, FilterOption contextOption,
if (!hasMatch && !bloomFilterMiss) {
hasMatch = hasMatchingFilters(filters, numFilters, input, inputLen,
contextOption, contextDomain, &inputBloomFilter,
inputHost, inputHostLen);
inputHost, inputHostLen, matchedFilter);
// If there's still no match after checking the block filters, then no need
// to try to block this because there is a false positive.
if (!hasMatch) {
Expand All @@ -844,22 +854,24 @@ bool AdBlockClient::matches(const char *input, FilterOption contextOption,
hasMatchingFilters(noFingerprintDomainOnlyExceptionFilters,
numNoFingerprintDomainOnlyExceptionFilters, input, inputLen,
contextOption, contextDomain, &inputBloomFilter, inputHost,
inputHostLen);
inputHostLen, matchedExceptionFilter);
}

if (isNoFingerprintDomainHashSetMiss(
noFingerprintAntiDomainExceptionHashSet, contextDomain,
contextDomainLen)) {
contextDomainLen )) {
hasExceptionMatch = hasExceptionMatch ||
hasMatchingFilters(noFingerprintAntiDomainOnlyExceptionFilters,
numNoFingerprintAntiDomainOnlyExceptionFilters, input, inputLen,
contextOption, contextDomain, &inputBloomFilter, inputHost, inputHostLen);
contextOption, contextDomain, &inputBloomFilter, inputHost, inputHostLen,
matchedExceptionFilter);
}

hasExceptionMatch = hasExceptionMatch ||
hasMatchingFilters(noFingerprintExceptionFilters,
numNoFingerprintExceptionFilters, input, inputLen, contextOption,
contextDomain, &inputBloomFilter, inputHost, inputHostLen);
contextDomain, &inputBloomFilter, inputHost, inputHostLen,
matchedExceptionFilter);

// If there's a matching no fingerprint exception then we can just return
// right away because we shouldn't block
Expand All @@ -872,7 +884,8 @@ bool AdBlockClient::matches(const char *input, FilterOption contextOption,
AdBlockClient::kFingerprintSize);
bool hostAnchoredExceptionHashSetMiss =
isHostAnchoredHashSetMiss(input, inputLen, hostAnchoredExceptionHashSet,
inputHost, inputHostLen, contextOption, contextDomain);
inputHost, inputHostLen, contextOption, contextDomain,
matchedExceptionFilter);

// Now that we have a matching rule, we should check if no exception rule
// hits, if none hits, we should block
Expand All @@ -896,7 +909,8 @@ bool AdBlockClient::matches(const char *input, FilterOption contextOption,
if (!bloomExceptionFilterMiss) {
if (!hasMatchingFilters(exceptionFilters, numExceptionFilters, input,
inputLen, contextOption, contextDomain,
&inputBloomFilter, inputHost, inputHostLen)) {
&inputBloomFilter, inputHost, inputHostLen,
matchedExceptionFilter)) {
// False positive on the exception filter list
numExceptionFalsePositives++;
// cout << "exception false positive for input: " << input << endl;
Expand Down
6 changes: 4 additions & 2 deletions ad_block_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ class AdBlockClient {
void clear();
// bool parse(const char *input);
bool parse(const char *input, bool preserveRules = false);
bool matches(const char *input,
bool matches(const char* input,
FilterOption contextOption = FONoFilterOption,
const char *contextDomain = nullptr);
const char* contextDomain = nullptr,
Filter** matchedFilter = nullptr,
Filter** matchedExceptionFilter = nullptr);
bool findMatchingFilters(const char *input,
FilterOption contextOption,
const char *contextDomain,
Expand Down
36 changes: 36 additions & 0 deletions test/parser_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -979,3 +979,39 @@ TEST(findMatchingFilters, basic) {
CHECK(!strcmp(matchingFilter->data, "googlesyndication.com/safeframe/"));
CHECK(!strcmp(matchingExceptionFilter->data, "safeframe"));
}

// Testing matchingFilter
TEST(matchesWithFilterInfo, basic) {
AdBlockClient client;
client.parse("||googlesyndication.com/safeframe/$third-party\n"
"||brianbondy.com/ads");
const char *urlToCheck =
"http://tpc.googlesyndication.com/safeframe/1-0-2/html/container.html";
const char *currentPageDomain = "slashdot.org";

Filter none;
Filter *matchingFilter = &none;
Filter *matchingExceptionFilter = &none;

// Test finds a match
CHECK(client.matches(urlToCheck, FOScript, currentPageDomain,
&matchingFilter, &matchingExceptionFilter));
CHECK(matchingFilter)
CHECK(matchingExceptionFilter == nullptr)
CHECK(!strcmp(matchingFilter->data, "googlesyndication.com/safeframe/"));

// Test when no filter is found, returns false and sets out params to nullptr
CHECK(!client.matches("ssafsdf.com", FOScript, currentPageDomain,
&matchingFilter, &matchingExceptionFilter));
CHECK(matchingFilter == nullptr)
CHECK(matchingExceptionFilter == nullptr)

// Parse that it finds exception filters correctly
client.parse("@@safeframe\n");
CHECK(!client.matches(urlToCheck, FOScript, currentPageDomain,
&matchingFilter, &matchingExceptionFilter));
CHECK(matchingFilter)
CHECK(matchingExceptionFilter)
CHECK(!strcmp(matchingFilter->data, "googlesyndication.com/safeframe/"));
CHECK(!strcmp(matchingExceptionFilter->data, "safeframe"));
}