mirror of
https://github.com/gorhill/uBlock.git
synced 2024-11-07 03:12:33 +01:00
this fixes #621
Interpretation/implementation of exception filters with negated hostname(s) has been revised: no block filter is implied anymore for such filters. At time of writing I found only 10 such filters in EasyList, and none in commonly used filter lists.
This commit is contained in:
parent
028cfc144e
commit
a63ac99e03
@ -1,6 +1,6 @@
|
|||||||
6f506c670bd425f4743c3056d5a51d83 assets/ublock/unbreak.txt
|
6f506c670bd425f4743c3056d5a51d83 assets/ublock/unbreak.txt
|
||||||
75448208315e80706632ec8a6df0e6d3 assets/ublock/privacy.txt
|
75448208315e80706632ec8a6df0e6d3 assets/ublock/privacy.txt
|
||||||
09f198379cf23b2db2c14ea9ce032b7c assets/ublock/filters.txt
|
93cec249d997a853e86c1f4c7c130360 assets/ublock/filters.txt
|
||||||
d2c1dc3f8c4528e6d6a9083afc30b938 assets/ublock/badware.txt
|
d2c1dc3f8c4528e6d6a9083afc30b938 assets/ublock/badware.txt
|
||||||
c9c5cc56bec563bc1885847f925b9be2 assets/ublock/mirror-candidates.txt
|
c9c5cc56bec563bc1885847f925b9be2 assets/ublock/mirror-candidates.txt
|
||||||
bf58b93ff4853f6c5bf2aadec2b85916 assets/ublock/filter-lists.json
|
bf58b93ff4853f6c5bf2aadec2b85916 assets/ublock/filter-lists.json
|
||||||
|
@ -59,6 +59,9 @@ google.*###sqh
|
|||||||
# For when javascript is disabled
|
# For when javascript is disabled
|
||||||
google.*###center_col > #tads
|
google.*###center_col > #tads
|
||||||
|
|
||||||
|
# https://github.com/gorhill/uBlock/issues/621
|
||||||
|
search.yahoo.com###main > div > style + ol
|
||||||
|
|
||||||
# http://www.wilderssecurity.com/threads/ublock-a-lean-and-fast-blocker.365273/page-25#post-2461804
|
# http://www.wilderssecurity.com/threads/ublock-a-lean-and-fast-blocker.365273/page-25#post-2461804
|
||||||
# Specific cosmetic filters for Youtube home page
|
# Specific cosmetic filters for Youtube home page
|
||||||
www.youtube.com##.masthead-ad-control
|
www.youtube.com##.masthead-ad-control
|
||||||
|
@ -93,7 +93,7 @@ return {
|
|||||||
|
|
||||||
// read-only
|
// read-only
|
||||||
systemSettings: {
|
systemSettings: {
|
||||||
compiledMagic: 'msgmqxreevdy',
|
compiledMagic: 'bxajckhlxyck',
|
||||||
selfieMagic: 'mnigwksyvgkv'
|
selfieMagic: 'mnigwksyvgkv'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -46,7 +46,6 @@ var µb = µBlock;
|
|||||||
|
|
||||||
var BlockAction = 0 << 0;
|
var BlockAction = 0 << 0;
|
||||||
var AllowAction = 1 << 0;
|
var AllowAction = 1 << 0;
|
||||||
var ToggleAction = BlockAction ^ AllowAction;
|
|
||||||
|
|
||||||
var Important = 1 << 1;
|
var Important = 1 << 1;
|
||||||
|
|
||||||
@ -214,6 +213,14 @@ var toHex = function(n) {
|
|||||||
return n.toString(16);
|
return n.toString(16);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var hostnameHit = function(hostname) {
|
||||||
|
return pageHostnameRegister.slice(0 - hostname.length) === hostname;
|
||||||
|
};
|
||||||
|
|
||||||
|
var hostnameMiss = function(hostname) {
|
||||||
|
return pageHostnameRegister.slice(1 - hostname.length) !== hostname.slice(1);
|
||||||
|
};
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
Filters family tree:
|
Filters family tree:
|
||||||
@ -277,10 +284,11 @@ var FilterPlainHostname = function(s, tokenBeg, hostname) {
|
|||||||
this.s = s;
|
this.s = s;
|
||||||
this.tokenBeg = tokenBeg;
|
this.tokenBeg = tokenBeg;
|
||||||
this.hostname = hostname;
|
this.hostname = hostname;
|
||||||
|
this.hostnameTest = hostname.charAt(0) !== '~' ? hostnameHit : hostnameMiss;
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPlainHostname.prototype.match = function(url, tokenBeg) {
|
FilterPlainHostname.prototype.match = function(url, tokenBeg) {
|
||||||
return pageHostnameRegister.slice(-this.hostname.length) === this.hostname &&
|
return this.hostnameTest(this.hostname) &&
|
||||||
url.substr(tokenBeg - this.tokenBeg, this.s.length) === this.s;
|
url.substr(tokenBeg - this.tokenBeg, this.s.length) === this.s;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -334,10 +342,11 @@ FilterPlainPrefix0.fromSelfie = function(s) {
|
|||||||
var FilterPlainPrefix0Hostname = function(s, hostname) {
|
var FilterPlainPrefix0Hostname = function(s, hostname) {
|
||||||
this.s = s;
|
this.s = s;
|
||||||
this.hostname = hostname;
|
this.hostname = hostname;
|
||||||
|
this.hostnameTest = hostname.charAt(0) !== '~' ? hostnameHit : hostnameMiss;
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPlainPrefix0Hostname.prototype.match = function(url, tokenBeg) {
|
FilterPlainPrefix0Hostname.prototype.match = function(url, tokenBeg) {
|
||||||
return pageHostnameRegister.slice(-this.hostname.length) === this.hostname &&
|
return this.hostnameTest(this.hostname) &&
|
||||||
url.substr(tokenBeg, this.s.length) === this.s;
|
url.substr(tokenBeg, this.s.length) === this.s;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -391,10 +400,11 @@ FilterPlainPrefix1.fromSelfie = function(s) {
|
|||||||
var FilterPlainPrefix1Hostname = function(s, hostname) {
|
var FilterPlainPrefix1Hostname = function(s, hostname) {
|
||||||
this.s = s;
|
this.s = s;
|
||||||
this.hostname = hostname;
|
this.hostname = hostname;
|
||||||
|
this.hostnameTest = hostname.charAt(0) !== '~' ? hostnameHit : hostnameMiss;
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPlainPrefix1Hostname.prototype.match = function(url, tokenBeg) {
|
FilterPlainPrefix1Hostname.prototype.match = function(url, tokenBeg) {
|
||||||
return pageHostnameRegister.slice(-this.hostname.length) === this.hostname &&
|
return this.hostnameTest(this.hostname) &&
|
||||||
url.substr(tokenBeg - 1, this.s.length) === this.s;
|
url.substr(tokenBeg - 1, this.s.length) === this.s;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -448,10 +458,11 @@ FilterPlainLeftAnchored.fromSelfie = function(s) {
|
|||||||
var FilterPlainLeftAnchoredHostname = function(s, hostname) {
|
var FilterPlainLeftAnchoredHostname = function(s, hostname) {
|
||||||
this.s = s;
|
this.s = s;
|
||||||
this.hostname = hostname;
|
this.hostname = hostname;
|
||||||
|
this.hostnameTest = hostname.charAt(0) !== '~' ? hostnameHit : hostnameMiss;
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPlainLeftAnchoredHostname.prototype.match = function(url) {
|
FilterPlainLeftAnchoredHostname.prototype.match = function(url) {
|
||||||
return pageHostnameRegister.slice(-this.hostname.length) === this.hostname &&
|
return this.hostnameTest(this.hostname) &&
|
||||||
url.slice(0, this.s.length) === this.s;
|
url.slice(0, this.s.length) === this.s;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -505,10 +516,11 @@ FilterPlainRightAnchored.fromSelfie = function(s) {
|
|||||||
var FilterPlainRightAnchoredHostname = function(s, hostname) {
|
var FilterPlainRightAnchoredHostname = function(s, hostname) {
|
||||||
this.s = s;
|
this.s = s;
|
||||||
this.hostname = hostname;
|
this.hostname = hostname;
|
||||||
|
this.hostnameTest = hostname.charAt(0) !== '~' ? hostnameHit : hostnameMiss;
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPlainRightAnchoredHostname.prototype.match = function(url) {
|
FilterPlainRightAnchoredHostname.prototype.match = function(url) {
|
||||||
return pageHostnameRegister.slice(-this.hostname.length) === this.hostname &&
|
return this.hostnameTest(this.hostname) &&
|
||||||
url.slice(-this.s.length) === this.s;
|
url.slice(-this.s.length) === this.s;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -575,10 +587,11 @@ FilterPlainHnAnchored.fromSelfie = function(s) {
|
|||||||
var FilterPlainHnAnchoredHostname = function(s, hostname) {
|
var FilterPlainHnAnchoredHostname = function(s, hostname) {
|
||||||
this.s = s;
|
this.s = s;
|
||||||
this.hostname = hostname;
|
this.hostname = hostname;
|
||||||
|
this.hostnameTest = hostname.charAt(0) !== '~' ? hostnameHit : hostnameMiss;
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPlainHnAnchoredHostname.prototype.match = function(url, tokenBeg) {
|
FilterPlainHnAnchoredHostname.prototype.match = function(url, tokenBeg) {
|
||||||
if ( pageHostnameRegister.slice(-this.hostname.length) !== this.hostname ) {
|
if ( this.hostnameTest(this.hostname) === false ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ( url.substr(tokenBeg, this.s.length) !== this.s ) {
|
if ( url.substr(tokenBeg, this.s.length) !== this.s ) {
|
||||||
@ -650,12 +663,13 @@ FilterGeneric.fromSelfie = function(s) {
|
|||||||
var FilterGenericHostname = function(s, anchor, hostname) {
|
var FilterGenericHostname = function(s, anchor, hostname) {
|
||||||
FilterGeneric.call(this, s, anchor);
|
FilterGeneric.call(this, s, anchor);
|
||||||
this.hostname = hostname;
|
this.hostname = hostname;
|
||||||
|
this.hostnameTest = hostname.charAt(0) !== '~' ? hostnameHit : hostnameMiss;
|
||||||
};
|
};
|
||||||
FilterGenericHostname.prototype = Object.create(FilterGeneric.prototype);
|
FilterGenericHostname.prototype = Object.create(FilterGeneric.prototype);
|
||||||
FilterGenericHostname.prototype.constructor = FilterGenericHostname;
|
FilterGenericHostname.prototype.constructor = FilterGenericHostname;
|
||||||
|
|
||||||
FilterGenericHostname.prototype.match = function(url) {
|
FilterGenericHostname.prototype.match = function(url) {
|
||||||
if ( pageHostnameRegister.slice(-this.hostname.length) !== this.hostname ) {
|
if ( this.hostnameTest(this.hostname) === false ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return FilterGeneric.prototype.match.call(this, url);
|
return FilterGeneric.prototype.match.call(this, url);
|
||||||
@ -728,12 +742,13 @@ FilterGenericHnAnchored.fromSelfie = function(s) {
|
|||||||
var FilterGenericHnAnchoredHostname = function(s, hostname) {
|
var FilterGenericHnAnchoredHostname = function(s, hostname) {
|
||||||
FilterGenericHnAnchored.call(this, s);
|
FilterGenericHnAnchored.call(this, s);
|
||||||
this.hostname = hostname;
|
this.hostname = hostname;
|
||||||
|
this.hostnameTest = hostname.charAt(0) !== '~' ? hostnameHit : hostnameMiss;
|
||||||
};
|
};
|
||||||
FilterGenericHnAnchoredHostname.prototype = Object.create(FilterGenericHnAnchored.prototype);
|
FilterGenericHnAnchoredHostname.prototype = Object.create(FilterGenericHnAnchored.prototype);
|
||||||
FilterGenericHnAnchoredHostname.prototype.constructor = FilterGenericHnAnchoredHostname;
|
FilterGenericHnAnchoredHostname.prototype.constructor = FilterGenericHnAnchoredHostname;
|
||||||
|
|
||||||
FilterGenericHnAnchoredHostname.prototype.match = function(url) {
|
FilterGenericHnAnchoredHostname.prototype.match = function(url) {
|
||||||
if ( pageHostnameRegister.slice(-this.hostname.length) !== this.hostname ) {
|
if ( this.hostnameTest(this.hostname) === false ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return FilterGenericHnAnchored.prototype.match.call(this, url);
|
return FilterGenericHnAnchored.prototype.match.call(this, url);
|
||||||
@ -791,11 +806,12 @@ FilterRegex.fromSelfie = function(s) {
|
|||||||
var FilterRegexHostname = function(s, hostname) {
|
var FilterRegexHostname = function(s, hostname) {
|
||||||
this.re = new RegExp(s);
|
this.re = new RegExp(s);
|
||||||
this.hostname = hostname;
|
this.hostname = hostname;
|
||||||
|
this.hostnameTest = hostname.charAt(0) !== '~' ? hostnameHit : hostnameMiss;
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterRegexHostname.prototype.match = function(url) {
|
FilterRegexHostname.prototype.match = function(url) {
|
||||||
// test hostname first, it's cheaper than evaluating a regex
|
// test hostname first, it's cheaper than evaluating a regex
|
||||||
return pageHostnameRegister.slice(-this.hostname.length) === this.hostname &&
|
return this.hostnameTest(this.hostname) &&
|
||||||
this.re.test(url);
|
this.re.test(url);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1217,7 +1233,6 @@ var FilterParser = function() {
|
|||||||
this.reIsolateHostname = /^([^\x00-\x24\x26-\x2C\x2F\x3A-\x5E\x60\x7B-\x7F]+)(.*)/;
|
this.reIsolateHostname = /^([^\x00-\x24\x26-\x2C\x2F\x3A-\x5E\x60\x7B-\x7F]+)(.*)/;
|
||||||
this.reHasUnicode = /[^\x00-\x7F]/;
|
this.reHasUnicode = /[^\x00-\x7F]/;
|
||||||
this.hostnames = [];
|
this.hostnames = [];
|
||||||
this.notHostnames = [];
|
|
||||||
this.reset();
|
this.reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1251,7 +1266,6 @@ FilterParser.prototype.reset = function() {
|
|||||||
this.hostnameAnchored = false;
|
this.hostnameAnchored = false;
|
||||||
this.hostnamePure = false;
|
this.hostnamePure = false;
|
||||||
this.hostnames.length = 0;
|
this.hostnames.length = 0;
|
||||||
this.notHostnames.length = 0;
|
|
||||||
this.isRegex = false;
|
this.isRegex = false;
|
||||||
this.thirdParty = false;
|
this.thirdParty = false;
|
||||||
this.token = '';
|
this.token = '';
|
||||||
@ -1301,14 +1315,8 @@ FilterParser.prototype.parseOptParty = function(firstParty, not) {
|
|||||||
|
|
||||||
FilterParser.prototype.parseOptHostnames = function(raw) {
|
FilterParser.prototype.parseOptHostnames = function(raw) {
|
||||||
var hostnames = raw.split('|');
|
var hostnames = raw.split('|');
|
||||||
var hostname;
|
|
||||||
for ( var i = 0; i < hostnames.length; i++ ) {
|
for ( var i = 0; i < hostnames.length; i++ ) {
|
||||||
hostname = hostnames[i];
|
this.hostnames.push(hostnames[i]);
|
||||||
if ( hostname.charAt(0) === '~' ) {
|
|
||||||
this.notHostnames.push(hostname.slice(1));
|
|
||||||
} else {
|
|
||||||
this.hostnames.push(hostname);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1793,7 +1801,7 @@ FilterContainer.prototype.compile = function(raw, out) {
|
|||||||
|
|
||||||
FilterContainer.prototype.compileHostnameOnlyFilter = function(parsed, out) {
|
FilterContainer.prototype.compileHostnameOnlyFilter = function(parsed, out) {
|
||||||
// Can't fit the filter in a pure hostname dictionary.
|
// Can't fit the filter in a pure hostname dictionary.
|
||||||
if ( parsed.hostnames.length !== 0 || parsed.notHostnames.length !== 0 ) {
|
if ( parsed.hostnames.length !== 0 ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1846,10 +1854,9 @@ FilterContainer.prototype.compileFilter = function(parsed, out) {
|
|||||||
|
|
||||||
var filterClass;
|
var filterClass;
|
||||||
var i = parsed.hostnames.length;
|
var i = parsed.hostnames.length;
|
||||||
var j = parsed.notHostnames.length;
|
|
||||||
|
|
||||||
// Applies to all domains without exceptions
|
// Applies everywhere
|
||||||
if ( i === 0 && j === 0 ) {
|
if ( i === 0 ) {
|
||||||
filterClass = getFilterClass(parsed);
|
filterClass = getFilterClass(parsed);
|
||||||
if ( filterClass === null ) {
|
if ( filterClass === null ) {
|
||||||
return false;
|
return false;
|
||||||
@ -1859,55 +1866,14 @@ FilterContainer.prototype.compileFilter = function(parsed, out) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Applies to specific domains
|
// Applies to specific domains
|
||||||
if ( i !== 0 ) {
|
while ( i-- ) {
|
||||||
while ( i-- ) {
|
|
||||||
filterClass = getHostnameBasedFilterClass(parsed);
|
|
||||||
if ( filterClass === null ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
this.compileToAtomicFilter(filterClass, parsed, party, out, parsed.hostnames[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// No exceptions
|
|
||||||
if ( j === 0 ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Case:
|
|
||||||
// - applies everywhere except to specific domains
|
|
||||||
// Example:
|
|
||||||
// - ||adm.fwmrm.net/p/msnbc_live/$object-subrequest,third-party,domain=~msnbc.msn.com|~www.nbcnews.com
|
|
||||||
if ( i === 0 ) {
|
|
||||||
filterClass = getFilterClass(parsed);
|
|
||||||
if ( filterClass === null ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// https://github.com/chrisaljoudi/uBlock/issues/251
|
|
||||||
// Apply third-party option if it is present
|
|
||||||
this.compileToAtomicFilter(filterClass, parsed, party, out);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cases:
|
|
||||||
// - applies everywhere except to specific domains
|
|
||||||
// - applies to specific domains except other specific domains
|
|
||||||
// Example:
|
|
||||||
// - /^https?\:\/\/(?!(...)\/)/$script,third-party,xmlhttprequest,domain=photobucket.com|~secure.photobucket.com
|
|
||||||
|
|
||||||
// Reverse purpose of filter
|
|
||||||
parsed.action ^= ToggleAction;
|
|
||||||
while ( j-- ) {
|
|
||||||
filterClass = getHostnameBasedFilterClass(parsed);
|
filterClass = getHostnameBasedFilterClass(parsed);
|
||||||
if ( filterClass === null ) {
|
if ( filterClass === null ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// https://github.com/chrisaljoudi/uBlock/issues/191#issuecomment-53654024
|
this.compileToAtomicFilter(filterClass, parsed, party, out, parsed.hostnames[i]);
|
||||||
// If it is a block filter, we need to reverse the order of
|
|
||||||
// evaluation.
|
|
||||||
if ( parsed.action === BlockAction ) {
|
|
||||||
parsed.important = Important;
|
|
||||||
}
|
|
||||||
this.compileToAtomicFilter(filterClass, parsed, party, out, parsed.notHostnames[j]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user