2014-06-24 00:42:43 +02:00
|
|
|
/*******************************************************************************
|
|
|
|
|
2016-03-07 15:55:04 +01:00
|
|
|
uBlock Origin - a browser extension to block requests.
|
2018-07-22 16:47:02 +02:00
|
|
|
Copyright (C) 2014-present Raymond Hill
|
2014-06-24 00:42:43 +02:00
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
|
|
|
|
|
|
|
Home: https://github.com/gorhill/uBlock
|
|
|
|
*/
|
|
|
|
|
2016-07-01 04:03:29 +02:00
|
|
|
'use strict';
|
|
|
|
|
2021-07-25 16:55:35 +02:00
|
|
|
/******************************************************************************/
|
|
|
|
|
|
|
|
import {
|
|
|
|
domainFromHostname,
|
|
|
|
hostnameFromURI,
|
|
|
|
isNetworkURI,
|
|
|
|
} from './uri-utils.js';
|
|
|
|
|
|
|
|
import µBlock from './background.js';
|
|
|
|
|
2014-06-24 00:42:43 +02:00
|
|
|
/*******************************************************************************
|
|
|
|
|
|
|
|
A PageRequestStore object is used to store net requests in two ways:
|
|
|
|
|
|
|
|
To record distinct net requests
|
|
|
|
To create a log of net requests
|
|
|
|
|
|
|
|
**/
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2018-12-13 18:30:54 +01:00
|
|
|
const µb = µBlock;
|
2014-06-24 00:42:43 +02:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
const NetFilteringResultCache = class {
|
|
|
|
constructor() {
|
|
|
|
this.init();
|
|
|
|
}
|
2018-12-21 20:16:17 +01:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
init() {
|
2018-12-21 20:16:17 +01:00
|
|
|
this.blocked = new Map();
|
|
|
|
this.results = new Map();
|
|
|
|
this.hash = 0;
|
|
|
|
this.timer = undefined;
|
|
|
|
return this;
|
2019-07-05 23:44:08 +02:00
|
|
|
}
|
2018-12-21 20:16:17 +01:00
|
|
|
|
2020-10-10 14:36:30 +02:00
|
|
|
// https://github.com/gorhill/uBlock/issues/3619
|
|
|
|
// Don't collapse redirected resources
|
2019-07-05 23:44:08 +02:00
|
|
|
rememberResult(fctxt, result) {
|
2018-12-21 20:16:17 +01:00
|
|
|
if ( fctxt.tabId <= 0 ) { return; }
|
|
|
|
if ( this.results.size === 0 ) {
|
|
|
|
this.pruneAsync();
|
2017-08-03 16:18:05 +02:00
|
|
|
}
|
2020-10-10 14:36:30 +02:00
|
|
|
const key = `${fctxt.getDocHostname()} ${fctxt.type} ${fctxt.url}`;
|
2018-12-21 20:16:17 +01:00
|
|
|
this.results.set(key, {
|
2020-10-10 14:36:30 +02:00
|
|
|
result,
|
|
|
|
redirectURL: fctxt.redirectURL,
|
2018-12-21 20:16:17 +01:00
|
|
|
logData: fctxt.filter,
|
|
|
|
tstamp: Date.now()
|
|
|
|
});
|
2020-10-10 14:36:30 +02:00
|
|
|
if ( result !== 1 || fctxt.redirectURL !== undefined ) { return; }
|
2018-12-21 20:16:17 +01:00
|
|
|
const now = Date.now();
|
|
|
|
this.blocked.set(key, now);
|
|
|
|
this.hash = now;
|
2019-07-05 23:44:08 +02:00
|
|
|
}
|
2018-12-21 20:16:17 +01:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
rememberBlock(fctxt) {
|
2018-12-21 20:16:17 +01:00
|
|
|
if ( fctxt.tabId <= 0 ) { return; }
|
|
|
|
if ( this.blocked.size === 0 ) {
|
|
|
|
this.pruneAsync();
|
2014-07-30 07:05:35 +02:00
|
|
|
}
|
2020-10-10 14:36:30 +02:00
|
|
|
if ( fctxt.redirectURL !== undefined ) { return; }
|
2018-12-21 20:16:17 +01:00
|
|
|
const now = Date.now();
|
|
|
|
this.blocked.set(
|
2020-10-10 14:36:30 +02:00
|
|
|
`${fctxt.getDocHostname()} ${fctxt.type} ${fctxt.url}`,
|
2018-12-21 20:16:17 +01:00
|
|
|
now
|
|
|
|
);
|
|
|
|
this.hash = now;
|
2019-07-05 23:44:08 +02:00
|
|
|
}
|
2018-12-21 20:16:17 +01:00
|
|
|
|
2020-10-10 14:36:30 +02:00
|
|
|
forgetResult(docHostname, type, url) {
|
|
|
|
const key = `${docHostname} ${type} ${url}`;
|
2020-10-09 19:50:54 +02:00
|
|
|
this.results.delete(key);
|
|
|
|
this.blocked.delete(key);
|
|
|
|
}
|
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
empty() {
|
2018-12-21 20:16:17 +01:00
|
|
|
this.blocked.clear();
|
|
|
|
this.results.clear();
|
|
|
|
this.hash = 0;
|
|
|
|
if ( this.timer !== undefined ) {
|
|
|
|
clearTimeout(this.timer);
|
|
|
|
this.timer = undefined;
|
|
|
|
}
|
2019-07-05 23:44:08 +02:00
|
|
|
}
|
2018-12-21 20:16:17 +01:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
prune() {
|
2018-12-21 20:16:17 +01:00
|
|
|
const obsolete = Date.now() - this.shelfLife;
|
|
|
|
for ( const entry of this.blocked ) {
|
|
|
|
if ( entry[1] <= obsolete ) {
|
|
|
|
this.results.delete(entry[0]);
|
|
|
|
this.blocked.delete(entry[0]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for ( const entry of this.results ) {
|
|
|
|
if ( entry[1].tstamp <= obsolete ) {
|
|
|
|
this.results.delete(entry[0]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( this.blocked.size !== 0 || this.results.size !== 0 ) {
|
|
|
|
this.pruneAsync();
|
|
|
|
}
|
2019-07-05 23:44:08 +02:00
|
|
|
}
|
2018-12-21 20:16:17 +01:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
pruneAsync() {
|
2018-12-21 20:16:17 +01:00
|
|
|
if ( this.timer !== undefined ) { return; }
|
|
|
|
this.timer = vAPI.setTimeout(
|
|
|
|
( ) => {
|
|
|
|
this.timer = undefined;
|
|
|
|
this.prune();
|
|
|
|
},
|
|
|
|
this.shelfLife
|
|
|
|
);
|
2019-07-05 23:44:08 +02:00
|
|
|
}
|
2018-12-21 20:16:17 +01:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
lookupResult(fctxt) {
|
2020-11-10 16:43:26 +01:00
|
|
|
const entry = this.results.get(
|
2018-12-21 20:16:17 +01:00
|
|
|
fctxt.getDocHostname() + ' ' +
|
|
|
|
fctxt.type + ' ' +
|
|
|
|
fctxt.url
|
|
|
|
);
|
2020-11-10 16:43:26 +01:00
|
|
|
if ( entry === undefined ) { return; }
|
|
|
|
// We need to use a new WAR secret if one is present since WAR secrets
|
|
|
|
// can only be used once.
|
|
|
|
if (
|
|
|
|
entry.redirectURL !== undefined &&
|
|
|
|
entry.redirectURL.startsWith(this.extensionOriginURL)
|
|
|
|
) {
|
|
|
|
const redirectURL = new URL(entry.redirectURL);
|
|
|
|
redirectURL.searchParams.set('secret', vAPI.warSecret());
|
|
|
|
entry.redirectURL = redirectURL.href;
|
|
|
|
}
|
|
|
|
return entry;
|
2019-07-05 23:44:08 +02:00
|
|
|
}
|
2018-12-21 20:16:17 +01:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
lookupAllBlocked(hostname) {
|
2018-12-21 20:16:17 +01:00
|
|
|
const result = [];
|
|
|
|
for ( const entry of this.blocked ) {
|
|
|
|
const pos = entry[0].indexOf(' ');
|
|
|
|
if ( entry[0].slice(0, pos) === hostname ) {
|
|
|
|
result[result.length] = entry[0].slice(pos + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
2019-07-05 23:44:08 +02:00
|
|
|
}
|
2014-09-14 22:20:40 +02:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
static factory() {
|
2019-09-21 22:42:15 +02:00
|
|
|
return new NetFilteringResultCache();
|
2019-07-05 23:44:08 +02:00
|
|
|
}
|
2014-09-14 22:20:40 +02:00
|
|
|
};
|
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
NetFilteringResultCache.prototype.shelfLife = 15000;
|
2020-11-10 16:43:26 +01:00
|
|
|
NetFilteringResultCache.prototype.extensionOriginURL = vAPI.getURL('/');
|
2019-07-05 23:44:08 +02:00
|
|
|
|
2014-09-14 22:20:40 +02:00
|
|
|
/******************************************************************************/
|
|
|
|
|
Add support for `cname` type and `denyallow` option
This concerns the static network filtering engine.
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/943
* * *
New static network filter type: `cname`
By default, network requests which are result of
resolving a canonical name are subject to filtering.
This filtering can be bypassed by creating exception
filters using the `cname` option. For example:
@@*$cname
The filter above tells the network filtering engine
to except network requests which fulfill all the
following conditions:
- network request is blocked
- network request is that of an unaliased hostname
Filter list authors are discouraged from using
exception filters of `cname` type, unless there no
other practical solution such that maintenance
burden become the greater issue. Of course, such
exception filters should be as narrow as possible,
i.e. apply to specific domain, etc.
* * *
New static network filter option: `denyallow`
The purpose of `denyallow` is bring
default-deny/allow-exceptionally ability into static
network filtering arsenal. Example of usage:
*$3p,script, \
denyallow=x.com|y.com \
domain=a.com|b.com
The above filter tells the network filtering engine that
when the context is `a.com` or `b.com`, block all
3rd-party scripts except those from `x.com` and `y.com`.
Essentially, the new `denyallow` option makes it easier
to implement default-deny/allow-exceptionally in static
filter lists, whereas before this had to be done with
unwieldy regular expressions[1], or through the mix of
broadly blocking filters along with exception filters[2].
[1] https://hg.adblockplus.org/ruadlist/rev/f362910bc9a0
[2] Typically filters which pattern are of the
form `|http*://`
2020-03-15 17:23:25 +01:00
|
|
|
// Frame stores are used solely to associate a URL with a frame id.
|
2015-04-09 00:46:08 +02:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
const FrameStore = class {
|
2021-01-10 17:56:27 +01:00
|
|
|
constructor(frameURL, parentId) {
|
|
|
|
this.init(frameURL, parentId);
|
2019-07-05 23:44:08 +02:00
|
|
|
}
|
2014-07-30 07:05:35 +02:00
|
|
|
|
2021-01-10 17:56:27 +01:00
|
|
|
init(frameURL, parentId) {
|
2020-07-18 13:44:26 +02:00
|
|
|
this.t0 = Date.now();
|
2021-01-10 17:56:27 +01:00
|
|
|
this.parentId = parentId;
|
Add support for `cname` type and `denyallow` option
This concerns the static network filtering engine.
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/943
* * *
New static network filter type: `cname`
By default, network requests which are result of
resolving a canonical name are subject to filtering.
This filtering can be bypassed by creating exception
filters using the `cname` option. For example:
@@*$cname
The filter above tells the network filtering engine
to except network requests which fulfill all the
following conditions:
- network request is blocked
- network request is that of an unaliased hostname
Filter list authors are discouraged from using
exception filters of `cname` type, unless there no
other practical solution such that maintenance
burden become the greater issue. Of course, such
exception filters should be as narrow as possible,
i.e. apply to specific domain, etc.
* * *
New static network filter option: `denyallow`
The purpose of `denyallow` is bring
default-deny/allow-exceptionally ability into static
network filtering arsenal. Example of usage:
*$3p,script, \
denyallow=x.com|y.com \
domain=a.com|b.com
The above filter tells the network filtering engine that
when the context is `a.com` or `b.com`, block all
3rd-party scripts except those from `x.com` and `y.com`.
Essentially, the new `denyallow` option makes it easier
to implement default-deny/allow-exceptionally in static
filter lists, whereas before this had to be done with
unwieldy regular expressions[1], or through the mix of
broadly blocking filters along with exception filters[2].
[1] https://hg.adblockplus.org/ruadlist/rev/f362910bc9a0
[2] Typically filters which pattern are of the
form `|http*://`
2020-03-15 17:23:25 +01:00
|
|
|
this.exceptCname = undefined;
|
2020-10-10 14:36:30 +02:00
|
|
|
this.clickToLoad = false;
|
Add support for `cname` type and `denyallow` option
This concerns the static network filtering engine.
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/943
* * *
New static network filter type: `cname`
By default, network requests which are result of
resolving a canonical name are subject to filtering.
This filtering can be bypassed by creating exception
filters using the `cname` option. For example:
@@*$cname
The filter above tells the network filtering engine
to except network requests which fulfill all the
following conditions:
- network request is blocked
- network request is that of an unaliased hostname
Filter list authors are discouraged from using
exception filters of `cname` type, unless there no
other practical solution such that maintenance
burden become the greater issue. Of course, such
exception filters should be as narrow as possible,
i.e. apply to specific domain, etc.
* * *
New static network filter option: `denyallow`
The purpose of `denyallow` is bring
default-deny/allow-exceptionally ability into static
network filtering arsenal. Example of usage:
*$3p,script, \
denyallow=x.com|y.com \
domain=a.com|b.com
The above filter tells the network filtering engine that
when the context is `a.com` or `b.com`, block all
3rd-party scripts except those from `x.com` and `y.com`.
Essentially, the new `denyallow` option makes it easier
to implement default-deny/allow-exceptionally in static
filter lists, whereas before this had to be done with
unwieldy regular expressions[1], or through the mix of
broadly blocking filters along with exception filters[2].
[1] https://hg.adblockplus.org/ruadlist/rev/f362910bc9a0
[2] Typically filters which pattern are of the
form `|http*://`
2020-03-15 17:23:25 +01:00
|
|
|
this.rawURL = frameURL;
|
|
|
|
if ( frameURL !== undefined ) {
|
2021-07-25 16:55:35 +02:00
|
|
|
this.hostname = hostnameFromURI(frameURL);
|
|
|
|
this.domain = domainFromHostname(this.hostname) || this.hostname;
|
Add support for `cname` type and `denyallow` option
This concerns the static network filtering engine.
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/943
* * *
New static network filter type: `cname`
By default, network requests which are result of
resolving a canonical name are subject to filtering.
This filtering can be bypassed by creating exception
filters using the `cname` option. For example:
@@*$cname
The filter above tells the network filtering engine
to except network requests which fulfill all the
following conditions:
- network request is blocked
- network request is that of an unaliased hostname
Filter list authors are discouraged from using
exception filters of `cname` type, unless there no
other practical solution such that maintenance
burden become the greater issue. Of course, such
exception filters should be as narrow as possible,
i.e. apply to specific domain, etc.
* * *
New static network filter option: `denyallow`
The purpose of `denyallow` is bring
default-deny/allow-exceptionally ability into static
network filtering arsenal. Example of usage:
*$3p,script, \
denyallow=x.com|y.com \
domain=a.com|b.com
The above filter tells the network filtering engine that
when the context is `a.com` or `b.com`, block all
3rd-party scripts except those from `x.com` and `y.com`.
Essentially, the new `denyallow` option makes it easier
to implement default-deny/allow-exceptionally in static
filter lists, whereas before this had to be done with
unwieldy regular expressions[1], or through the mix of
broadly blocking filters along with exception filters[2].
[1] https://hg.adblockplus.org/ruadlist/rev/f362910bc9a0
[2] Typically filters which pattern are of the
form `|http*://`
2020-03-15 17:23:25 +01:00
|
|
|
}
|
2021-07-12 17:55:58 +02:00
|
|
|
// Evaluated on-demand
|
|
|
|
// - 0b01: specific cosmetic filtering
|
|
|
|
// - 0b10: generic cosmetic filtering
|
|
|
|
this._cosmeticFilteringBits = undefined;
|
2018-12-21 20:16:17 +01:00
|
|
|
return this;
|
2019-07-05 23:44:08 +02:00
|
|
|
}
|
2018-12-21 20:16:17 +01:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
dispose() {
|
Add support for `cname` type and `denyallow` option
This concerns the static network filtering engine.
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/943
* * *
New static network filter type: `cname`
By default, network requests which are result of
resolving a canonical name are subject to filtering.
This filtering can be bypassed by creating exception
filters using the `cname` option. For example:
@@*$cname
The filter above tells the network filtering engine
to except network requests which fulfill all the
following conditions:
- network request is blocked
- network request is that of an unaliased hostname
Filter list authors are discouraged from using
exception filters of `cname` type, unless there no
other practical solution such that maintenance
burden become the greater issue. Of course, such
exception filters should be as narrow as possible,
i.e. apply to specific domain, etc.
* * *
New static network filter option: `denyallow`
The purpose of `denyallow` is bring
default-deny/allow-exceptionally ability into static
network filtering arsenal. Example of usage:
*$3p,script, \
denyallow=x.com|y.com \
domain=a.com|b.com
The above filter tells the network filtering engine that
when the context is `a.com` or `b.com`, block all
3rd-party scripts except those from `x.com` and `y.com`.
Essentially, the new `denyallow` option makes it easier
to implement default-deny/allow-exceptionally in static
filter lists, whereas before this had to be done with
unwieldy regular expressions[1], or through the mix of
broadly blocking filters along with exception filters[2].
[1] https://hg.adblockplus.org/ruadlist/rev/f362910bc9a0
[2] Typically filters which pattern are of the
form `|http*://`
2020-03-15 17:23:25 +01:00
|
|
|
this.rawURL = this.hostname = this.domain = '';
|
2021-02-15 12:52:31 +01:00
|
|
|
if ( FrameStore.junkyard.length < FrameStore.junkyardMax ) {
|
|
|
|
FrameStore.junkyard.push(this);
|
2018-12-21 20:16:17 +01:00
|
|
|
}
|
|
|
|
return null;
|
2019-07-05 23:44:08 +02:00
|
|
|
}
|
2014-07-30 07:05:35 +02:00
|
|
|
|
2021-07-12 17:55:58 +02:00
|
|
|
getCosmeticFilteringBits(tabId) {
|
|
|
|
if ( this._cosmeticFilteringBits !== undefined ) {
|
|
|
|
return this._cosmeticFilteringBits;
|
|
|
|
}
|
|
|
|
this._cosmeticFilteringBits = 0b11;
|
|
|
|
{
|
2021-07-25 16:55:35 +02:00
|
|
|
const result = µb.staticNetFilteringEngine.matchRequestReverse(
|
2021-07-12 17:55:58 +02:00
|
|
|
'specifichide',
|
|
|
|
this.rawURL
|
|
|
|
);
|
|
|
|
if ( result !== 0 && µb.logger.enabled ) {
|
|
|
|
µBlock.filteringContext
|
|
|
|
.duplicate()
|
|
|
|
.fromTabId(tabId)
|
|
|
|
.setURL(this.rawURL)
|
|
|
|
.setRealm('network')
|
|
|
|
.setType('specifichide')
|
|
|
|
.setFilter(µb.staticNetFilteringEngine.toLogData())
|
|
|
|
.toLogger();
|
|
|
|
}
|
|
|
|
if ( result === 2 ) {
|
|
|
|
this._cosmeticFilteringBits &= ~0b01;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
{
|
2021-07-25 16:55:35 +02:00
|
|
|
const result = µb.staticNetFilteringEngine.matchRequestReverse(
|
2021-07-12 17:55:58 +02:00
|
|
|
'generichide',
|
|
|
|
this.rawURL
|
|
|
|
);
|
|
|
|
if ( result !== 0 && µb.logger.enabled ) {
|
|
|
|
µBlock.filteringContext
|
|
|
|
.duplicate()
|
|
|
|
.fromTabId(tabId)
|
|
|
|
.setURL(this.rawURL)
|
|
|
|
.setRealm('network')
|
|
|
|
.setType('generichide')
|
|
|
|
.setFilter(µb.staticNetFilteringEngine.toLogData())
|
|
|
|
.toLogger();
|
|
|
|
}
|
|
|
|
if ( result === 2 ) {
|
|
|
|
this._cosmeticFilteringBits &= ~0b10;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return this._cosmeticFilteringBits;
|
|
|
|
}
|
|
|
|
|
|
|
|
shouldApplySpecificCosmeticFilters(tabId) {
|
|
|
|
return (this.getCosmeticFilteringBits(tabId) & 0b01) !== 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
shouldApplyGenericCosmeticFilters(tabId) {
|
|
|
|
return (this.getCosmeticFilteringBits(tabId) & 0b10) !== 0;
|
|
|
|
}
|
|
|
|
|
2021-01-10 17:56:27 +01:00
|
|
|
static factory(frameURL, parentId = -1) {
|
2021-02-15 12:52:31 +01:00
|
|
|
const entry = FrameStore.junkyard.pop();
|
2019-07-05 23:44:08 +02:00
|
|
|
if ( entry === undefined ) {
|
2021-01-10 17:56:27 +01:00
|
|
|
return new FrameStore(frameURL, parentId);
|
2019-07-05 23:44:08 +02:00
|
|
|
}
|
2021-01-10 17:56:27 +01:00
|
|
|
return entry.init(frameURL, parentId);
|
2014-09-14 22:20:40 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2021-02-15 12:52:31 +01:00
|
|
|
// To mitigate memory churning
|
|
|
|
FrameStore.junkyard = [];
|
|
|
|
FrameStore.junkyardMax = 50;
|
|
|
|
|
2014-07-30 07:05:35 +02:00
|
|
|
/******************************************************************************/
|
|
|
|
|
2021-02-15 12:52:31 +01:00
|
|
|
const CountDetails = class {
|
|
|
|
constructor() {
|
|
|
|
this.allowed = { any: 0, frame: 0, script: 0 };
|
|
|
|
this.blocked = { any: 0, frame: 0, script: 0 };
|
|
|
|
}
|
|
|
|
reset() {
|
|
|
|
const { allowed, blocked } = this;
|
|
|
|
blocked.any = blocked.frame = blocked.script =
|
|
|
|
allowed.any = allowed.frame = allowed.script = 0;
|
|
|
|
}
|
|
|
|
inc(blocked, type = undefined) {
|
|
|
|
const stat = blocked ? this.blocked : this.allowed;
|
|
|
|
if ( type !== undefined ) { stat[type] += 1; }
|
|
|
|
stat.any += 1;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const HostnameDetails = class {
|
|
|
|
constructor(hostname) {
|
|
|
|
this.counts = new CountDetails();
|
|
|
|
this.init(hostname);
|
|
|
|
}
|
|
|
|
init(hostname) {
|
|
|
|
this.hostname = hostname;
|
|
|
|
this.counts.reset();
|
|
|
|
}
|
|
|
|
dispose() {
|
|
|
|
this.hostname = '';
|
|
|
|
if ( HostnameDetails.junkyard.length < HostnameDetails.junkyardMax ) {
|
|
|
|
HostnameDetails.junkyard.push(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
HostnameDetails.junkyard = [];
|
|
|
|
HostnameDetails.junkyardMax = 100;
|
|
|
|
|
|
|
|
const HostnameDetailsMap = class extends Map {
|
|
|
|
reset() {
|
|
|
|
this.clear();
|
|
|
|
}
|
|
|
|
dispose() {
|
|
|
|
for ( const item of this.values() ) {
|
|
|
|
item.dispose();
|
|
|
|
}
|
|
|
|
this.reset();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/******************************************************************************/
|
2014-09-14 22:20:40 +02:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
const PageStore = class {
|
2021-07-16 14:59:30 +02:00
|
|
|
constructor(tabId, details) {
|
2019-07-05 23:44:08 +02:00
|
|
|
this.extraData = new Map();
|
|
|
|
this.journal = [];
|
2021-01-02 17:52:16 +01:00
|
|
|
this.journalTimer = undefined;
|
|
|
|
this.journalLastCommitted = this.journalLastUncommitted = -1;
|
|
|
|
this.journalLastUncommittedOrigin = undefined;
|
2019-09-21 22:42:15 +02:00
|
|
|
this.netFilteringCache = NetFilteringResultCache.factory();
|
2021-02-15 12:52:31 +01:00
|
|
|
this.hostnameDetailsMap = new HostnameDetailsMap();
|
|
|
|
this.counts = new CountDetails();
|
2021-07-16 14:59:30 +02:00
|
|
|
this.init(tabId, details);
|
2014-09-14 22:20:40 +02:00
|
|
|
}
|
|
|
|
|
2021-07-16 14:59:30 +02:00
|
|
|
static factory(tabId, details) {
|
2021-02-15 12:52:31 +01:00
|
|
|
let entry = PageStore.junkyard.pop();
|
2019-07-05 23:44:08 +02:00
|
|
|
if ( entry === undefined ) {
|
2021-07-16 14:59:30 +02:00
|
|
|
entry = new PageStore(tabId, details);
|
2019-07-05 23:44:08 +02:00
|
|
|
} else {
|
2021-07-16 14:59:30 +02:00
|
|
|
entry.init(tabId, details);
|
2019-07-05 23:44:08 +02:00
|
|
|
}
|
|
|
|
return entry;
|
|
|
|
}
|
2014-09-14 22:20:40 +02:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
// https://github.com/gorhill/uBlock/issues/3201
|
|
|
|
// The context is used to determine whether we report behavior change
|
|
|
|
// to the logger.
|
2017-11-07 17:31:19 +01:00
|
|
|
|
2021-07-16 14:59:30 +02:00
|
|
|
init(tabId, details) {
|
2019-07-05 23:44:08 +02:00
|
|
|
const tabContext = µb.tabContextManager.mustLookup(tabId);
|
|
|
|
this.tabId = tabId;
|
2016-01-17 19:30:43 +01:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
// If we are navigating from-to same site, remember whether large
|
|
|
|
// media elements were temporarily allowed.
|
|
|
|
if (
|
|
|
|
typeof this.allowLargeMediaElementsUntil !== 'number' ||
|
|
|
|
tabContext.rootHostname !== this.tabHostname
|
|
|
|
) {
|
2020-10-18 16:07:46 +02:00
|
|
|
this.allowLargeMediaElementsUntil = Date.now();
|
2019-07-05 23:44:08 +02:00
|
|
|
}
|
2016-01-17 19:30:43 +01:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
this.tabHostname = tabContext.rootHostname;
|
|
|
|
this.rawURL = tabContext.rawURL;
|
2021-02-15 12:52:31 +01:00
|
|
|
this.hostnameDetailsMap.reset();
|
2019-07-05 23:44:08 +02:00
|
|
|
this.contentLastModified = 0;
|
|
|
|
this.logData = undefined;
|
2021-02-15 12:52:31 +01:00
|
|
|
this.counts.reset();
|
2019-07-05 23:44:08 +02:00
|
|
|
this.remoteFontCount = 0;
|
|
|
|
this.popupBlockedCount = 0;
|
|
|
|
this.largeMediaCount = 0;
|
|
|
|
this.largeMediaTimer = null;
|
2020-10-18 16:07:46 +02:00
|
|
|
this.allowLargeMediaElementsRegex = undefined;
|
2019-07-05 23:44:08 +02:00
|
|
|
this.extraData.clear();
|
|
|
|
|
2020-07-19 15:01:45 +02:00
|
|
|
this.frameAddCount = 0;
|
Add support for `cname` type and `denyallow` option
This concerns the static network filtering engine.
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/943
* * *
New static network filter type: `cname`
By default, network requests which are result of
resolving a canonical name are subject to filtering.
This filtering can be bypassed by creating exception
filters using the `cname` option. For example:
@@*$cname
The filter above tells the network filtering engine
to except network requests which fulfill all the
following conditions:
- network request is blocked
- network request is that of an unaliased hostname
Filter list authors are discouraged from using
exception filters of `cname` type, unless there no
other practical solution such that maintenance
burden become the greater issue. Of course, such
exception filters should be as narrow as possible,
i.e. apply to specific domain, etc.
* * *
New static network filter option: `denyallow`
The purpose of `denyallow` is bring
default-deny/allow-exceptionally ability into static
network filtering arsenal. Example of usage:
*$3p,script, \
denyallow=x.com|y.com \
domain=a.com|b.com
The above filter tells the network filtering engine that
when the context is `a.com` or `b.com`, block all
3rd-party scripts except those from `x.com` and `y.com`.
Essentially, the new `denyallow` option makes it easier
to implement default-deny/allow-exceptionally in static
filter lists, whereas before this had to be done with
unwieldy regular expressions[1], or through the mix of
broadly blocking filters along with exception filters[2].
[1] https://hg.adblockplus.org/ruadlist/rev/f362910bc9a0
[2] Typically filters which pattern are of the
form `|http*://`
2020-03-15 17:23:25 +01:00
|
|
|
this.frames = new Map();
|
2021-01-10 17:56:27 +01:00
|
|
|
this.setFrameURL({ url: tabContext.rawURL });
|
Add support for `cname` type and `denyallow` option
This concerns the static network filtering engine.
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/943
* * *
New static network filter type: `cname`
By default, network requests which are result of
resolving a canonical name are subject to filtering.
This filtering can be bypassed by creating exception
filters using the `cname` option. For example:
@@*$cname
The filter above tells the network filtering engine
to except network requests which fulfill all the
following conditions:
- network request is blocked
- network request is that of an unaliased hostname
Filter list authors are discouraged from using
exception filters of `cname` type, unless there no
other practical solution such that maintenance
burden become the greater issue. Of course, such
exception filters should be as narrow as possible,
i.e. apply to specific domain, etc.
* * *
New static network filter option: `denyallow`
The purpose of `denyallow` is bring
default-deny/allow-exceptionally ability into static
network filtering arsenal. Example of usage:
*$3p,script, \
denyallow=x.com|y.com \
domain=a.com|b.com
The above filter tells the network filtering engine that
when the context is `a.com` or `b.com`, block all
3rd-party scripts except those from `x.com` and `y.com`.
Essentially, the new `denyallow` option makes it easier
to implement default-deny/allow-exceptionally in static
filter lists, whereas before this had to be done with
unwieldy regular expressions[1], or through the mix of
broadly blocking filters along with exception filters[2].
[1] https://hg.adblockplus.org/ruadlist/rev/f362910bc9a0
[2] Typically filters which pattern are of the
form `|http*://`
2020-03-15 17:23:25 +01:00
|
|
|
|
2021-07-16 14:59:30 +02:00
|
|
|
if ( this.titleFromDetails(details) === false ) {
|
|
|
|
this.title = tabContext.rawURL;
|
|
|
|
}
|
|
|
|
|
2021-07-12 17:55:58 +02:00
|
|
|
// Evaluated on-demand
|
|
|
|
this._noCosmeticFiltering = undefined;
|
2015-03-26 00:28:22 +01:00
|
|
|
|
2014-10-02 22:45:26 +02:00
|
|
|
return this;
|
|
|
|
}
|
2015-04-09 00:46:08 +02:00
|
|
|
|
2021-07-16 14:59:30 +02:00
|
|
|
reuse(context, details) {
|
2019-07-05 23:44:08 +02:00
|
|
|
// When force refreshing a page, the page store data needs to be reset.
|
2014-06-24 00:42:43 +02:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
// If the hostname changes, we can't merely just update the context.
|
|
|
|
const tabContext = µb.tabContextManager.mustLookup(this.tabId);
|
|
|
|
if ( tabContext.rootHostname !== this.tabHostname ) {
|
|
|
|
context = '';
|
|
|
|
}
|
2014-09-14 22:20:40 +02:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
// If URL changes without a page reload (more and more common), then
|
|
|
|
// we need to keep all that we collected for reuse. In particular,
|
|
|
|
// not doing so was causing a problem in `videos.foxnews.com`:
|
|
|
|
// clicking a video thumbnail would not work, because the frame
|
|
|
|
// hierarchy structure was flushed from memory, while not really being
|
|
|
|
// flushed on the page.
|
|
|
|
if ( context === 'tabUpdated' ) {
|
|
|
|
// As part of https://github.com/chrisaljoudi/uBlock/issues/405
|
|
|
|
// URL changed, force a re-evaluation of filtering switch
|
|
|
|
this.rawURL = tabContext.rawURL;
|
2021-01-10 17:56:27 +01:00
|
|
|
this.setFrameURL({ url: this.rawURL });
|
2021-07-16 14:59:30 +02:00
|
|
|
this.titleFromDetails(details);
|
2019-07-05 23:44:08 +02:00
|
|
|
return this;
|
|
|
|
}
|
2014-06-24 00:42:43 +02:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
// A new page is completely reloaded from scratch, reset all.
|
|
|
|
if ( this.largeMediaTimer !== null ) {
|
|
|
|
clearTimeout(this.largeMediaTimer);
|
|
|
|
this.largeMediaTimer = null;
|
|
|
|
}
|
|
|
|
this.disposeFrameStores();
|
2021-07-16 14:59:30 +02:00
|
|
|
this.init(this.tabId, details);
|
2019-07-05 23:44:08 +02:00
|
|
|
return this;
|
2014-06-24 00:42:43 +02:00
|
|
|
}
|
2014-09-14 22:20:40 +02:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
dispose() {
|
|
|
|
this.tabHostname = '';
|
|
|
|
this.title = '';
|
|
|
|
this.rawURL = '';
|
2021-02-15 12:52:31 +01:00
|
|
|
this.hostnameDetailsMap.dispose();
|
2019-09-21 22:42:15 +02:00
|
|
|
this.netFilteringCache.empty();
|
2020-10-18 16:07:46 +02:00
|
|
|
this.allowLargeMediaElementsUntil = Date.now();
|
|
|
|
this.allowLargeMediaElementsRegex = undefined;
|
2019-07-05 23:44:08 +02:00
|
|
|
if ( this.largeMediaTimer !== null ) {
|
|
|
|
clearTimeout(this.largeMediaTimer);
|
|
|
|
this.largeMediaTimer = null;
|
|
|
|
}
|
|
|
|
this.disposeFrameStores();
|
2021-01-02 17:52:16 +01:00
|
|
|
if ( this.journalTimer !== undefined ) {
|
2019-07-05 23:44:08 +02:00
|
|
|
clearTimeout(this.journalTimer);
|
2021-01-02 17:52:16 +01:00
|
|
|
this.journalTimer = undefined;
|
2019-07-05 23:44:08 +02:00
|
|
|
}
|
|
|
|
this.journal = [];
|
2021-01-02 17:52:16 +01:00
|
|
|
this.journalLastUncommittedOrigin = undefined;
|
2021-01-02 18:07:31 +01:00
|
|
|
this.journalLastCommitted = this.journalLastUncommitted = -1;
|
2021-02-15 12:52:31 +01:00
|
|
|
if ( PageStore.junkyard.length < PageStore.junkyardMax ) {
|
|
|
|
PageStore.junkyard.push(this);
|
2019-07-05 23:44:08 +02:00
|
|
|
}
|
|
|
|
return null;
|
2014-09-14 22:20:40 +02:00
|
|
|
}
|
2014-07-30 07:05:35 +02:00
|
|
|
|
2021-07-16 14:59:30 +02:00
|
|
|
titleFromDetails(details) {
|
2021-07-16 20:06:59 +02:00
|
|
|
if (
|
|
|
|
details instanceof Object === false ||
|
|
|
|
details.title === undefined
|
|
|
|
) {
|
|
|
|
return false;
|
2021-07-16 14:59:30 +02:00
|
|
|
}
|
2021-07-16 20:06:59 +02:00
|
|
|
this.title = µb.orphanizeString(details.title.slice(0, 128));
|
|
|
|
return true;
|
2021-07-16 14:59:30 +02:00
|
|
|
}
|
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
disposeFrameStores() {
|
|
|
|
for ( const frameStore of this.frames.values() ) {
|
|
|
|
frameStore.dispose();
|
|
|
|
}
|
|
|
|
this.frames.clear();
|
2015-02-25 20:15:36 +01:00
|
|
|
}
|
2014-07-30 07:05:35 +02:00
|
|
|
|
2020-10-09 19:50:54 +02:00
|
|
|
getFrameStore(frameId) {
|
2019-07-05 23:44:08 +02:00
|
|
|
return this.frames.get(frameId) || null;
|
|
|
|
}
|
2014-07-30 07:05:35 +02:00
|
|
|
|
2021-01-10 17:56:27 +01:00
|
|
|
setFrameURL(details) {
|
|
|
|
let { frameId, url, parentFrameId } = details;
|
|
|
|
if ( frameId === undefined ) { frameId = 0; }
|
|
|
|
if ( parentFrameId === undefined ) { parentFrameId = -1; }
|
2020-10-09 19:50:54 +02:00
|
|
|
let frameStore = this.frames.get(frameId);
|
2019-07-05 23:44:08 +02:00
|
|
|
if ( frameStore !== undefined ) {
|
2021-01-10 17:56:27 +01:00
|
|
|
if ( url === frameStore.rawURL ) {
|
|
|
|
frameStore.parentId = parentFrameId;
|
|
|
|
} else {
|
|
|
|
frameStore.init(url, parentFrameId);
|
|
|
|
}
|
|
|
|
return frameStore;
|
2020-12-09 14:16:28 +01:00
|
|
|
}
|
2021-01-10 17:56:27 +01:00
|
|
|
frameStore = FrameStore.factory(url, parentFrameId);
|
2020-12-09 14:16:28 +01:00
|
|
|
this.frames.set(frameId, frameStore);
|
|
|
|
this.frameAddCount += 1;
|
|
|
|
if ( (this.frameAddCount & 0b111111) === 0 ) {
|
|
|
|
this.pruneFrames();
|
2020-07-18 13:44:26 +02:00
|
|
|
}
|
2020-10-09 19:50:54 +02:00
|
|
|
return frameStore;
|
2020-07-18 13:44:26 +02:00
|
|
|
}
|
|
|
|
|
2021-01-10 17:56:27 +01:00
|
|
|
getEffectiveFrameURL(sender) {
|
|
|
|
let { frameId } = sender;
|
|
|
|
for (;;) {
|
|
|
|
const frameStore = this.getFrameStore(frameId);
|
|
|
|
if ( frameStore === null ) { break; }
|
|
|
|
if ( frameStore.rawURL.startsWith('about:') === false ) {
|
|
|
|
return frameStore.rawURL;
|
|
|
|
}
|
|
|
|
frameId = frameStore.parentId;
|
|
|
|
if ( frameId === -1 ) { break; }
|
|
|
|
}
|
|
|
|
return sender.frameURL;
|
|
|
|
}
|
|
|
|
|
2020-07-18 13:44:26 +02:00
|
|
|
// There is no event to tell us a specific subframe has been removed from
|
|
|
|
// the main document. The code below will remove subframes which are no
|
|
|
|
// longer present in the root document. Removing obsolete subframes is
|
|
|
|
// not a critical task, so this is executed just once on a while, to avoid
|
|
|
|
// bloated dictionary of subframes.
|
|
|
|
// A TTL is used to avoid race conditions when new iframes are added
|
|
|
|
// through the webRequest API but still not yet visible through the
|
|
|
|
// webNavigation API.
|
|
|
|
async pruneFrames() {
|
|
|
|
let entries;
|
|
|
|
try {
|
|
|
|
entries = await webext.webNavigation.getAllFrames({
|
|
|
|
tabId: this.tabId
|
|
|
|
});
|
|
|
|
} catch(ex) {
|
|
|
|
}
|
|
|
|
if ( Array.isArray(entries) === false ) { return; }
|
|
|
|
const toKeep = new Set();
|
|
|
|
for ( const { frameId } of entries ) {
|
|
|
|
toKeep.add(frameId);
|
|
|
|
}
|
|
|
|
const obsolete = Date.now() - 60000;
|
|
|
|
for ( const [ frameId, { t0 } ] of this.frames ) {
|
|
|
|
if ( toKeep.has(frameId) || t0 >= obsolete ) { continue; }
|
|
|
|
this.frames.delete(frameId);
|
2019-07-05 23:44:08 +02:00
|
|
|
}
|
|
|
|
}
|
2014-08-02 17:40:27 +02:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
getNetFilteringSwitch() {
|
|
|
|
return µb.tabContextManager
|
|
|
|
.mustLookup(this.tabId)
|
|
|
|
.getNetFilteringSwitch();
|
|
|
|
}
|
2015-02-06 05:14:12 +01:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
toggleNetFilteringSwitch(url, scope, state) {
|
|
|
|
µb.toggleNetFilteringSwitch(url, scope, state);
|
|
|
|
this.netFilteringCache.empty();
|
|
|
|
}
|
2015-01-22 03:46:11 +01:00
|
|
|
|
2021-07-12 17:55:58 +02:00
|
|
|
shouldApplyCosmeticFilters(frameId = 0) {
|
|
|
|
if ( this._noCosmeticFiltering === undefined ) {
|
|
|
|
this._noCosmeticFiltering = this.getNetFilteringSwitch() === false;
|
|
|
|
if ( this._noCosmeticFiltering === false ) {
|
|
|
|
this._noCosmeticFiltering = µb.sessionSwitches.evaluateZ(
|
|
|
|
'no-cosmetic-filtering',
|
|
|
|
this.tabHostname
|
|
|
|
) === true;
|
|
|
|
if ( this._noCosmeticFiltering && µb.logger.enabled ) {
|
|
|
|
µb.filteringContext
|
|
|
|
.duplicate()
|
|
|
|
.fromTabId(this.tabId)
|
|
|
|
.setURL(this.rawURL)
|
|
|
|
.setRealm('cosmetic')
|
|
|
|
.setType('dom')
|
|
|
|
.setFilter(µb.sessionSwitches.toLogData())
|
|
|
|
.toLogger();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( this._noCosmeticFiltering ) { return false; }
|
|
|
|
if ( frameId === -1 ) { return true; }
|
|
|
|
// Cosmetic filtering can be effectively disabled when both specific
|
|
|
|
// and generic cosmetic filters are disabled.
|
|
|
|
return this.shouldApplySpecificCosmeticFilters(frameId) ||
|
|
|
|
this.shouldApplyGenericCosmeticFilters(frameId);
|
|
|
|
}
|
|
|
|
|
|
|
|
shouldApplySpecificCosmeticFilters(frameId) {
|
|
|
|
if ( this.shouldApplyCosmeticFilters(-1) === false ) { return false; }
|
|
|
|
const frameStore = this.getFrameStore(frameId);
|
|
|
|
if ( frameStore === null ) { return false; }
|
|
|
|
return frameStore.shouldApplySpecificCosmeticFilters(this.tabId);
|
|
|
|
}
|
|
|
|
|
|
|
|
shouldApplyGenericCosmeticFilters(frameId) {
|
|
|
|
if ( this.shouldApplyCosmeticFilters(-1) === false ) { return false; }
|
|
|
|
const frameStore = this.getFrameStore(frameId);
|
|
|
|
if ( frameStore === null ) { return false; }
|
|
|
|
return frameStore.shouldApplyGenericCosmeticFilters(this.tabId);
|
|
|
|
}
|
|
|
|
|
2021-02-15 12:52:31 +01:00
|
|
|
// https://github.com/gorhill/uBlock/issues/2105
|
|
|
|
// Be sure to always include the current page's hostname -- it might not
|
|
|
|
// be present when the page itself is pulled from the browser's
|
|
|
|
// short-term memory cache.
|
|
|
|
getAllHostnameDetails() {
|
|
|
|
if (
|
|
|
|
this.hostnameDetailsMap.has(this.tabHostname) === false &&
|
2021-07-25 16:55:35 +02:00
|
|
|
isNetworkURI(this.rawURL)
|
2021-02-15 12:52:31 +01:00
|
|
|
) {
|
|
|
|
this.hostnameDetailsMap.set(
|
|
|
|
this.tabHostname,
|
|
|
|
new HostnameDetails(this.tabHostname)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return this.hostnameDetailsMap;
|
|
|
|
}
|
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
injectLargeMediaElementScriptlet() {
|
2019-09-16 22:17:48 +02:00
|
|
|
vAPI.tabs.executeScript(this.tabId, {
|
2019-07-05 23:44:08 +02:00
|
|
|
file: '/js/scriptlets/load-large-media-interactive.js',
|
|
|
|
allFrames: true,
|
|
|
|
runAt: 'document_idle',
|
|
|
|
});
|
|
|
|
µb.contextMenu.update(this.tabId);
|
|
|
|
}
|
2016-01-17 19:30:43 +01:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
temporarilyAllowLargeMediaElements(state) {
|
|
|
|
this.largeMediaCount = 0;
|
|
|
|
µb.contextMenu.update(this.tabId);
|
2020-10-18 16:07:46 +02:00
|
|
|
if ( state ) {
|
|
|
|
this.allowLargeMediaElementsUntil = 0;
|
|
|
|
this.allowLargeMediaElementsRegex = undefined;
|
|
|
|
} else {
|
|
|
|
this.allowLargeMediaElementsUntil = Date.now();
|
|
|
|
}
|
2019-07-05 23:44:08 +02:00
|
|
|
µb.scriptlets.injectDeep(this.tabId, 'load-large-media-all');
|
|
|
|
}
|
2016-01-17 19:30:43 +01:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
// https://github.com/gorhill/uBlock/issues/2053
|
|
|
|
// There is no way around using journaling to ensure we deal properly with
|
|
|
|
// potentially out of order navigation events vs. network request events.
|
2021-02-15 12:52:31 +01:00
|
|
|
journalAddRequest(fctxt, result) {
|
|
|
|
const hostname = fctxt.getHostname();
|
2019-07-05 23:44:08 +02:00
|
|
|
if ( hostname === '' ) { return; }
|
2021-02-15 12:52:31 +01:00
|
|
|
this.journal.push(hostname, result, fctxt.itype);
|
|
|
|
if ( this.journalTimer !== undefined ) { return; }
|
|
|
|
this.journalTimer = vAPI.setTimeout(
|
|
|
|
( ) => { this.journalProcess(true); },
|
|
|
|
µb.hiddenSettings.requestJournalProcessPeriod
|
2019-07-05 23:44:08 +02:00
|
|
|
);
|
|
|
|
}
|
2016-01-17 19:30:43 +01:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
journalAddRootFrame(type, url) {
|
|
|
|
if ( type === 'committed' ) {
|
|
|
|
this.journalLastCommitted = this.journal.length;
|
|
|
|
if (
|
2021-01-02 17:52:16 +01:00
|
|
|
this.journalLastUncommitted !== -1 &&
|
2019-07-05 23:44:08 +02:00
|
|
|
this.journalLastUncommitted < this.journalLastCommitted &&
|
2021-07-25 16:55:35 +02:00
|
|
|
this.journalLastUncommittedOrigin === hostnameFromURI(url)
|
2019-07-05 23:44:08 +02:00
|
|
|
) {
|
|
|
|
this.journalLastCommitted = this.journalLastUncommitted;
|
|
|
|
}
|
|
|
|
} else if ( type === 'uncommitted' ) {
|
2021-07-25 16:55:35 +02:00
|
|
|
const newOrigin = hostnameFromURI(url);
|
2021-01-02 17:52:16 +01:00
|
|
|
if (
|
|
|
|
this.journalLastUncommitted === -1 ||
|
|
|
|
this.journalLastUncommittedOrigin !== newOrigin
|
|
|
|
) {
|
|
|
|
this.journalLastUncommitted = this.journal.length;
|
|
|
|
this.journalLastUncommittedOrigin = newOrigin;
|
|
|
|
}
|
2019-07-05 23:44:08 +02:00
|
|
|
}
|
2021-01-02 17:52:16 +01:00
|
|
|
if ( this.journalTimer !== undefined ) {
|
2019-07-05 23:44:08 +02:00
|
|
|
clearTimeout(this.journalTimer);
|
|
|
|
}
|
2018-09-01 00:47:02 +02:00
|
|
|
this.journalTimer = vAPI.setTimeout(
|
|
|
|
( ) => { this.journalProcess(true); },
|
|
|
|
µb.hiddenSettings.requestJournalProcessPeriod
|
|
|
|
);
|
2016-10-08 16:15:31 +02:00
|
|
|
}
|
|
|
|
|
2021-01-02 17:52:16 +01:00
|
|
|
journalProcess(fromTimer = false) {
|
|
|
|
if ( fromTimer === false ) { clearTimeout(this.journalTimer); }
|
|
|
|
this.journalTimer = undefined;
|
2016-10-08 16:15:31 +02:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
const journal = this.journal;
|
2021-01-02 18:41:13 +01:00
|
|
|
const pivot = Math.max(0, this.journalLastCommitted);
|
2019-07-05 23:44:08 +02:00
|
|
|
const now = Date.now();
|
2021-02-15 12:52:31 +01:00
|
|
|
const { SCRIPT, SUB_FRAME } = µb.FilteringContext;
|
|
|
|
let aggregateAllowed = 0;
|
|
|
|
let aggregateBlocked = 0;
|
2019-07-05 23:44:08 +02:00
|
|
|
|
|
|
|
// Everything after pivot originates from current page.
|
2021-02-15 12:52:31 +01:00
|
|
|
for ( let i = pivot; i < journal.length; i += 3 ) {
|
|
|
|
const hostname = journal[i+0];
|
|
|
|
let hnDetails = this.hostnameDetailsMap.get(hostname);
|
|
|
|
if ( hnDetails === undefined ) {
|
|
|
|
hnDetails = new HostnameDetails(hostname);
|
|
|
|
this.hostnameDetailsMap.set(hostname, hnDetails);
|
2019-07-05 23:44:08 +02:00
|
|
|
this.contentLastModified = now;
|
|
|
|
}
|
2021-02-15 12:52:31 +01:00
|
|
|
const blocked = journal[i+1] === 1;
|
|
|
|
const itype = journal[i+2];
|
|
|
|
if ( itype === SCRIPT ) {
|
|
|
|
hnDetails.counts.inc(blocked, 'script');
|
|
|
|
this.counts.inc(blocked, 'script');
|
|
|
|
} else if ( itype === SUB_FRAME ) {
|
|
|
|
hnDetails.counts.inc(blocked, 'frame');
|
|
|
|
this.counts.inc(blocked, 'frame');
|
|
|
|
} else {
|
|
|
|
hnDetails.counts.inc(blocked);
|
|
|
|
this.counts.inc(blocked);
|
|
|
|
}
|
|
|
|
if ( blocked ) {
|
|
|
|
aggregateBlocked += 1;
|
|
|
|
} else {
|
|
|
|
aggregateAllowed += 1;
|
|
|
|
}
|
2019-07-05 23:44:08 +02:00
|
|
|
}
|
2021-01-02 17:52:16 +01:00
|
|
|
this.journalLastUncommitted = this.journalLastCommitted = -1;
|
2019-07-05 23:44:08 +02:00
|
|
|
|
|
|
|
// https://github.com/chrisaljoudi/uBlock/issues/905#issuecomment-76543649
|
|
|
|
// No point updating the badge if it's not being displayed.
|
2021-02-15 12:52:31 +01:00
|
|
|
if ( aggregateBlocked !== 0 && µb.userSettings.showIconBadge ) {
|
2019-07-05 23:44:08 +02:00
|
|
|
µb.updateToolbarIcon(this.tabId, 0x02);
|
2016-10-08 16:15:31 +02:00
|
|
|
}
|
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
// Everything before pivot does not originate from current page -- we
|
|
|
|
// still need to bump global blocked/allowed counts.
|
2021-02-15 12:52:31 +01:00
|
|
|
for ( let i = 0; i < pivot; i += 3 ) {
|
|
|
|
if ( journal[i+1] === 1 ) {
|
|
|
|
aggregateBlocked += 1;
|
|
|
|
} else {
|
|
|
|
aggregateAllowed += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( aggregateAllowed !== 0 || aggregateBlocked !== 0 ) {
|
|
|
|
µb.localSettings.blockedRequestCount += aggregateBlocked;
|
|
|
|
µb.localSettings.allowedRequestCount += aggregateAllowed;
|
2019-07-05 23:44:08 +02:00
|
|
|
µb.localSettingsLastModified = now;
|
|
|
|
}
|
|
|
|
journal.length = 0;
|
2016-10-08 16:15:31 +02:00
|
|
|
}
|
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
filterRequest(fctxt) {
|
|
|
|
fctxt.filter = undefined;
|
2020-11-10 16:43:26 +01:00
|
|
|
fctxt.redirectURL = undefined;
|
2017-05-12 16:35:11 +02:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
if ( this.getNetFilteringSwitch(fctxt) === false ) {
|
|
|
|
return 0;
|
|
|
|
}
|
2017-08-03 16:18:05 +02:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
if (
|
Add new filter option `queryprune=`
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/760
The purpose of this new network filter option is to remove
query parameters form the URL of network requests.
The name `queryprune` has been picked over `querystrip`
since the purpose of the option is to remove some
parameters from the URL rather than all parameters.
`queryprune` is a modifier option (like `csp`) in that it
does not cause a network request to be blocked but rather
modified before being emitted.
`queryprune` must be assigned a value, which value will
determine which parameters from a query string will be
removed. The syntax for the value is that of regular
expression *except* for the following rules:
- do not wrap the regex directive between `/`
- do not use regex special values `^` and `$`
- do not use literal comma character in the value,
though you can use hex-encoded version, `\x2c`
- to match the start of a query parameter, prepend `|`
- to match the end of a query parameter, append `|`
`queryprune` regex-like values will be tested against each
key-value parameter pair as `[key]=[value]` string. This
way you can prune according to either the key, the value,
or both.
This commit introduces the concept of modifier filter
options, which as of now are:
- `csp=`
- `queryprune=`
They both work in similar way when used with `important`
option or when used in exception filters. Modifier
options can apply to any network requests, hence the
logger reports the type of the network requests, and no
longer use the modifier as the type, i.e. `csp` filters
are no longer reported as requests of type `csp`.
Though modifier options can apply to any network requests,
for the time being the `csp=` modifier option still apply
only to top or embedded (frame) documents, just as before.
In some future we may want to apply `csp=` directives to
network requests of type script, to control the behavior
of service workers for example.
A new built-in filter expression has been added to the
logger: "modified", which allow to see all the network
requests which were modified before being emitted. The
translation work for this new option will be available
in a future commit.
2020-10-31 15:42:53 +01:00
|
|
|
fctxt.itype === fctxt.CSP_REPORT &&
|
2019-07-05 23:44:08 +02:00
|
|
|
this.filterCSPReport(fctxt) === 1
|
|
|
|
) {
|
|
|
|
return 1;
|
|
|
|
}
|
2016-10-14 16:06:34 +02:00
|
|
|
|
Add new filter option `queryprune=`
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/760
The purpose of this new network filter option is to remove
query parameters form the URL of network requests.
The name `queryprune` has been picked over `querystrip`
since the purpose of the option is to remove some
parameters from the URL rather than all parameters.
`queryprune` is a modifier option (like `csp`) in that it
does not cause a network request to be blocked but rather
modified before being emitted.
`queryprune` must be assigned a value, which value will
determine which parameters from a query string will be
removed. The syntax for the value is that of regular
expression *except* for the following rules:
- do not wrap the regex directive between `/`
- do not use regex special values `^` and `$`
- do not use literal comma character in the value,
though you can use hex-encoded version, `\x2c`
- to match the start of a query parameter, prepend `|`
- to match the end of a query parameter, append `|`
`queryprune` regex-like values will be tested against each
key-value parameter pair as `[key]=[value]` string. This
way you can prune according to either the key, the value,
or both.
This commit introduces the concept of modifier filter
options, which as of now are:
- `csp=`
- `queryprune=`
They both work in similar way when used with `important`
option or when used in exception filters. Modifier
options can apply to any network requests, hence the
logger reports the type of the network requests, and no
longer use the modifier as the type, i.e. `csp` filters
are no longer reported as requests of type `csp`.
Though modifier options can apply to any network requests,
for the time being the `csp=` modifier option still apply
only to top or embedded (frame) documents, just as before.
In some future we may want to apply `csp=` directives to
network requests of type script, to control the behavior
of service workers for example.
A new built-in filter expression has been added to the
logger: "modified", which allow to see all the network
requests which were modified before being emitted. The
translation work for this new option will be available
in a future commit.
2020-10-31 15:42:53 +01:00
|
|
|
if (
|
|
|
|
(fctxt.itype & fctxt.FONT_ANY) !== 0 &&
|
|
|
|
this.filterFont(fctxt) === 1 )
|
|
|
|
{
|
2019-07-05 23:44:08 +02:00
|
|
|
return 1;
|
|
|
|
}
|
2014-12-28 16:07:43 +01:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
if (
|
Add new filter option `queryprune=`
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/760
The purpose of this new network filter option is to remove
query parameters form the URL of network requests.
The name `queryprune` has been picked over `querystrip`
since the purpose of the option is to remove some
parameters from the URL rather than all parameters.
`queryprune` is a modifier option (like `csp`) in that it
does not cause a network request to be blocked but rather
modified before being emitted.
`queryprune` must be assigned a value, which value will
determine which parameters from a query string will be
removed. The syntax for the value is that of regular
expression *except* for the following rules:
- do not wrap the regex directive between `/`
- do not use regex special values `^` and `$`
- do not use literal comma character in the value,
though you can use hex-encoded version, `\x2c`
- to match the start of a query parameter, prepend `|`
- to match the end of a query parameter, append `|`
`queryprune` regex-like values will be tested against each
key-value parameter pair as `[key]=[value]` string. This
way you can prune according to either the key, the value,
or both.
This commit introduces the concept of modifier filter
options, which as of now are:
- `csp=`
- `queryprune=`
They both work in similar way when used with `important`
option or when used in exception filters. Modifier
options can apply to any network requests, hence the
logger reports the type of the network requests, and no
longer use the modifier as the type, i.e. `csp` filters
are no longer reported as requests of type `csp`.
Though modifier options can apply to any network requests,
for the time being the `csp=` modifier option still apply
only to top or embedded (frame) documents, just as before.
In some future we may want to apply `csp=` directives to
network requests of type script, to control the behavior
of service workers for example.
A new built-in filter expression has been added to the
logger: "modified", which allow to see all the network
requests which were modified before being emitted. The
translation work for this new option will be available
in a future commit.
2020-10-31 15:42:53 +01:00
|
|
|
fctxt.itype === fctxt.SCRIPT &&
|
2019-07-05 23:44:08 +02:00
|
|
|
this.filterScripting(fctxt, true) === 1
|
|
|
|
) {
|
|
|
|
return 1;
|
|
|
|
}
|
2018-09-01 00:47:02 +02:00
|
|
|
|
2021-01-22 15:37:12 +01:00
|
|
|
const cacheableResult =
|
|
|
|
this.cacheableResults.has(fctxt.itype) &&
|
|
|
|
fctxt.aliasURL === undefined;
|
2017-08-03 16:18:05 +02:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
if ( cacheableResult ) {
|
|
|
|
const entry = this.netFilteringCache.lookupResult(fctxt);
|
|
|
|
if ( entry !== undefined ) {
|
2020-10-10 14:36:30 +02:00
|
|
|
fctxt.redirectURL = entry.redirectURL;
|
2019-07-05 23:44:08 +02:00
|
|
|
fctxt.filter = entry.logData;
|
|
|
|
return entry.result;
|
|
|
|
}
|
2017-08-03 16:18:05 +02:00
|
|
|
}
|
2015-01-06 14:01:15 +01:00
|
|
|
|
Add new filter option `queryprune=`
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/760
The purpose of this new network filter option is to remove
query parameters form the URL of network requests.
The name `queryprune` has been picked over `querystrip`
since the purpose of the option is to remove some
parameters from the URL rather than all parameters.
`queryprune` is a modifier option (like `csp`) in that it
does not cause a network request to be blocked but rather
modified before being emitted.
`queryprune` must be assigned a value, which value will
determine which parameters from a query string will be
removed. The syntax for the value is that of regular
expression *except* for the following rules:
- do not wrap the regex directive between `/`
- do not use regex special values `^` and `$`
- do not use literal comma character in the value,
though you can use hex-encoded version, `\x2c`
- to match the start of a query parameter, prepend `|`
- to match the end of a query parameter, append `|`
`queryprune` regex-like values will be tested against each
key-value parameter pair as `[key]=[value]` string. This
way you can prune according to either the key, the value,
or both.
This commit introduces the concept of modifier filter
options, which as of now are:
- `csp=`
- `queryprune=`
They both work in similar way when used with `important`
option or when used in exception filters. Modifier
options can apply to any network requests, hence the
logger reports the type of the network requests, and no
longer use the modifier as the type, i.e. `csp` filters
are no longer reported as requests of type `csp`.
Though modifier options can apply to any network requests,
for the time being the `csp=` modifier option still apply
only to top or embedded (frame) documents, just as before.
In some future we may want to apply `csp=` directives to
network requests of type script, to control the behavior
of service workers for example.
A new built-in filter expression has been added to the
logger: "modified", which allow to see all the network
requests which were modified before being emitted. The
translation work for this new option will be available
in a future commit.
2020-10-31 15:42:53 +01:00
|
|
|
const requestType = fctxt.type;
|
|
|
|
const loggerEnabled = µb.logger.enabled;
|
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
// Dynamic URL filtering.
|
|
|
|
let result = µb.sessionURLFiltering.evaluateZ(
|
2018-12-13 18:30:54 +01:00
|
|
|
fctxt.getTabHostname(),
|
2019-07-05 23:44:08 +02:00
|
|
|
fctxt.url,
|
2018-12-13 18:30:54 +01:00
|
|
|
requestType
|
|
|
|
);
|
Add new filter option `queryprune=`
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/760
The purpose of this new network filter option is to remove
query parameters form the URL of network requests.
The name `queryprune` has been picked over `querystrip`
since the purpose of the option is to remove some
parameters from the URL rather than all parameters.
`queryprune` is a modifier option (like `csp`) in that it
does not cause a network request to be blocked but rather
modified before being emitted.
`queryprune` must be assigned a value, which value will
determine which parameters from a query string will be
removed. The syntax for the value is that of regular
expression *except* for the following rules:
- do not wrap the regex directive between `/`
- do not use regex special values `^` and `$`
- do not use literal comma character in the value,
though you can use hex-encoded version, `\x2c`
- to match the start of a query parameter, prepend `|`
- to match the end of a query parameter, append `|`
`queryprune` regex-like values will be tested against each
key-value parameter pair as `[key]=[value]` string. This
way you can prune according to either the key, the value,
or both.
This commit introduces the concept of modifier filter
options, which as of now are:
- `csp=`
- `queryprune=`
They both work in similar way when used with `important`
option or when used in exception filters. Modifier
options can apply to any network requests, hence the
logger reports the type of the network requests, and no
longer use the modifier as the type, i.e. `csp` filters
are no longer reported as requests of type `csp`.
Though modifier options can apply to any network requests,
for the time being the `csp=` modifier option still apply
only to top or embedded (frame) documents, just as before.
In some future we may want to apply `csp=` directives to
network requests of type script, to control the behavior
of service workers for example.
A new built-in filter expression has been added to the
logger: "modified", which allow to see all the network
requests which were modified before being emitted. The
translation work for this new option will be available
in a future commit.
2020-10-31 15:42:53 +01:00
|
|
|
if ( result !== 0 && loggerEnabled ) {
|
2019-07-05 23:44:08 +02:00
|
|
|
fctxt.filter = µb.sessionURLFiltering.toLogData();
|
2015-06-09 16:27:08 +02:00
|
|
|
}
|
2014-12-28 16:07:43 +01:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
// Dynamic hostname/type filtering.
|
|
|
|
if ( result === 0 && µb.userSettings.advancedUserEnabled ) {
|
|
|
|
result = µb.sessionFirewall.evaluateCellZY(
|
|
|
|
fctxt.getTabHostname(),
|
|
|
|
fctxt.getHostname(),
|
|
|
|
requestType
|
|
|
|
);
|
Add new filter option `queryprune=`
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/760
The purpose of this new network filter option is to remove
query parameters form the URL of network requests.
The name `queryprune` has been picked over `querystrip`
since the purpose of the option is to remove some
parameters from the URL rather than all parameters.
`queryprune` is a modifier option (like `csp`) in that it
does not cause a network request to be blocked but rather
modified before being emitted.
`queryprune` must be assigned a value, which value will
determine which parameters from a query string will be
removed. The syntax for the value is that of regular
expression *except* for the following rules:
- do not wrap the regex directive between `/`
- do not use regex special values `^` and `$`
- do not use literal comma character in the value,
though you can use hex-encoded version, `\x2c`
- to match the start of a query parameter, prepend `|`
- to match the end of a query parameter, append `|`
`queryprune` regex-like values will be tested against each
key-value parameter pair as `[key]=[value]` string. This
way you can prune according to either the key, the value,
or both.
This commit introduces the concept of modifier filter
options, which as of now are:
- `csp=`
- `queryprune=`
They both work in similar way when used with `important`
option or when used in exception filters. Modifier
options can apply to any network requests, hence the
logger reports the type of the network requests, and no
longer use the modifier as the type, i.e. `csp` filters
are no longer reported as requests of type `csp`.
Though modifier options can apply to any network requests,
for the time being the `csp=` modifier option still apply
only to top or embedded (frame) documents, just as before.
In some future we may want to apply `csp=` directives to
network requests of type script, to control the behavior
of service workers for example.
A new built-in filter expression has been added to the
logger: "modified", which allow to see all the network
requests which were modified before being emitted. The
translation work for this new option will be available
in a future commit.
2020-10-31 15:42:53 +01:00
|
|
|
if ( result !== 0 && result !== 3 && loggerEnabled ) {
|
2019-07-05 23:44:08 +02:00
|
|
|
fctxt.filter = µb.sessionFirewall.toLogData();
|
|
|
|
}
|
|
|
|
}
|
2015-01-06 14:01:15 +01:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
// Static filtering has lowest precedence.
|
Add new filter option `queryprune=`
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/760
The purpose of this new network filter option is to remove
query parameters form the URL of network requests.
The name `queryprune` has been picked over `querystrip`
since the purpose of the option is to remove some
parameters from the URL rather than all parameters.
`queryprune` is a modifier option (like `csp`) in that it
does not cause a network request to be blocked but rather
modified before being emitted.
`queryprune` must be assigned a value, which value will
determine which parameters from a query string will be
removed. The syntax for the value is that of regular
expression *except* for the following rules:
- do not wrap the regex directive between `/`
- do not use regex special values `^` and `$`
- do not use literal comma character in the value,
though you can use hex-encoded version, `\x2c`
- to match the start of a query parameter, prepend `|`
- to match the end of a query parameter, append `|`
`queryprune` regex-like values will be tested against each
key-value parameter pair as `[key]=[value]` string. This
way you can prune according to either the key, the value,
or both.
This commit introduces the concept of modifier filter
options, which as of now are:
- `csp=`
- `queryprune=`
They both work in similar way when used with `important`
option or when used in exception filters. Modifier
options can apply to any network requests, hence the
logger reports the type of the network requests, and no
longer use the modifier as the type, i.e. `csp` filters
are no longer reported as requests of type `csp`.
Though modifier options can apply to any network requests,
for the time being the `csp=` modifier option still apply
only to top or embedded (frame) documents, just as before.
In some future we may want to apply `csp=` directives to
network requests of type script, to control the behavior
of service workers for example.
A new built-in filter expression has been added to the
logger: "modified", which allow to see all the network
requests which were modified before being emitted. The
translation work for this new option will be available
in a future commit.
2020-10-31 15:42:53 +01:00
|
|
|
const snfe = µb.staticNetFilteringEngine;
|
2019-07-05 23:44:08 +02:00
|
|
|
if ( result === 0 || result === 3 ) {
|
2021-07-25 16:55:35 +02:00
|
|
|
result = snfe.matchRequest(fctxt);
|
Add support for `cname` type and `denyallow` option
This concerns the static network filtering engine.
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/943
* * *
New static network filter type: `cname`
By default, network requests which are result of
resolving a canonical name are subject to filtering.
This filtering can be bypassed by creating exception
filters using the `cname` option. For example:
@@*$cname
The filter above tells the network filtering engine
to except network requests which fulfill all the
following conditions:
- network request is blocked
- network request is that of an unaliased hostname
Filter list authors are discouraged from using
exception filters of `cname` type, unless there no
other practical solution such that maintenance
burden become the greater issue. Of course, such
exception filters should be as narrow as possible,
i.e. apply to specific domain, etc.
* * *
New static network filter option: `denyallow`
The purpose of `denyallow` is bring
default-deny/allow-exceptionally ability into static
network filtering arsenal. Example of usage:
*$3p,script, \
denyallow=x.com|y.com \
domain=a.com|b.com
The above filter tells the network filtering engine that
when the context is `a.com` or `b.com`, block all
3rd-party scripts except those from `x.com` and `y.com`.
Essentially, the new `denyallow` option makes it easier
to implement default-deny/allow-exceptionally in static
filter lists, whereas before this had to be done with
unwieldy regular expressions[1], or through the mix of
broadly blocking filters along with exception filters[2].
[1] https://hg.adblockplus.org/ruadlist/rev/f362910bc9a0
[2] Typically filters which pattern are of the
form `|http*://`
2020-03-15 17:23:25 +01:00
|
|
|
if ( result !== 0 ) {
|
Add new filter option `queryprune=`
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/760
The purpose of this new network filter option is to remove
query parameters form the URL of network requests.
The name `queryprune` has been picked over `querystrip`
since the purpose of the option is to remove some
parameters from the URL rather than all parameters.
`queryprune` is a modifier option (like `csp`) in that it
does not cause a network request to be blocked but rather
modified before being emitted.
`queryprune` must be assigned a value, which value will
determine which parameters from a query string will be
removed. The syntax for the value is that of regular
expression *except* for the following rules:
- do not wrap the regex directive between `/`
- do not use regex special values `^` and `$`
- do not use literal comma character in the value,
though you can use hex-encoded version, `\x2c`
- to match the start of a query parameter, prepend `|`
- to match the end of a query parameter, append `|`
`queryprune` regex-like values will be tested against each
key-value parameter pair as `[key]=[value]` string. This
way you can prune according to either the key, the value,
or both.
This commit introduces the concept of modifier filter
options, which as of now are:
- `csp=`
- `queryprune=`
They both work in similar way when used with `important`
option or when used in exception filters. Modifier
options can apply to any network requests, hence the
logger reports the type of the network requests, and no
longer use the modifier as the type, i.e. `csp` filters
are no longer reported as requests of type `csp`.
Though modifier options can apply to any network requests,
for the time being the `csp=` modifier option still apply
only to top or embedded (frame) documents, just as before.
In some future we may want to apply `csp=` directives to
network requests of type script, to control the behavior
of service workers for example.
A new built-in filter expression has been added to the
logger: "modified", which allow to see all the network
requests which were modified before being emitted. The
translation work for this new option will be available
in a future commit.
2020-10-31 15:42:53 +01:00
|
|
|
if ( loggerEnabled ) {
|
2020-12-08 17:16:17 +01:00
|
|
|
fctxt.setFilter(snfe.toLogData());
|
Add support for `cname` type and `denyallow` option
This concerns the static network filtering engine.
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/943
* * *
New static network filter type: `cname`
By default, network requests which are result of
resolving a canonical name are subject to filtering.
This filtering can be bypassed by creating exception
filters using the `cname` option. For example:
@@*$cname
The filter above tells the network filtering engine
to except network requests which fulfill all the
following conditions:
- network request is blocked
- network request is that of an unaliased hostname
Filter list authors are discouraged from using
exception filters of `cname` type, unless there no
other practical solution such that maintenance
burden become the greater issue. Of course, such
exception filters should be as narrow as possible,
i.e. apply to specific domain, etc.
* * *
New static network filter option: `denyallow`
The purpose of `denyallow` is bring
default-deny/allow-exceptionally ability into static
network filtering arsenal. Example of usage:
*$3p,script, \
denyallow=x.com|y.com \
domain=a.com|b.com
The above filter tells the network filtering engine that
when the context is `a.com` or `b.com`, block all
3rd-party scripts except those from `x.com` and `y.com`.
Essentially, the new `denyallow` option makes it easier
to implement default-deny/allow-exceptionally in static
filter lists, whereas before this had to be done with
unwieldy regular expressions[1], or through the mix of
broadly blocking filters along with exception filters[2].
[1] https://hg.adblockplus.org/ruadlist/rev/f362910bc9a0
[2] Typically filters which pattern are of the
form `|http*://`
2020-03-15 17:23:25 +01:00
|
|
|
}
|
|
|
|
// https://github.com/uBlockOrigin/uBlock-issues/issues/943
|
|
|
|
// Blanket-except blocked aliased canonical hostnames?
|
|
|
|
if (
|
|
|
|
result === 1 &&
|
|
|
|
fctxt.aliasURL !== undefined &&
|
|
|
|
snfe.isBlockImportant() === false &&
|
|
|
|
this.shouldExceptCname(fctxt)
|
|
|
|
) {
|
|
|
|
return 2;
|
|
|
|
}
|
2019-07-05 23:44:08 +02:00
|
|
|
}
|
|
|
|
}
|
2017-08-03 16:18:05 +02:00
|
|
|
|
2020-10-10 14:36:30 +02:00
|
|
|
// Click-to-load?
|
2020-10-09 19:50:54 +02:00
|
|
|
// When frameId is not -1, the resource is always sub_frame.
|
|
|
|
if ( result === 1 && fctxt.frameId !== -1 ) {
|
2020-10-10 14:36:30 +02:00
|
|
|
const frameStore = this.getFrameStore(fctxt.frameId);
|
|
|
|
if ( frameStore !== null && frameStore.clickToLoad ) {
|
2020-10-09 19:50:54 +02:00
|
|
|
result = 2;
|
Add new filter option `queryprune=`
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/760
The purpose of this new network filter option is to remove
query parameters form the URL of network requests.
The name `queryprune` has been picked over `querystrip`
since the purpose of the option is to remove some
parameters from the URL rather than all parameters.
`queryprune` is a modifier option (like `csp`) in that it
does not cause a network request to be blocked but rather
modified before being emitted.
`queryprune` must be assigned a value, which value will
determine which parameters from a query string will be
removed. The syntax for the value is that of regular
expression *except* for the following rules:
- do not wrap the regex directive between `/`
- do not use regex special values `^` and `$`
- do not use literal comma character in the value,
though you can use hex-encoded version, `\x2c`
- to match the start of a query parameter, prepend `|`
- to match the end of a query parameter, append `|`
`queryprune` regex-like values will be tested against each
key-value parameter pair as `[key]=[value]` string. This
way you can prune according to either the key, the value,
or both.
This commit introduces the concept of modifier filter
options, which as of now are:
- `csp=`
- `queryprune=`
They both work in similar way when used with `important`
option or when used in exception filters. Modifier
options can apply to any network requests, hence the
logger reports the type of the network requests, and no
longer use the modifier as the type, i.e. `csp` filters
are no longer reported as requests of type `csp`.
Though modifier options can apply to any network requests,
for the time being the `csp=` modifier option still apply
only to top or embedded (frame) documents, just as before.
In some future we may want to apply `csp=` directives to
network requests of type script, to control the behavior
of service workers for example.
A new built-in filter expression has been added to the
logger: "modified", which allow to see all the network
requests which were modified before being emitted. The
translation work for this new option will be available
in a future commit.
2020-10-31 15:42:53 +01:00
|
|
|
if ( loggerEnabled ) {
|
|
|
|
fctxt.pushFilter({
|
2020-10-09 19:50:54 +02:00
|
|
|
result,
|
|
|
|
source: 'network',
|
|
|
|
raw: 'click-to-load',
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Add new filter option `queryprune=`
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/760
The purpose of this new network filter option is to remove
query parameters form the URL of network requests.
The name `queryprune` has been picked over `querystrip`
since the purpose of the option is to remove some
parameters from the URL rather than all parameters.
`queryprune` is a modifier option (like `csp`) in that it
does not cause a network request to be blocked but rather
modified before being emitted.
`queryprune` must be assigned a value, which value will
determine which parameters from a query string will be
removed. The syntax for the value is that of regular
expression *except* for the following rules:
- do not wrap the regex directive between `/`
- do not use regex special values `^` and `$`
- do not use literal comma character in the value,
though you can use hex-encoded version, `\x2c`
- to match the start of a query parameter, prepend `|`
- to match the end of a query parameter, append `|`
`queryprune` regex-like values will be tested against each
key-value parameter pair as `[key]=[value]` string. This
way you can prune according to either the key, the value,
or both.
This commit introduces the concept of modifier filter
options, which as of now are:
- `csp=`
- `queryprune=`
They both work in similar way when used with `important`
option or when used in exception filters. Modifier
options can apply to any network requests, hence the
logger reports the type of the network requests, and no
longer use the modifier as the type, i.e. `csp` filters
are no longer reported as requests of type `csp`.
Though modifier options can apply to any network requests,
for the time being the `csp=` modifier option still apply
only to top or embedded (frame) documents, just as before.
In some future we may want to apply `csp=` directives to
network requests of type script, to control the behavior
of service workers for example.
A new built-in filter expression has been added to the
logger: "modified", which allow to see all the network
requests which were modified before being emitted. The
translation work for this new option will be available
in a future commit.
2020-10-31 15:42:53 +01:00
|
|
|
// Modifier(s)?
|
|
|
|
// A modifier is an action which transform the original network request.
|
2020-10-10 14:36:30 +02:00
|
|
|
// https://github.com/gorhill/uBlock/issues/949
|
|
|
|
// Redirect blocked request?
|
Add new filter option `queryprune=`
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/760
The purpose of this new network filter option is to remove
query parameters form the URL of network requests.
The name `queryprune` has been picked over `querystrip`
since the purpose of the option is to remove some
parameters from the URL rather than all parameters.
`queryprune` is a modifier option (like `csp`) in that it
does not cause a network request to be blocked but rather
modified before being emitted.
`queryprune` must be assigned a value, which value will
determine which parameters from a query string will be
removed. The syntax for the value is that of regular
expression *except* for the following rules:
- do not wrap the regex directive between `/`
- do not use regex special values `^` and `$`
- do not use literal comma character in the value,
though you can use hex-encoded version, `\x2c`
- to match the start of a query parameter, prepend `|`
- to match the end of a query parameter, append `|`
`queryprune` regex-like values will be tested against each
key-value parameter pair as `[key]=[value]` string. This
way you can prune according to either the key, the value,
or both.
This commit introduces the concept of modifier filter
options, which as of now are:
- `csp=`
- `queryprune=`
They both work in similar way when used with `important`
option or when used in exception filters. Modifier
options can apply to any network requests, hence the
logger reports the type of the network requests, and no
longer use the modifier as the type, i.e. `csp` filters
are no longer reported as requests of type `csp`.
Though modifier options can apply to any network requests,
for the time being the `csp=` modifier option still apply
only to top or embedded (frame) documents, just as before.
In some future we may want to apply `csp=` directives to
network requests of type script, to control the behavior
of service workers for example.
A new built-in filter expression has been added to the
logger: "modified", which allow to see all the network
requests which were modified before being emitted. The
translation work for this new option will be available
in a future commit.
2020-10-31 15:42:53 +01:00
|
|
|
// https://github.com/uBlockOrigin/uBlock-issues/issues/760
|
|
|
|
// Redirect non-blocked request?
|
|
|
|
if ( (fctxt.itype & fctxt.INLINE_ANY) === 0 ) {
|
|
|
|
if ( result === 1 ) {
|
2020-11-03 15:15:26 +01:00
|
|
|
this.redirectBlockedRequest(fctxt);
|
Add new filter option `queryprune=`
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/760
The purpose of this new network filter option is to remove
query parameters form the URL of network requests.
The name `queryprune` has been picked over `querystrip`
since the purpose of the option is to remove some
parameters from the URL rather than all parameters.
`queryprune` is a modifier option (like `csp`) in that it
does not cause a network request to be blocked but rather
modified before being emitted.
`queryprune` must be assigned a value, which value will
determine which parameters from a query string will be
removed. The syntax for the value is that of regular
expression *except* for the following rules:
- do not wrap the regex directive between `/`
- do not use regex special values `^` and `$`
- do not use literal comma character in the value,
though you can use hex-encoded version, `\x2c`
- to match the start of a query parameter, prepend `|`
- to match the end of a query parameter, append `|`
`queryprune` regex-like values will be tested against each
key-value parameter pair as `[key]=[value]` string. This
way you can prune according to either the key, the value,
or both.
This commit introduces the concept of modifier filter
options, which as of now are:
- `csp=`
- `queryprune=`
They both work in similar way when used with `important`
option or when used in exception filters. Modifier
options can apply to any network requests, hence the
logger reports the type of the network requests, and no
longer use the modifier as the type, i.e. `csp` filters
are no longer reported as requests of type `csp`.
Though modifier options can apply to any network requests,
for the time being the `csp=` modifier option still apply
only to top or embedded (frame) documents, just as before.
In some future we may want to apply `csp=` directives to
network requests of type script, to control the behavior
of service workers for example.
A new built-in filter expression has been added to the
logger: "modified", which allow to see all the network
requests which were modified before being emitted. The
translation work for this new option will be available
in a future commit.
2020-10-31 15:42:53 +01:00
|
|
|
} else if ( snfe.hasQuery(fctxt) ) {
|
2020-11-03 15:15:26 +01:00
|
|
|
this.redirectNonBlockedRequest(fctxt);
|
2020-10-10 14:36:30 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
if ( cacheableResult ) {
|
|
|
|
this.netFilteringCache.rememberResult(fctxt, result);
|
Add new filter option `queryprune=`
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/760
The purpose of this new network filter option is to remove
query parameters form the URL of network requests.
The name `queryprune` has been picked over `querystrip`
since the purpose of the option is to remove some
parameters from the URL rather than all parameters.
`queryprune` is a modifier option (like `csp`) in that it
does not cause a network request to be blocked but rather
modified before being emitted.
`queryprune` must be assigned a value, which value will
determine which parameters from a query string will be
removed. The syntax for the value is that of regular
expression *except* for the following rules:
- do not wrap the regex directive between `/`
- do not use regex special values `^` and `$`
- do not use literal comma character in the value,
though you can use hex-encoded version, `\x2c`
- to match the start of a query parameter, prepend `|`
- to match the end of a query parameter, append `|`
`queryprune` regex-like values will be tested against each
key-value parameter pair as `[key]=[value]` string. This
way you can prune according to either the key, the value,
or both.
This commit introduces the concept of modifier filter
options, which as of now are:
- `csp=`
- `queryprune=`
They both work in similar way when used with `important`
option or when used in exception filters. Modifier
options can apply to any network requests, hence the
logger reports the type of the network requests, and no
longer use the modifier as the type, i.e. `csp` filters
are no longer reported as requests of type `csp`.
Though modifier options can apply to any network requests,
for the time being the `csp=` modifier option still apply
only to top or embedded (frame) documents, just as before.
In some future we may want to apply `csp=` directives to
network requests of type script, to control the behavior
of service workers for example.
A new built-in filter expression has been added to the
logger: "modified", which allow to see all the network
requests which were modified before being emitted. The
translation work for this new option will be available
in a future commit.
2020-10-31 15:42:53 +01:00
|
|
|
} else if ( result === 1 && this.collapsibleResources.has(fctxt.itype) ) {
|
2020-10-10 14:36:30 +02:00
|
|
|
this.netFilteringCache.rememberBlock(fctxt);
|
2019-07-05 23:44:08 +02:00
|
|
|
}
|
2017-08-03 16:18:05 +02:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
return result;
|
|
|
|
}
|
2015-01-24 18:06:22 +01:00
|
|
|
|
Add support for `1P`, `3P`, `header=` filter options and other changes
New filter options
==================
Strict partyness: `1P`, `3P`
----------------------------
The current options 1p/3p are meant to "weakly" match partyness, i.e. a
network request is considered 1st-party to its context as long as both the
context and the request share the same base domain.
The new partyness options are meant to check for strict partyness, i.e. a
network request will be considered 1st-party if and only if both the context
and the request share the same hostname.
For examples:
- context: `www.example.org`
- request: `www.example.org`
- `1p`: yes, `1P`: yes
- `3p`: no, `3P`: no
- context: `www.example.org`
- request: `subdomain.example.org`
- `1p`: yes, `1P`: no
- `3p`: no, `3P`: yes
- context: `www.example.org`
- request: `www.example.com`
- `1p`: no, `1P`: no
- `3p`: yes, `3P`: yes
The strict partyness options will be visually emphasized in the editor so as
to prevent mistakenly using `1P` or `3P` where weak partyness is meant to be
used.
Filter on response headers: `header=`
-------------------------------------
Currently experimental and under evaluation. Disabled by default, enable by
toggling `filterOnHeaders` to `true` in advanced settings.
Ability to filter network requests according to whether a specific response
header is present and whether it matches or does not match a specific value.
For example:
*$1p,3P,script,header=via:1\.1\s+google
The above filter is meant to block network requests which fullfill all the
following conditions:
- is weakly 1st-party to the context
- is not strictly 1st-party to the context
- is of type `script`
- has a response HTTP header named `via`, which value matches the regular
expression `1\.1\s+google`.
The matches are always performed in a case-insensitive manner.
The header value is assumed to be a literal regular expression, except for
the following special characters:
- to anchor to start of string, use leading `|`, not `^`
- to anchor to end of string, use trailing `|`, not `$`
- to invert the test, use a leading `!`
To block a network request if it merely contains a specific HTTP header is
just a matter of specifying the header name without a header value:
*$1p,3P,script,header=via
Generic exception filters can be used to disable specific block `header=`
filters, i.e. `@@*$1p,3P,script,header` will override the block `header=`
filters given as example above.
Dynamic filtering's `allow` rules override block `headers=` filters.
Important: It is key that filter authors use as many narrowing filter options
as possible when using the `header=` option, and the `header=` option should
be used ONLY when other filter options are not sufficient.
More documentation justifying the purpose of `header=` option will be
provided eventually if ever it is decided to move it from experimental to
stable status.
To be decided: to restrict usage of this filter option to only uBO's own
filter lists or "My filters".
Changes
=======
Fine tuning `queryprune=`
-------------------------
The following changes have been implemented:
The special value `*` (i.e. `queryprune=*`) means "remove all query
parameters".
If the `queryprune=` value is made only of alphanumeric characters
(including `_`), the value will be internally converted to regex equivalent
`^value=`. This ensures a better future compatibility with AdGuard's
`removeparam=`.
If the `queryprune=` value starts with `!`, the test will be inverted. This
can be used to remove all query parameters EXCEPT those who match the
specified value.
Other
-----
The legacy code to test for spurious CSP reports has been removed. This
is no longer an issue ever since uBO redirects to local resources through
web accessible resources.
Notes
=====
The following new and recently added filter options are not compatible with
Chromium's manifest v3 changes:
- `queryprune=`
- `1P`
- `3P`
- `header=`
2020-11-23 14:22:43 +01:00
|
|
|
filterOnHeaders(fctxt, headers) {
|
|
|
|
fctxt.filter = undefined;
|
|
|
|
|
|
|
|
if ( this.getNetFilteringSwitch(fctxt) === false ) { return 0; }
|
|
|
|
|
|
|
|
let result = µb.staticNetFilteringEngine.matchHeaders(fctxt, headers);
|
|
|
|
if ( result === 0 ) { return 0; }
|
|
|
|
|
|
|
|
const loggerEnabled = µb.logger.enabled;
|
|
|
|
if ( loggerEnabled ) {
|
|
|
|
fctxt.filter = µb.staticNetFilteringEngine.toLogData();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Dynamic filtering allow rules
|
|
|
|
// URL filtering
|
|
|
|
if (
|
|
|
|
result === 1 &&
|
|
|
|
µb.sessionURLFiltering.evaluateZ(
|
|
|
|
fctxt.getTabHostname(),
|
|
|
|
fctxt.url,
|
|
|
|
fctxt.type
|
|
|
|
) === 2
|
|
|
|
) {
|
|
|
|
result = 2;
|
|
|
|
if ( loggerEnabled ) {
|
|
|
|
fctxt.filter = µb.sessionURLFiltering.toLogData();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Hostname filtering
|
|
|
|
if (
|
|
|
|
result === 1 &&
|
|
|
|
µb.userSettings.advancedUserEnabled &&
|
|
|
|
µb.sessionFirewall.evaluateCellZY(
|
|
|
|
fctxt.getTabHostname(),
|
|
|
|
fctxt.getHostname(),
|
|
|
|
fctxt.type
|
|
|
|
) === 2
|
|
|
|
) {
|
|
|
|
result = 2;
|
|
|
|
if ( loggerEnabled ) {
|
|
|
|
fctxt.filter = µb.sessionFirewall.toLogData();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2020-11-03 15:15:26 +01:00
|
|
|
redirectBlockedRequest(fctxt) {
|
2021-07-25 16:55:35 +02:00
|
|
|
const directives = µb.staticNetFilteringEngine.redirectRequest(
|
|
|
|
µb.redirectEngine,
|
|
|
|
fctxt
|
|
|
|
);
|
2020-12-01 15:29:40 +01:00
|
|
|
if ( directives === undefined ) { return; }
|
2020-11-03 15:15:26 +01:00
|
|
|
if ( µb.logger.enabled !== true ) { return; }
|
2020-12-01 15:29:40 +01:00
|
|
|
fctxt.pushFilters(directives.map(a => a.logData()));
|
2020-11-03 15:15:26 +01:00
|
|
|
if ( fctxt.redirectURL === undefined ) { return; }
|
|
|
|
fctxt.pushFilter({
|
|
|
|
source: 'redirect',
|
|
|
|
raw: µb.redirectEngine.resourceNameRegister
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
redirectNonBlockedRequest(fctxt) {
|
|
|
|
const directives = µb.staticNetFilteringEngine.filterQuery(fctxt);
|
|
|
|
if ( directives === undefined ) { return; }
|
|
|
|
if ( µb.logger.enabled !== true ) { return; }
|
|
|
|
fctxt.pushFilters(directives.map(a => a.logData()));
|
|
|
|
if ( fctxt.redirectURL === undefined ) { return; }
|
|
|
|
fctxt.pushFilter({
|
|
|
|
source: 'redirect',
|
|
|
|
raw: fctxt.redirectURL
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
filterCSPReport(fctxt) {
|
|
|
|
if (
|
|
|
|
µb.sessionSwitches.evaluateZ(
|
|
|
|
'no-csp-reports',
|
|
|
|
fctxt.getHostname()
|
|
|
|
)
|
|
|
|
) {
|
|
|
|
if ( µb.logger.enabled ) {
|
|
|
|
fctxt.filter = µb.sessionSwitches.toLogData();
|
|
|
|
}
|
|
|
|
return 1;
|
2017-10-19 15:35:28 +02:00
|
|
|
}
|
2019-07-05 23:44:08 +02:00
|
|
|
return 0;
|
2017-10-19 15:35:28 +02:00
|
|
|
}
|
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
filterFont(fctxt) {
|
Add new filter option `queryprune=`
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/760
The purpose of this new network filter option is to remove
query parameters form the URL of network requests.
The name `queryprune` has been picked over `querystrip`
since the purpose of the option is to remove some
parameters from the URL rather than all parameters.
`queryprune` is a modifier option (like `csp`) in that it
does not cause a network request to be blocked but rather
modified before being emitted.
`queryprune` must be assigned a value, which value will
determine which parameters from a query string will be
removed. The syntax for the value is that of regular
expression *except* for the following rules:
- do not wrap the regex directive between `/`
- do not use regex special values `^` and `$`
- do not use literal comma character in the value,
though you can use hex-encoded version, `\x2c`
- to match the start of a query parameter, prepend `|`
- to match the end of a query parameter, append `|`
`queryprune` regex-like values will be tested against each
key-value parameter pair as `[key]=[value]` string. This
way you can prune according to either the key, the value,
or both.
This commit introduces the concept of modifier filter
options, which as of now are:
- `csp=`
- `queryprune=`
They both work in similar way when used with `important`
option or when used in exception filters. Modifier
options can apply to any network requests, hence the
logger reports the type of the network requests, and no
longer use the modifier as the type, i.e. `csp` filters
are no longer reported as requests of type `csp`.
Though modifier options can apply to any network requests,
for the time being the `csp=` modifier option still apply
only to top or embedded (frame) documents, just as before.
In some future we may want to apply `csp=` directives to
network requests of type script, to control the behavior
of service workers for example.
A new built-in filter expression has been added to the
logger: "modified", which allow to see all the network
requests which were modified before being emitted. The
translation work for this new option will be available
in a future commit.
2020-10-31 15:42:53 +01:00
|
|
|
if ( fctxt.itype === fctxt.FONT ) {
|
2019-07-05 23:44:08 +02:00
|
|
|
this.remoteFontCount += 1;
|
|
|
|
}
|
|
|
|
if (
|
|
|
|
µb.sessionSwitches.evaluateZ(
|
|
|
|
'no-remote-fonts',
|
|
|
|
fctxt.getTabHostname()
|
|
|
|
) !== false
|
|
|
|
) {
|
|
|
|
if ( µb.logger.enabled ) {
|
|
|
|
fctxt.filter = µb.sessionSwitches.toLogData();
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
2017-10-19 15:35:28 +02:00
|
|
|
}
|
2019-07-05 23:44:08 +02:00
|
|
|
|
|
|
|
filterScripting(fctxt, netFiltering) {
|
|
|
|
fctxt.filter = undefined;
|
|
|
|
if ( netFiltering === undefined ) {
|
|
|
|
netFiltering = this.getNetFilteringSwitch(fctxt);
|
|
|
|
}
|
|
|
|
if (
|
|
|
|
netFiltering === false ||
|
|
|
|
µb.sessionSwitches.evaluateZ(
|
|
|
|
'no-scripting',
|
|
|
|
fctxt.getTabHostname()
|
|
|
|
) === false
|
|
|
|
) {
|
|
|
|
return 0;
|
|
|
|
}
|
2018-12-13 18:30:54 +01:00
|
|
|
if ( µb.logger.enabled ) {
|
|
|
|
fctxt.filter = µb.sessionSwitches.toLogData();
|
2017-10-19 15:35:28 +02:00
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
2018-09-01 00:47:02 +02:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
// The caller is responsible to check whether filtering is enabled or not.
|
|
|
|
filterLargeMediaElement(fctxt, size) {
|
|
|
|
fctxt.filter = undefined;
|
2018-09-01 00:47:02 +02:00
|
|
|
|
2020-10-18 16:07:46 +02:00
|
|
|
if ( this.allowLargeMediaElementsUntil === 0 ) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
// Disregard large media elements previously allowed: for example, to
|
|
|
|
// seek inside a previously allowed audio/video.
|
|
|
|
if (
|
|
|
|
this.allowLargeMediaElementsRegex instanceof RegExp &&
|
|
|
|
this.allowLargeMediaElementsRegex.test(fctxt.url)
|
|
|
|
) {
|
|
|
|
return 0;
|
|
|
|
}
|
2019-07-05 23:44:08 +02:00
|
|
|
if ( Date.now() < this.allowLargeMediaElementsUntil ) {
|
2020-10-18 16:07:46 +02:00
|
|
|
const sources = this.allowLargeMediaElementsRegex instanceof RegExp
|
|
|
|
? [ this.allowLargeMediaElementsRegex.source ]
|
|
|
|
: [];
|
|
|
|
sources.push('^' + µb.escapeRegex(fctxt.url));
|
|
|
|
this.allowLargeMediaElementsRegex = new RegExp(sources.join('|'));
|
2019-07-05 23:44:08 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (
|
|
|
|
µb.sessionSwitches.evaluateZ(
|
|
|
|
'no-large-media',
|
|
|
|
fctxt.getTabHostname()
|
|
|
|
) !== true
|
|
|
|
) {
|
2020-10-18 16:07:46 +02:00
|
|
|
this.allowLargeMediaElementsUntil = 0;
|
2019-07-05 23:44:08 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if ( (size >>> 10) < µb.userSettings.largeMediaSize ) {
|
|
|
|
return 0;
|
|
|
|
}
|
2016-11-08 21:53:08 +01:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
this.largeMediaCount += 1;
|
|
|
|
if ( this.largeMediaTimer === null ) {
|
|
|
|
this.largeMediaTimer = vAPI.setTimeout(( ) => {
|
|
|
|
this.largeMediaTimer = null;
|
|
|
|
this.injectLargeMediaElementScriptlet();
|
|
|
|
}, 500);
|
|
|
|
}
|
2017-05-12 16:35:11 +02:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
if ( µb.logger.enabled ) {
|
|
|
|
fctxt.filter = µb.sessionSwitches.toLogData();
|
|
|
|
}
|
2016-11-08 21:53:08 +01:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
return 1;
|
2016-11-08 21:53:08 +01:00
|
|
|
}
|
|
|
|
|
2020-10-09 19:50:54 +02:00
|
|
|
clickToLoad(frameId, frameURL) {
|
|
|
|
let frameStore = this.getFrameStore(frameId);
|
|
|
|
if ( frameStore === null ) {
|
2021-01-10 17:56:27 +01:00
|
|
|
frameStore = this.setFrameURL({ frameId, url: frameURL });
|
2020-10-09 19:50:54 +02:00
|
|
|
}
|
2020-10-10 14:36:30 +02:00
|
|
|
this.netFilteringCache.forgetResult(
|
|
|
|
this.tabHostname,
|
|
|
|
'sub_frame',
|
|
|
|
frameURL
|
|
|
|
);
|
|
|
|
frameStore.clickToLoad = true;
|
2020-10-09 19:50:54 +02:00
|
|
|
}
|
|
|
|
|
Add support for `cname` type and `denyallow` option
This concerns the static network filtering engine.
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/943
* * *
New static network filter type: `cname`
By default, network requests which are result of
resolving a canonical name are subject to filtering.
This filtering can be bypassed by creating exception
filters using the `cname` option. For example:
@@*$cname
The filter above tells the network filtering engine
to except network requests which fulfill all the
following conditions:
- network request is blocked
- network request is that of an unaliased hostname
Filter list authors are discouraged from using
exception filters of `cname` type, unless there no
other practical solution such that maintenance
burden become the greater issue. Of course, such
exception filters should be as narrow as possible,
i.e. apply to specific domain, etc.
* * *
New static network filter option: `denyallow`
The purpose of `denyallow` is bring
default-deny/allow-exceptionally ability into static
network filtering arsenal. Example of usage:
*$3p,script, \
denyallow=x.com|y.com \
domain=a.com|b.com
The above filter tells the network filtering engine that
when the context is `a.com` or `b.com`, block all
3rd-party scripts except those from `x.com` and `y.com`.
Essentially, the new `denyallow` option makes it easier
to implement default-deny/allow-exceptionally in static
filter lists, whereas before this had to be done with
unwieldy regular expressions[1], or through the mix of
broadly blocking filters along with exception filters[2].
[1] https://hg.adblockplus.org/ruadlist/rev/f362910bc9a0
[2] Typically filters which pattern are of the
form `|http*://`
2020-03-15 17:23:25 +01:00
|
|
|
shouldExceptCname(fctxt) {
|
|
|
|
let exceptCname;
|
|
|
|
let frameStore;
|
|
|
|
if ( fctxt.docId !== undefined ) {
|
2020-10-09 19:50:54 +02:00
|
|
|
frameStore = this.getFrameStore(fctxt.docId);
|
Add support for `cname` type and `denyallow` option
This concerns the static network filtering engine.
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/943
* * *
New static network filter type: `cname`
By default, network requests which are result of
resolving a canonical name are subject to filtering.
This filtering can be bypassed by creating exception
filters using the `cname` option. For example:
@@*$cname
The filter above tells the network filtering engine
to except network requests which fulfill all the
following conditions:
- network request is blocked
- network request is that of an unaliased hostname
Filter list authors are discouraged from using
exception filters of `cname` type, unless there no
other practical solution such that maintenance
burden become the greater issue. Of course, such
exception filters should be as narrow as possible,
i.e. apply to specific domain, etc.
* * *
New static network filter option: `denyallow`
The purpose of `denyallow` is bring
default-deny/allow-exceptionally ability into static
network filtering arsenal. Example of usage:
*$3p,script, \
denyallow=x.com|y.com \
domain=a.com|b.com
The above filter tells the network filtering engine that
when the context is `a.com` or `b.com`, block all
3rd-party scripts except those from `x.com` and `y.com`.
Essentially, the new `denyallow` option makes it easier
to implement default-deny/allow-exceptionally in static
filter lists, whereas before this had to be done with
unwieldy regular expressions[1], or through the mix of
broadly blocking filters along with exception filters[2].
[1] https://hg.adblockplus.org/ruadlist/rev/f362910bc9a0
[2] Typically filters which pattern are of the
form `|http*://`
2020-03-15 17:23:25 +01:00
|
|
|
if ( frameStore instanceof Object ) {
|
|
|
|
exceptCname = frameStore.exceptCname;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( exceptCname === undefined ) {
|
2021-07-25 16:55:35 +02:00
|
|
|
const result = µb.staticNetFilteringEngine.matchRequestReverse(
|
Add support for `cname` type and `denyallow` option
This concerns the static network filtering engine.
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/943
* * *
New static network filter type: `cname`
By default, network requests which are result of
resolving a canonical name are subject to filtering.
This filtering can be bypassed by creating exception
filters using the `cname` option. For example:
@@*$cname
The filter above tells the network filtering engine
to except network requests which fulfill all the
following conditions:
- network request is blocked
- network request is that of an unaliased hostname
Filter list authors are discouraged from using
exception filters of `cname` type, unless there no
other practical solution such that maintenance
burden become the greater issue. Of course, such
exception filters should be as narrow as possible,
i.e. apply to specific domain, etc.
* * *
New static network filter option: `denyallow`
The purpose of `denyallow` is bring
default-deny/allow-exceptionally ability into static
network filtering arsenal. Example of usage:
*$3p,script, \
denyallow=x.com|y.com \
domain=a.com|b.com
The above filter tells the network filtering engine that
when the context is `a.com` or `b.com`, block all
3rd-party scripts except those from `x.com` and `y.com`.
Essentially, the new `denyallow` option makes it easier
to implement default-deny/allow-exceptionally in static
filter lists, whereas before this had to be done with
unwieldy regular expressions[1], or through the mix of
broadly blocking filters along with exception filters[2].
[1] https://hg.adblockplus.org/ruadlist/rev/f362910bc9a0
[2] Typically filters which pattern are of the
form `|http*://`
2020-03-15 17:23:25 +01:00
|
|
|
'cname',
|
|
|
|
frameStore instanceof Object
|
|
|
|
? frameStore.rawURL
|
|
|
|
: fctxt.getDocOrigin()
|
|
|
|
);
|
2020-12-08 17:16:17 +01:00
|
|
|
exceptCname = result === 2
|
|
|
|
? µb.staticNetFilteringEngine.toLogData()
|
|
|
|
: false;
|
Add support for `cname` type and `denyallow` option
This concerns the static network filtering engine.
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/943
* * *
New static network filter type: `cname`
By default, network requests which are result of
resolving a canonical name are subject to filtering.
This filtering can be bypassed by creating exception
filters using the `cname` option. For example:
@@*$cname
The filter above tells the network filtering engine
to except network requests which fulfill all the
following conditions:
- network request is blocked
- network request is that of an unaliased hostname
Filter list authors are discouraged from using
exception filters of `cname` type, unless there no
other practical solution such that maintenance
burden become the greater issue. Of course, such
exception filters should be as narrow as possible,
i.e. apply to specific domain, etc.
* * *
New static network filter option: `denyallow`
The purpose of `denyallow` is bring
default-deny/allow-exceptionally ability into static
network filtering arsenal. Example of usage:
*$3p,script, \
denyallow=x.com|y.com \
domain=a.com|b.com
The above filter tells the network filtering engine that
when the context is `a.com` or `b.com`, block all
3rd-party scripts except those from `x.com` and `y.com`.
Essentially, the new `denyallow` option makes it easier
to implement default-deny/allow-exceptionally in static
filter lists, whereas before this had to be done with
unwieldy regular expressions[1], or through the mix of
broadly blocking filters along with exception filters[2].
[1] https://hg.adblockplus.org/ruadlist/rev/f362910bc9a0
[2] Typically filters which pattern are of the
form `|http*://`
2020-03-15 17:23:25 +01:00
|
|
|
if ( frameStore instanceof Object ) {
|
|
|
|
frameStore.exceptCname = exceptCname;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( exceptCname === false ) { return false; }
|
|
|
|
if ( exceptCname instanceof Object ) {
|
2020-12-08 17:16:17 +01:00
|
|
|
fctxt.setFilter(exceptCname);
|
Add support for `cname` type and `denyallow` option
This concerns the static network filtering engine.
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/943
* * *
New static network filter type: `cname`
By default, network requests which are result of
resolving a canonical name are subject to filtering.
This filtering can be bypassed by creating exception
filters using the `cname` option. For example:
@@*$cname
The filter above tells the network filtering engine
to except network requests which fulfill all the
following conditions:
- network request is blocked
- network request is that of an unaliased hostname
Filter list authors are discouraged from using
exception filters of `cname` type, unless there no
other practical solution such that maintenance
burden become the greater issue. Of course, such
exception filters should be as narrow as possible,
i.e. apply to specific domain, etc.
* * *
New static network filter option: `denyallow`
The purpose of `denyallow` is bring
default-deny/allow-exceptionally ability into static
network filtering arsenal. Example of usage:
*$3p,script, \
denyallow=x.com|y.com \
domain=a.com|b.com
The above filter tells the network filtering engine that
when the context is `a.com` or `b.com`, block all
3rd-party scripts except those from `x.com` and `y.com`.
Essentially, the new `denyallow` option makes it easier
to implement default-deny/allow-exceptionally in static
filter lists, whereas before this had to be done with
unwieldy regular expressions[1], or through the mix of
broadly blocking filters along with exception filters[2].
[1] https://hg.adblockplus.org/ruadlist/rev/f362910bc9a0
[2] Typically filters which pattern are of the
form `|http*://`
2020-03-15 17:23:25 +01:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
getBlockedResources(request, response) {
|
2021-07-25 16:55:35 +02:00
|
|
|
const normalURL = µb.normalizeTabURL(this.tabId, request.frameURL);
|
2019-07-05 23:44:08 +02:00
|
|
|
const resources = request.resources;
|
|
|
|
const fctxt = µb.filteringContext;
|
|
|
|
fctxt.fromTabId(this.tabId)
|
|
|
|
.setDocOriginFromURL(normalURL);
|
|
|
|
// Force some resources to go through the filtering engine in order to
|
|
|
|
// populate the blocked-resources cache. This is required because for
|
|
|
|
// some resources it's not possible to detect whether they were blocked
|
|
|
|
// content script-side (i.e. `iframes` -- unlike `img`).
|
|
|
|
if ( Array.isArray(resources) && resources.length !== 0 ) {
|
|
|
|
for ( const resource of resources ) {
|
2020-10-10 14:36:30 +02:00
|
|
|
this.filterRequest(
|
2020-10-09 19:50:54 +02:00
|
|
|
fctxt.setType(resource.type).setURL(resource.url)
|
2019-07-05 23:44:08 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( this.netFilteringCache.hash === response.hash ) { return; }
|
|
|
|
response.hash = this.netFilteringCache.hash;
|
|
|
|
response.blockedResources =
|
|
|
|
this.netFilteringCache.lookupAllBlocked(fctxt.getDocHostname());
|
2017-05-12 16:35:11 +02:00
|
|
|
}
|
2016-11-08 21:53:08 +01:00
|
|
|
};
|
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
PageStore.prototype.cacheableResults = new Set([
|
Add new filter option `queryprune=`
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/760
The purpose of this new network filter option is to remove
query parameters form the URL of network requests.
The name `queryprune` has been picked over `querystrip`
since the purpose of the option is to remove some
parameters from the URL rather than all parameters.
`queryprune` is a modifier option (like `csp`) in that it
does not cause a network request to be blocked but rather
modified before being emitted.
`queryprune` must be assigned a value, which value will
determine which parameters from a query string will be
removed. The syntax for the value is that of regular
expression *except* for the following rules:
- do not wrap the regex directive between `/`
- do not use regex special values `^` and `$`
- do not use literal comma character in the value,
though you can use hex-encoded version, `\x2c`
- to match the start of a query parameter, prepend `|`
- to match the end of a query parameter, append `|`
`queryprune` regex-like values will be tested against each
key-value parameter pair as `[key]=[value]` string. This
way you can prune according to either the key, the value,
or both.
This commit introduces the concept of modifier filter
options, which as of now are:
- `csp=`
- `queryprune=`
They both work in similar way when used with `important`
option or when used in exception filters. Modifier
options can apply to any network requests, hence the
logger reports the type of the network requests, and no
longer use the modifier as the type, i.e. `csp` filters
are no longer reported as requests of type `csp`.
Though modifier options can apply to any network requests,
for the time being the `csp=` modifier option still apply
only to top or embedded (frame) documents, just as before.
In some future we may want to apply `csp=` directives to
network requests of type script, to control the behavior
of service workers for example.
A new built-in filter expression has been added to the
logger: "modified", which allow to see all the network
requests which were modified before being emitted. The
translation work for this new option will be available
in a future commit.
2020-10-31 15:42:53 +01:00
|
|
|
µb.FilteringContext.SUB_FRAME,
|
2019-07-05 23:44:08 +02:00
|
|
|
]);
|
2015-06-10 15:23:48 +02:00
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
PageStore.prototype.collapsibleResources = new Set([
|
Add new filter option `queryprune=`
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/760
The purpose of this new network filter option is to remove
query parameters form the URL of network requests.
The name `queryprune` has been picked over `querystrip`
since the purpose of the option is to remove some
parameters from the URL rather than all parameters.
`queryprune` is a modifier option (like `csp`) in that it
does not cause a network request to be blocked but rather
modified before being emitted.
`queryprune` must be assigned a value, which value will
determine which parameters from a query string will be
removed. The syntax for the value is that of regular
expression *except* for the following rules:
- do not wrap the regex directive between `/`
- do not use regex special values `^` and `$`
- do not use literal comma character in the value,
though you can use hex-encoded version, `\x2c`
- to match the start of a query parameter, prepend `|`
- to match the end of a query parameter, append `|`
`queryprune` regex-like values will be tested against each
key-value parameter pair as `[key]=[value]` string. This
way you can prune according to either the key, the value,
or both.
This commit introduces the concept of modifier filter
options, which as of now are:
- `csp=`
- `queryprune=`
They both work in similar way when used with `important`
option or when used in exception filters. Modifier
options can apply to any network requests, hence the
logger reports the type of the network requests, and no
longer use the modifier as the type, i.e. `csp` filters
are no longer reported as requests of type `csp`.
Though modifier options can apply to any network requests,
for the time being the `csp=` modifier option still apply
only to top or embedded (frame) documents, just as before.
In some future we may want to apply `csp=` directives to
network requests of type script, to control the behavior
of service workers for example.
A new built-in filter expression has been added to the
logger: "modified", which allow to see all the network
requests which were modified before being emitted. The
translation work for this new option will be available
in a future commit.
2020-10-31 15:42:53 +01:00
|
|
|
µb.FilteringContext.IMAGE,
|
|
|
|
µb.FilteringContext.MEDIA,
|
|
|
|
µb.FilteringContext.OBJECT,
|
|
|
|
µb.FilteringContext.SUB_FRAME,
|
2019-07-05 23:44:08 +02:00
|
|
|
]);
|
2017-05-12 16:35:11 +02:00
|
|
|
|
2021-02-15 12:52:31 +01:00
|
|
|
// To mitigate memory churning
|
|
|
|
PageStore.junkyard = [];
|
|
|
|
PageStore.junkyardMax = 10;
|
|
|
|
|
2019-07-05 23:44:08 +02:00
|
|
|
µb.PageStore = PageStore;
|
2015-01-24 18:06:22 +01:00
|
|
|
|
2014-06-24 00:42:43 +02:00
|
|
|
/******************************************************************************/
|