Index: lib/abp2blocklist.js |
=================================================================== |
--- a/lib/abp2blocklist.js |
+++ b/lib/abp2blocklist.js |
@@ -271,20 +271,32 @@ |
parseDomains(filter.domains, included, excluded); |
if (exceptionDomains) |
excluded = excluded.concat(exceptionDomains); |
if (withResourceTypes) |
{ |
- trigger["resource-type"] = getResourceTypes(filter); |
+ let resourceTypes = getResourceTypes(filter); |
- if (trigger["resource-type"].length == 0) |
+ // Content blocker rules can't differentiate between sub-document requests |
+ // (iframes) and top-level document requests. To avoid too many false |
+ // positives, we prevent rules with no hostname part from blocking document |
+ // requests. |
+ // |
+ // Once Safari 11 becomes our minimum supported version, we could change |
+ // our approach here to use the new "unless-top-url" property instead. |
+ if (filter instanceof filterClasses.BlockingFilter && !parsed.hostname) |
+ resourceTypes = resourceTypes.filter(type => type != "document"); |
+ |
+ if (resourceTypes.length == 0) |
return; |
+ |
+ trigger["resource-type"] = resourceTypes; |
} |
if (filter.thirdParty != null) |
trigger["load-type"] = [filter.thirdParty ? "third-party" : "first-party"]; |
if (included.length > 0) |
{ |
trigger["if-domain"] = []; |
@@ -310,18 +322,25 @@ |
} |
} |
} |
else if (excluded.length > 0) |
{ |
trigger["unless-domain"] = excluded.map(name => "*" + name); |
} |
else if (filter instanceof filterClasses.BlockingFilter && |
- filter.contentType & typeMap.SUBDOCUMENT) |
+ filter.contentType & typeMap.SUBDOCUMENT && parsed.hostname) |
{ |
+ // Rules with a hostname part are still allowed to block document requests, |
+ // but we add an exception for top-level documents. |
+ // |
+ // Note that we can only do this if there's no "unless-domain" property for |
+ // now. This also only works in Safari 11 onwards, while older versions |
+ // simply ignore this property. Once Safari 11 becomes our minimum |
+ // supported version, we can merge "unless-domain" into "unless-top-url". |
trigger["unless-top-url"] = [trigger["url-filter"]]; |
if (trigger["url-filter-is-case-sensitive"]) |
trigger["top-url-filter-is-case-sensitive"] = true; |
} |
rules.push({trigger: trigger, action: {type: action}}); |
} |