Index: lib/abp2blocklist.js |
=================================================================== |
--- a/lib/abp2blocklist.js |
+++ b/lib/abp2blocklist.js |
@@ -137,17 +137,18 @@ |
function getURLSchemes(contentType) |
{ |
// If the given content type includes all supported URL schemes, simply |
// return a single generic URL scheme pattern. This minimizes the size of the |
// generated rule set. The downside to this is that it will also match |
// schemes that we do not want to match (e.g. "ftp://"), but this can be |
// mitigated by adding exceptions for those schemes. |
- if (contentType & typeMap.WEBSOCKET && contentType & typeMap.WEBRTC && |
+ if (contentType & typeMap.WEBSOCKET && |
+ (!typeMap.WEBRTC || contentType & typeMap.WEBRTC) && |
contentType & httpRequestTypes) |
return ["[^:]+:(//)?"]; |
let urlSchemes = []; |
if (contentType & typeMap.WEBSOCKET) |
urlSchemes.push("wss?://"); |
@@ -414,17 +415,17 @@ |
// If WebSocket or WebRTC are given along with other options but not |
// including all three of WebSocket, WebRTC, and at least one HTTP raw type, |
// we must generate multiple rules. For example, for the filter |
// "foo$websocket,image", we must generate one rule with "^wss?://" and "raw" |
// and another rule with "^https?://" and "image". If we merge the two, we |
// end up blocking requests of all HTTP raw types (e.g. XMLHttpRequest) |
// inadvertently. |
if ((contentType & typeMap.WEBSOCKET && contentType != typeMap.WEBSOCKET && |
- !(contentType & typeMap.WEBRTC && |
+ !((!typeMap.WEBRTC || contentType & typeMap.WEBRTC) && |
contentType & rawRequestTypes & httpRequestTypes)) || |
(contentType & typeMap.WEBRTC && contentType != typeMap.WEBRTC && |
!(contentType & typeMap.WEBSOCKET && |
contentType & rawRequestTypes & httpRequestTypes))) |
{ |
if (contentType & typeMap.WEBSOCKET) |
{ |
convertFilterAddRules(rules, filter, action, withResourceTypes, |
@@ -1225,19 +1226,21 @@ |
* Generate content blocker list for all filters that were added |
*/ |
ContentBlockerList.prototype.generateRules = function() |
{ |
let cssRules = []; |
let cssExceptionRules = []; |
let blockingRules = []; |
let blockingExceptionRules = []; |
+ let urlSchemeExceptionRules = []; |
let ruleGroups = [cssRules, cssExceptionRules, |
- blockingRules, blockingExceptionRules]; |
+ blockingRules, blockingExceptionRules, |
+ urlSchemeExceptionRules]; |
let genericSelectors = []; |
let groupedElemhideFilters = new Map(); |
for (let filter of this.elemhideFilters) |
{ |
let result = convertElemHideFilter(filter, this.elemhideSelectorExceptions); |
if (!result) |
@@ -1306,16 +1309,35 @@ |
} |
for (let filter of this.requestExceptions) |
{ |
convertFilterAddRules(blockingExceptionRules, filter, |
"ignore-previous-rules", true); |
} |
+ // If WebRTC is not supported, we still end up generating a lot of rules with |
+ // a generic URL scheme pattern that covers WebRTC anyway. In order to avoid |
+ // inadvertently blocking any WebRTC requests, we must add exceptions here |
+ // for WebRTC URLs. This is not required when WebRTC is supported, because in |
+ // that case we explicitly check if the filter covers WebRTC. |
+ if (!typeMap.WEBRTC) |
+ { |
+ urlSchemeExceptionRules.push([ |
+ { |
+ trigger: {"url-filter": "^stuns?:"}, |
+ action: {type: "ignore-previous-rules"} |
+ }, |
+ { |
+ trigger: {"url-filter": "^turns?:"}, |
+ action: {type: "ignore-previous-rules"} |
+ } |
+ ]); |
+ } |
+ |
return async(ruleGroups, (group, index) => () => |
{ |
let next = () => |
{ |
if (index == ruleGroups.length - 1) |
return ruleGroups.reduce((all, rules) => all.concat(rules), []); |
}; |