mirror of
https://github.com/gorhill/uBlock.git
synced 2026-03-11 09:04:36 +00:00
this fixes #191 completely
This commit is contained in:
parent
527817d2f2
commit
fe2d761908
1 changed files with 178 additions and 77 deletions
|
|
@ -41,6 +41,7 @@
|
||||||
|
|
||||||
const BlockAction = 0 << 15;
|
const BlockAction = 0 << 15;
|
||||||
const AllowAction = 1 << 15;
|
const AllowAction = 1 << 15;
|
||||||
|
const ToggleAction = BlockAction ^ AllowAction;
|
||||||
|
|
||||||
const AnyType = 1 << 11;
|
const AnyType = 1 << 11;
|
||||||
|
|
||||||
|
|
@ -209,6 +210,12 @@ FilterPlain.prototype.match = function(url, tokenBeg) {
|
||||||
return url.substr(tokenBeg - this.tokenBeg, this.s.length) === this.s;
|
return url.substr(tokenBeg - this.tokenBeg, this.s.length) === this.s;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FilterPlain.prototype.toString = function() {
|
||||||
|
return this.s;
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterPlainHostname = function(s, tokenBeg, hostname) {
|
var FilterPlainHostname = function(s, tokenBeg, hostname) {
|
||||||
this.s = s;
|
this.s = s;
|
||||||
this.tokenBeg = tokenBeg;
|
this.tokenBeg = tokenBeg;
|
||||||
|
|
@ -221,6 +228,10 @@ FilterPlainHostname.prototype.match = function(url, tokenBeg) {
|
||||||
url.substr(tokenBeg - this.tokenBeg, this.s.length) === this.s;
|
url.substr(tokenBeg - this.tokenBeg, this.s.length) === this.s;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FilterPlainHostname.prototype.toString = function() {
|
||||||
|
return this.s + '$domain=' + this.hostname;
|
||||||
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterPlainPrefix0 = function(s) {
|
var FilterPlainPrefix0 = function(s) {
|
||||||
|
|
@ -232,6 +243,12 @@ FilterPlainPrefix0.prototype.match = function(url, tokenBeg) {
|
||||||
return url.substr(tokenBeg, this.s.length) === this.s;
|
return url.substr(tokenBeg, this.s.length) === this.s;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FilterPlainPrefix0.prototype.toString = function() {
|
||||||
|
return this.s;
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterPlainPrefix0Hostname = function(s, hostname) {
|
var FilterPlainPrefix0Hostname = function(s, hostname) {
|
||||||
this.s = s;
|
this.s = s;
|
||||||
this.hostname = hostname;
|
this.hostname = hostname;
|
||||||
|
|
@ -243,6 +260,10 @@ FilterPlainPrefix0Hostname.prototype.match = function(url, tokenBeg) {
|
||||||
url.substr(tokenBeg, this.s.length) === this.s;
|
url.substr(tokenBeg, this.s.length) === this.s;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FilterPlainPrefix0Hostname.prototype.toString = function() {
|
||||||
|
return this.s + '$domain=' + this.hostname;
|
||||||
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterPlainPrefix1 = function(s) {
|
var FilterPlainPrefix1 = function(s) {
|
||||||
|
|
@ -254,6 +275,12 @@ FilterPlainPrefix1.prototype.match = function(url, tokenBeg) {
|
||||||
return url.substr(tokenBeg - 1, this.s.length) === this.s;
|
return url.substr(tokenBeg - 1, this.s.length) === this.s;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FilterPlainPrefix1.prototype.toString = function() {
|
||||||
|
return this.s;
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterPlainPrefix1Hostname = function(s, hostname) {
|
var FilterPlainPrefix1Hostname = function(s, hostname) {
|
||||||
this.s = s;
|
this.s = s;
|
||||||
this.hostname = hostname;
|
this.hostname = hostname;
|
||||||
|
|
@ -265,6 +292,10 @@ FilterPlainPrefix1Hostname.prototype.match = function(url, tokenBeg) {
|
||||||
url.substr(tokenBeg - 1, this.s.length) === this.s;
|
url.substr(tokenBeg - 1, this.s.length) === this.s;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FilterPlainPrefix1Hostname.prototype.toString = function() {
|
||||||
|
return this.s + '$domain=' + this.hostname;
|
||||||
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterPlainLeftAnchored = function(s) {
|
var FilterPlainLeftAnchored = function(s) {
|
||||||
|
|
@ -276,6 +307,12 @@ FilterPlainLeftAnchored.prototype.match = function(url) {
|
||||||
return url.slice(0, this.s.length) === this.s;
|
return url.slice(0, this.s.length) === this.s;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FilterPlainLeftAnchored.prototype.toString = function() {
|
||||||
|
return '|' + this.s;
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterPlainLeftAnchoredHostname = function(s, hostname) {
|
var FilterPlainLeftAnchoredHostname = function(s, hostname) {
|
||||||
this.s = s;
|
this.s = s;
|
||||||
this.hostname = hostname;
|
this.hostname = hostname;
|
||||||
|
|
@ -287,6 +324,10 @@ FilterPlainLeftAnchoredHostname.prototype.match = function(url) {
|
||||||
url.slice(0, this.s.length) === this.s;
|
url.slice(0, this.s.length) === this.s;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FilterPlainLeftAnchoredHostname.prototype.toString = function() {
|
||||||
|
return '|' + this.s + '$domain=' + this.hostname;
|
||||||
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterPlainRightAnchored = function(s) {
|
var FilterPlainRightAnchored = function(s) {
|
||||||
|
|
@ -298,6 +339,12 @@ FilterPlainRightAnchored.prototype.match = function(url) {
|
||||||
return url.slice(-this.s.length) === this.s;
|
return url.slice(-this.s.length) === this.s;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FilterPlainRightAnchored.prototype.toString = function() {
|
||||||
|
return this.s + '|';
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterPlainRightAnchoredHostname = function(s, hostname) {
|
var FilterPlainRightAnchoredHostname = function(s, hostname) {
|
||||||
this.s = s;
|
this.s = s;
|
||||||
this.hostname = hostname;
|
this.hostname = hostname;
|
||||||
|
|
@ -309,6 +356,10 @@ FilterPlainRightAnchoredHostname.prototype.match = function(url) {
|
||||||
url.slice(-this.s.length) === this.s;
|
url.slice(-this.s.length) === this.s;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FilterPlainRightAnchoredHostname.prototype.toString = function() {
|
||||||
|
return this.s + '|$domain=' + this.hostname;
|
||||||
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
// With a single wildcard, regex is not optimal.
|
// With a single wildcard, regex is not optimal.
|
||||||
|
|
@ -317,7 +368,6 @@ FilterPlainRightAnchoredHostname.prototype.match = function(url) {
|
||||||
// http://jsperf.com/regexp-vs-indexof-abp-hit/3
|
// http://jsperf.com/regexp-vs-indexof-abp-hit/3
|
||||||
|
|
||||||
var FilterSingleWildcard = function(s, tokenBeg) {
|
var FilterSingleWildcard = function(s, tokenBeg) {
|
||||||
this.s = s;
|
|
||||||
this.tokenBeg = tokenBeg;
|
this.tokenBeg = tokenBeg;
|
||||||
var wcOffset = s.indexOf('*');
|
var wcOffset = s.indexOf('*');
|
||||||
this.lSegment = s.slice(0, wcOffset);
|
this.lSegment = s.slice(0, wcOffset);
|
||||||
|
|
@ -331,8 +381,13 @@ FilterSingleWildcard.prototype.match = function(url, tokenBeg) {
|
||||||
url.indexOf(this.rSegment, tokenBeg + this.lSegment.length) > 0;
|
url.indexOf(this.rSegment, tokenBeg + this.lSegment.length) > 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FilterSingleWildcard.prototype.toString = function() {
|
||||||
|
return this.lSegment + '*' + this.rSegment;
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterSingleWildcardHostname = function(s, tokenBeg, hostname) {
|
var FilterSingleWildcardHostname = function(s, tokenBeg, hostname) {
|
||||||
this.s = s;
|
|
||||||
this.tokenBeg = tokenBeg;
|
this.tokenBeg = tokenBeg;
|
||||||
var wcOffset = s.indexOf('*');
|
var wcOffset = s.indexOf('*');
|
||||||
this.lSegment = s.slice(0, wcOffset);
|
this.lSegment = s.slice(0, wcOffset);
|
||||||
|
|
@ -348,10 +403,13 @@ FilterSingleWildcardHostname.prototype.match = function(url, tokenBeg) {
|
||||||
url.indexOf(this.rSegment, tokenBeg + this.lSegment.length) > 0;
|
url.indexOf(this.rSegment, tokenBeg + this.lSegment.length) > 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FilterSingleWildcardHostname.prototype.toString = function() {
|
||||||
|
return this.lSegment + '*' + this.rSegment + '$domain=' + this.hostname;
|
||||||
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterSingleWildcardPrefix0 = function(s) {
|
var FilterSingleWildcardPrefix0 = function(s) {
|
||||||
this.s = s;
|
|
||||||
var wcOffset = s.indexOf('*');
|
var wcOffset = s.indexOf('*');
|
||||||
this.lSegment = s.slice(0, wcOffset);
|
this.lSegment = s.slice(0, wcOffset);
|
||||||
this.rSegment = s.slice(wcOffset + 1);
|
this.rSegment = s.slice(wcOffset + 1);
|
||||||
|
|
@ -363,8 +421,13 @@ FilterSingleWildcardPrefix0.prototype.match = function(url, tokenBeg) {
|
||||||
url.indexOf(this.rSegment, tokenBeg + this.lSegment.length) > 0;
|
url.indexOf(this.rSegment, tokenBeg + this.lSegment.length) > 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FilterSingleWildcardPrefix0.prototype.toString = function() {
|
||||||
|
return this.lSegment + '*' + this.rSegment;
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterSingleWildcardPrefix0Hostname = function(s, hostname) {
|
var FilterSingleWildcardPrefix0Hostname = function(s, hostname) {
|
||||||
this.s = s;
|
|
||||||
var wcOffset = s.indexOf('*');
|
var wcOffset = s.indexOf('*');
|
||||||
this.lSegment = s.slice(0, wcOffset);
|
this.lSegment = s.slice(0, wcOffset);
|
||||||
this.rSegment = s.slice(wcOffset + 1);
|
this.rSegment = s.slice(wcOffset + 1);
|
||||||
|
|
@ -378,6 +441,10 @@ FilterSingleWildcardPrefix0Hostname.prototype.match = function(url, tokenBeg) {
|
||||||
url.indexOf(this.rSegment, tokenBeg + this.lSegment.length) > 0;
|
url.indexOf(this.rSegment, tokenBeg + this.lSegment.length) > 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FilterSingleWildcardPrefix0Hostname.prototype.toString = function() {
|
||||||
|
return this.lSegment + '*' + this.rSegment + '$domain=' + this.hostname;
|
||||||
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
// With a single wildcard, regex is not optimal.
|
// With a single wildcard, regex is not optimal.
|
||||||
|
|
@ -386,7 +453,6 @@ FilterSingleWildcardPrefix0Hostname.prototype.match = function(url, tokenBeg) {
|
||||||
// http://jsperf.com/regexp-vs-indexof-abp-hit/3
|
// http://jsperf.com/regexp-vs-indexof-abp-hit/3
|
||||||
|
|
||||||
var FilterSingleWildcardLeftAnchored = function(s) {
|
var FilterSingleWildcardLeftAnchored = function(s) {
|
||||||
this.s = s;
|
|
||||||
var wcOffset = s.indexOf('*');
|
var wcOffset = s.indexOf('*');
|
||||||
this.lSegment = s.slice(0, wcOffset);
|
this.lSegment = s.slice(0, wcOffset);
|
||||||
this.rSegment = s.slice(wcOffset + 1);
|
this.rSegment = s.slice(wcOffset + 1);
|
||||||
|
|
@ -398,8 +464,13 @@ FilterSingleWildcardLeftAnchored.prototype.match = function(url) {
|
||||||
url.indexOf(this.rSegment, this.lSegment.length) > 0;
|
url.indexOf(this.rSegment, this.lSegment.length) > 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FilterSingleWildcardLeftAnchored.prototype.toString = function() {
|
||||||
|
return '|' + this.lSegment + '*' + this.rSegment;
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterSingleWildcardLeftAnchoredHostname = function(s, hostname) {
|
var FilterSingleWildcardLeftAnchoredHostname = function(s, hostname) {
|
||||||
this.s = s;
|
|
||||||
var wcOffset = s.indexOf('*');
|
var wcOffset = s.indexOf('*');
|
||||||
this.lSegment = s.slice(0, wcOffset);
|
this.lSegment = s.slice(0, wcOffset);
|
||||||
this.rSegment = s.slice(wcOffset + 1);
|
this.rSegment = s.slice(wcOffset + 1);
|
||||||
|
|
@ -413,6 +484,10 @@ FilterSingleWildcardLeftAnchoredHostname.prototype.match = function(url) {
|
||||||
url.indexOf(this.rSegment, this.lSegment.length) > 0;
|
url.indexOf(this.rSegment, this.lSegment.length) > 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FilterSingleWildcardLeftAnchoredHostname.prototype.toString = function() {
|
||||||
|
return '|' + this.lSegment + '*' + this.rSegment + '$domain=' + this.hostname;
|
||||||
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
// With a single wildcard, regex is not optimal.
|
// With a single wildcard, regex is not optimal.
|
||||||
|
|
@ -421,7 +496,6 @@ FilterSingleWildcardLeftAnchoredHostname.prototype.match = function(url) {
|
||||||
// http://jsperf.com/regexp-vs-indexof-abp-hit/3
|
// http://jsperf.com/regexp-vs-indexof-abp-hit/3
|
||||||
|
|
||||||
var FilterSingleWildcardRightAnchored = function(s) {
|
var FilterSingleWildcardRightAnchored = function(s) {
|
||||||
this.s = s;
|
|
||||||
var wcOffset = s.indexOf('*');
|
var wcOffset = s.indexOf('*');
|
||||||
this.lSegment = s.slice(0, wcOffset);
|
this.lSegment = s.slice(0, wcOffset);
|
||||||
this.rSegment = s.slice(wcOffset + 1);
|
this.rSegment = s.slice(wcOffset + 1);
|
||||||
|
|
@ -433,8 +507,13 @@ FilterSingleWildcardRightAnchored.prototype.match = function(url) {
|
||||||
url.lastIndexOf(this.lSegment, url.length - this.rSegment.length - this.lSegment.length) >= 0;
|
url.lastIndexOf(this.lSegment, url.length - this.rSegment.length - this.lSegment.length) >= 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FilterSingleWildcardRightAnchored.prototype.toString = function() {
|
||||||
|
return this.lSegment + '*' + this.rSegment + '|';
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterSingleWildcardRightAnchoredHostname = function(s, hostname) {
|
var FilterSingleWildcardRightAnchoredHostname = function(s, hostname) {
|
||||||
this.s = s;
|
|
||||||
var wcOffset = s.indexOf('*');
|
var wcOffset = s.indexOf('*');
|
||||||
this.lSegment = s.slice(0, wcOffset);
|
this.lSegment = s.slice(0, wcOffset);
|
||||||
this.rSegment = s.slice(wcOffset + 1);
|
this.rSegment = s.slice(wcOffset + 1);
|
||||||
|
|
@ -448,6 +527,10 @@ FilterSingleWildcardRightAnchoredHostname.prototype.match = function(url) {
|
||||||
url.lastIndexOf(this.lSegment, url.length - this.rSegment.length - this.lSegment.length) >= 0;
|
url.lastIndexOf(this.lSegment, url.length - this.rSegment.length - this.lSegment.length) >= 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FilterSingleWildcardRightAnchoredHostname.prototype.toString = function() {
|
||||||
|
return this.lSegment + '*' + this.rSegment + '|$domain=' + this.hostname;
|
||||||
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
// With many wildcards, a regex is best.
|
// With many wildcards, a regex is best.
|
||||||
|
|
@ -467,6 +550,12 @@ FilterManyWildcards.prototype.match = function(url, tokenBeg) {
|
||||||
return this.re.test(url.slice(tokenBeg - this.tokenBeg));
|
return this.re.test(url.slice(tokenBeg - this.tokenBeg));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FilterManyWildcards.prototype.toString = function() {
|
||||||
|
return this.s;
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterManyWildcardsHostname = function(s, tokenBeg, hostname) {
|
var FilterManyWildcardsHostname = function(s, tokenBeg, hostname) {
|
||||||
this.s = s;
|
this.s = s;
|
||||||
this.tokenBeg = tokenBeg;
|
this.tokenBeg = tokenBeg;
|
||||||
|
|
@ -480,6 +569,10 @@ FilterManyWildcardsHostname.prototype.match = function(url, tokenBeg) {
|
||||||
this.re.test(url.slice(tokenBeg - this.tokenBeg));
|
this.re.test(url.slice(tokenBeg - this.tokenBeg));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FilterManyWildcardsHostname.prototype.toString = function() {
|
||||||
|
return this.s + '$domain=' + this.hostname;
|
||||||
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var makeFilter = function(details, tokenBeg) {
|
var makeFilter = function(details, tokenBeg) {
|
||||||
|
|
@ -613,20 +706,10 @@ var trimChar = function(s, c) {
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterParser = function() {
|
var FilterParser = function() {
|
||||||
this.action = BlockAction;
|
|
||||||
this.anchor = 0;
|
|
||||||
this.domains = [];
|
this.domains = [];
|
||||||
this.elemHiding = false;
|
|
||||||
this.f = '';
|
|
||||||
this.firstParty = false;
|
|
||||||
this.fopts = '';
|
|
||||||
this.hostname = false;
|
|
||||||
this.hostnames = [];
|
this.hostnames = [];
|
||||||
this.notDomains = [];
|
|
||||||
this.notHostnames = [];
|
|
||||||
this.thirdParty = false;
|
|
||||||
this.types = [];
|
this.types = [];
|
||||||
this.unsupported = false;
|
this.reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
@ -648,17 +731,16 @@ FilterParser.prototype.toNormalizedType = {
|
||||||
FilterParser.prototype.reset = function() {
|
FilterParser.prototype.reset = function() {
|
||||||
this.action = BlockAction;
|
this.action = BlockAction;
|
||||||
this.anchor = 0;
|
this.anchor = 0;
|
||||||
this.domains = [];
|
this.domains.length = 0;
|
||||||
this.elemHiding = false;
|
this.elemHiding = false;
|
||||||
this.f = '';
|
this.f = '';
|
||||||
this.firstParty = false;
|
this.firstParty = false;
|
||||||
this.fopts = '';
|
this.fopts = '';
|
||||||
this.hostname = false;
|
this.hostname = false;
|
||||||
this.hostnames = [];
|
this.hostnames.length = 0;
|
||||||
this.notDomains = [];
|
this.notHostname = false;
|
||||||
this.notHostnames = [];
|
|
||||||
this.thirdParty = false;
|
this.thirdParty = false;
|
||||||
this.types = [];
|
this.types.length = 0;
|
||||||
this.unsupported = false;
|
this.unsupported = false;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
@ -710,13 +792,17 @@ FilterParser.prototype.parseOptHostnames = function(raw) {
|
||||||
if ( domain === '' ) {
|
if ( domain === '' ) {
|
||||||
domain = noDomainName;
|
domain = noDomainName;
|
||||||
}
|
}
|
||||||
if ( not ) {
|
// https://github.com/gorhill/uBlock/issues/191
|
||||||
this.notHostnames.push(hostname);
|
// Well it doesn't seem to make a whole lot of sense to have both
|
||||||
this.notDomains.push(domain);
|
// non-negated hostnames mixed with negated hostnames.
|
||||||
} else {
|
if ( this.hostnames.length !== 0 && not !== this.notHostname ) {
|
||||||
this.hostnames.push(hostname);
|
console.error('FilterContainer.parseOptHostnames(): ambiguous filter syntax: "%s"', this.f);
|
||||||
this.domains.push(domain);
|
this.unsupported = true;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
this.notHostname = not;
|
||||||
|
this.hostnames.push(hostname);
|
||||||
|
this.domains.push(domain);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -811,29 +897,32 @@ FilterParser.prototype.parse = function(s) {
|
||||||
|
|
||||||
var FilterBucket = function(a, b) {
|
var FilterBucket = function(a, b) {
|
||||||
this.filters = [a, b];
|
this.filters = [a, b];
|
||||||
this.s = '';
|
this.f = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
FilterBucket.prototype.add = function(a) {
|
FilterBucket.prototype.add = function(a) {
|
||||||
this.filters.push(a);
|
this.filters.push(a);
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
FilterBucket.prototype.match = function(url, tokenBeg) {
|
FilterBucket.prototype.match = function(url, tokenBeg) {
|
||||||
var filters = this.filters;
|
var filters = this.filters;
|
||||||
var i = filters.length;
|
var i = filters.length;
|
||||||
while ( i-- ) {
|
while ( i-- ) {
|
||||||
if ( filters[i].match(url, tokenBeg) !== false ) {
|
if ( filters[i].match(url, tokenBeg) !== false ) {
|
||||||
this.s = filters[i].s;
|
this.f = filters[i];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FilterBucket.prototype.toString = function() {
|
||||||
|
if ( this.f !== null ) {
|
||||||
|
return this.f.toString();
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
|
@ -996,19 +1085,12 @@ FilterContainer.prototype.addFilter = function(parsed) {
|
||||||
}
|
}
|
||||||
var tokenBeg = matches.index;
|
var tokenBeg = matches.index;
|
||||||
var tokenEnd = parsed.hostname ? reHostnameToken.lastIndex : reGoodToken.lastIndex;
|
var tokenEnd = parsed.hostname ? reHostnameToken.lastIndex : reGoodToken.lastIndex;
|
||||||
var i, n, filter;
|
var filter;
|
||||||
|
|
||||||
// https://github.com/gorhill/uBlock/issues/191
|
var i = parsed.hostnames.length;
|
||||||
// Well it doesn't seem to make a whole lot of sense to have both
|
|
||||||
// non-negated hostnames mixed with negated hostnames.
|
|
||||||
if ( parsed.hostnames.length && parsed.notHostnames.length ) {
|
|
||||||
console.error('FilterContainer.addFilter(): ambiguous filter syntax', parsed.f);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( parsed.hostnames.length ) {
|
if ( i !== 0 && !parsed.notHostname ) {
|
||||||
n = parsed.hostnames.length;
|
while ( i-- ) {
|
||||||
for ( i = 0; i < n; i++ ) {
|
|
||||||
filter = makeHostnameFilter(parsed, tokenBeg, parsed.hostnames[i]);
|
filter = makeHostnameFilter(parsed, tokenBeg, parsed.hostnames[i]);
|
||||||
if ( !filter ) {
|
if ( !filter ) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -1026,24 +1108,29 @@ FilterContainer.prototype.addFilter = function(parsed) {
|
||||||
|
|
||||||
// https://github.com/gorhill/uBlock/issues/191
|
// https://github.com/gorhill/uBlock/issues/191
|
||||||
// Invert the purpose of the filter for negated hostnames
|
// Invert the purpose of the filter for negated hostnames
|
||||||
if ( parsed.notHostnames.length ) {
|
if ( i !== 0 && parsed.notHostname ) {
|
||||||
filter = makeFilter(parsed, tokenBeg);
|
filter = makeFilter(parsed, tokenBeg);
|
||||||
if ( !filter ) {
|
if ( !filter ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
this.addFilterEntry(filter, parsed, AnyParty, tokenBeg, tokenEnd);
|
this.addFilterEntry(filter, parsed, AnyParty, tokenBeg, tokenEnd);
|
||||||
// Reverse purpose of filter
|
// Reverse purpose of filter
|
||||||
parsed.action ^= (BlockAction ^ AllowAction);
|
parsed.action ^= ToggleAction;
|
||||||
n = parsed.notHostnames.length;
|
while ( i-- ) {
|
||||||
for ( i = 0; i < n; i++ ) {
|
filter = makeHostnameFilter(parsed, tokenBeg, parsed.hostnames[i]);
|
||||||
filter = makeHostnameFilter(parsed, tokenBeg, parsed.notHostnames[i]);
|
|
||||||
if ( !filter ) {
|
if ( !filter ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// https://github.com/gorhill/uBlock/issues/191#issuecomment-53654024
|
||||||
|
// If it is a block filter, we need to reverse the order of
|
||||||
|
// evaluation.
|
||||||
|
if ( parsed.action === BlockAction ) {
|
||||||
|
filter.important = true;
|
||||||
|
}
|
||||||
this.addFilterEntry(
|
this.addFilterEntry(
|
||||||
filter,
|
filter,
|
||||||
parsed,
|
parsed,
|
||||||
SpecificParty | this.toDomainBits(parsed.notDomains[i]),
|
SpecificParty | this.toDomainBits(parsed.domains[i]),
|
||||||
tokenBeg,
|
tokenBeg,
|
||||||
tokenEnd
|
tokenEnd
|
||||||
);
|
);
|
||||||
|
|
@ -1123,49 +1210,49 @@ FilterContainer.prototype.matchTokens = function(url) {
|
||||||
if ( bucket0 !== undefined ) {
|
if ( bucket0 !== undefined ) {
|
||||||
f = bucket0[token];
|
f = bucket0[token];
|
||||||
if ( f !== undefined && f.match(url, beg) !== false ) {
|
if ( f !== undefined && f.match(url, beg) !== false ) {
|
||||||
return f.s;
|
return f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( bucket1 !== undefined ) {
|
if ( bucket1 !== undefined ) {
|
||||||
f = bucket1[token];
|
f = bucket1[token];
|
||||||
if ( f !== undefined && f.match(url, beg) !== false ) {
|
if ( f !== undefined && f.match(url, beg) !== false ) {
|
||||||
return f.s;
|
return f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( bucket2 !== undefined ) {
|
if ( bucket2 !== undefined ) {
|
||||||
f = bucket2[token];
|
f = bucket2[token];
|
||||||
if ( f !== undefined && f.match(url, beg) !== false ) {
|
if ( f !== undefined && f.match(url, beg) !== false ) {
|
||||||
return f.s;
|
return f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( bucket3 !== undefined ) {
|
if ( bucket3 !== undefined ) {
|
||||||
f = bucket3[token];
|
f = bucket3[token];
|
||||||
if ( f !== undefined && f.match(url, beg) !== false ) {
|
if ( f !== undefined && f.match(url, beg) !== false ) {
|
||||||
return f.s;
|
return f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( bucket4 !== undefined ) {
|
if ( bucket4 !== undefined ) {
|
||||||
f = bucket4[token];
|
f = bucket4[token];
|
||||||
if ( f !== undefined && f.match(url, beg) !== false ) {
|
if ( f !== undefined && f.match(url, beg) !== false ) {
|
||||||
return f.s;
|
return f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( bucket5 !== undefined ) {
|
if ( bucket5 !== undefined ) {
|
||||||
f = bucket5[token];
|
f = bucket5[token];
|
||||||
if ( f !== undefined && f.match(url, beg) !== false ) {
|
if ( f !== undefined && f.match(url, beg) !== false ) {
|
||||||
return f.s;
|
return f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( bucket6 !== undefined ) {
|
if ( bucket6 !== undefined ) {
|
||||||
f = bucket6[token];
|
f = bucket6[token];
|
||||||
if ( f !== undefined && f.match(url, beg) !== false ) {
|
if ( f !== undefined && f.match(url, beg) !== false ) {
|
||||||
return f.s;
|
return f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( bucket7 !== undefined ) {
|
if ( bucket7 !== undefined ) {
|
||||||
f = bucket7[token];
|
f = bucket7[token];
|
||||||
if ( f !== undefined && f.match(url, beg) !== false ) {
|
if ( f !== undefined && f.match(url, beg) !== false ) {
|
||||||
return f.s;
|
return f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1251,24 +1338,31 @@ FilterContainer.prototype.matchStringExactType = function(pageDetails, requestUR
|
||||||
buckets[4] = categories[this.makeCategoryKey(BlockAction | type | party)];
|
buckets[4] = categories[this.makeCategoryKey(BlockAction | type | party)];
|
||||||
buckets[5] = categories[this.makeCategoryKey(BlockOneParty | type | domainParty)];
|
buckets[5] = categories[this.makeCategoryKey(BlockOneParty | type | domainParty)];
|
||||||
buckets[7] = categories[this.makeCategoryKey(BlockOneParty | type | this.noDomainBits)];
|
buckets[7] = categories[this.makeCategoryKey(BlockOneParty | type | this.noDomainBits)];
|
||||||
var br = this.matchTokens(url);
|
var bf = this.matchTokens(url);
|
||||||
|
|
||||||
// If there is no block filter, no need to test against allow filters
|
// If there is no block filter, no need to test against allow filters
|
||||||
if ( br === false ) {
|
if ( bf === false ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The purpose of the `important` property is to reverse the order of
|
||||||
|
// evaluation. Normally, it is "evaluate block then evaluate allow", with
|
||||||
|
// the `important` property it is "evaluate allow then evaluate block".
|
||||||
|
if ( bf.important === true ) {
|
||||||
|
return bf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
// Test against allow filters
|
// Test against allow filters
|
||||||
buckets[3] = categories[this.makeCategoryKey(AllowAnyParty | type)];
|
buckets[3] = categories[this.makeCategoryKey(AllowAnyParty | type)];
|
||||||
buckets[4] = categories[this.makeCategoryKey(AllowAction | type | party)];
|
buckets[4] = categories[this.makeCategoryKey(AllowAction | type | party)];
|
||||||
buckets[5] = categories[this.makeCategoryKey(AllowOneParty | type | domainParty)];
|
buckets[5] = categories[this.makeCategoryKey(AllowOneParty | type | domainParty)];
|
||||||
buckets[7] = categories[this.makeCategoryKey(AllowOneParty | type | this.noDomainBits)];
|
buckets[7] = categories[this.makeCategoryKey(AllowOneParty | type | this.noDomainBits)];
|
||||||
var ar = this.matchTokens(url);
|
var af = this.matchTokens(url);
|
||||||
if ( ar !== false ) {
|
if ( af !== false ) {
|
||||||
return '@@' + ar;
|
return '@@' + af.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
return br;
|
return bf.toString();
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
@ -1309,9 +1403,9 @@ FilterContainer.prototype.matchString = function(pageDetails, requestURL, reques
|
||||||
ThirdParty;
|
ThirdParty;
|
||||||
|
|
||||||
// Test hostname-based block filters
|
// Test hostname-based block filters
|
||||||
var br = this.matchAnyPartyHostname(requestHostname);
|
var bf = this.matchAnyPartyHostname(requestHostname);
|
||||||
if ( br === false && party === ThirdParty ) {
|
if ( bf === false && party === ThirdParty ) {
|
||||||
br = this.match3rdPartyHostname(requestHostname);
|
bf = this.match3rdPartyHostname(requestHostname);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This will be used by hostname-based filters
|
// This will be used by hostname-based filters
|
||||||
|
|
@ -1323,7 +1417,7 @@ FilterContainer.prototype.matchString = function(pageDetails, requestURL, reques
|
||||||
var buckets = this.buckets;
|
var buckets = this.buckets;
|
||||||
|
|
||||||
// Test against block filters
|
// Test against block filters
|
||||||
if ( br === false ) {
|
if ( bf === false ) {
|
||||||
buckets[0] = categories[this.makeCategoryKey(BlockAnyTypeAnyParty)];
|
buckets[0] = categories[this.makeCategoryKey(BlockAnyTypeAnyParty)];
|
||||||
buckets[1] = categories[this.makeCategoryKey(BlockAnyType | party)];
|
buckets[1] = categories[this.makeCategoryKey(BlockAnyType | party)];
|
||||||
buckets[2] = categories[this.makeCategoryKey(BlockAnyTypeOneParty | domainParty)];
|
buckets[2] = categories[this.makeCategoryKey(BlockAnyTypeOneParty | domainParty)];
|
||||||
|
|
@ -1334,14 +1428,21 @@ FilterContainer.prototype.matchString = function(pageDetails, requestURL, reques
|
||||||
// Test for synthetic domain as well
|
// Test for synthetic domain as well
|
||||||
buckets[6] = categories[this.makeCategoryKey(BlockAnyTypeOneParty | this.noDomainBits)];
|
buckets[6] = categories[this.makeCategoryKey(BlockAnyTypeOneParty | this.noDomainBits)];
|
||||||
buckets[7] = categories[this.makeCategoryKey(BlockOneParty | type | this.noDomainBits)];
|
buckets[7] = categories[this.makeCategoryKey(BlockOneParty | type | this.noDomainBits)];
|
||||||
br = this.matchTokens(url);
|
bf = this.matchTokens(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is no block filter, no need to test against allow filters
|
// If there is no block filter, no need to test against allow filters
|
||||||
if ( br === false ) {
|
if ( bf === false ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The purpose of the `important` property is to reverse the order of
|
||||||
|
// evaluation. Normally, it is "evaluate block then evaluate allow", with
|
||||||
|
// the `important` property it is "evaluate allow then evaluate block".
|
||||||
|
if ( bf.important === true ) {
|
||||||
|
return bf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
// Test against allow filters
|
// Test against allow filters
|
||||||
buckets[0] = categories[this.makeCategoryKey(AllowAnyTypeAnyParty)];
|
buckets[0] = categories[this.makeCategoryKey(AllowAnyTypeAnyParty)];
|
||||||
buckets[1] = categories[this.makeCategoryKey(AllowAnyType | party)];
|
buckets[1] = categories[this.makeCategoryKey(AllowAnyType | party)];
|
||||||
|
|
@ -1353,12 +1454,12 @@ FilterContainer.prototype.matchString = function(pageDetails, requestURL, reques
|
||||||
// Test for synthetic domain as well
|
// Test for synthetic domain as well
|
||||||
buckets[6] = categories[this.makeCategoryKey(AllowAnyTypeOneParty | this.noDomainBits)];
|
buckets[6] = categories[this.makeCategoryKey(AllowAnyTypeOneParty | this.noDomainBits)];
|
||||||
buckets[7] = categories[this.makeCategoryKey(AllowOneParty | type | this.noDomainBits)];
|
buckets[7] = categories[this.makeCategoryKey(AllowOneParty | type | this.noDomainBits)];
|
||||||
var ar = this.matchTokens(url);
|
var af = this.matchTokens(url);
|
||||||
if ( ar !== false ) {
|
if ( af !== false ) {
|
||||||
return '@@' + ar;
|
return '@@' + af.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
return br;
|
return bf.toString();
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue