mirror of
https://github.com/gorhill/uBlock.git
synced 2024-11-07 03:12:33 +01:00
this fixes #59: now accurately reporting static filters in logger
This commit is contained in:
parent
323378fb38
commit
2234933b82
@ -104,7 +104,7 @@ var proceedPermanent = function() {
|
||||
/******************************************************************************/
|
||||
|
||||
uDom('.what').text(details.url);
|
||||
uDom('#why').text(details.why.slice(3));
|
||||
uDom('#why').text(details.why);
|
||||
|
||||
if ( window.history.length > 1 ) {
|
||||
uDom('#back').on('click', function() { window.history.back(); });
|
||||
|
@ -103,61 +103,24 @@ var tabIdFromClassName = function(className) {
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var retextFromStaticFilteringResult = function(result) {
|
||||
var retext = result.slice(3);
|
||||
var pos = retext.indexOf('$');
|
||||
if ( pos > 0 ) {
|
||||
retext = retext.slice(0, pos);
|
||||
}
|
||||
if ( retext === '*' ) {
|
||||
return '^.*$';
|
||||
}
|
||||
if ( retext.charAt(0) === '/' && retext.slice(-1) === '/' ) {
|
||||
return retext.slice(1, -1);
|
||||
}
|
||||
return retext
|
||||
.replace(/\./g, '\\.')
|
||||
.replace(/\?/g, '\\?')
|
||||
.replace('||', '')
|
||||
.replace(/\^/g, '.')
|
||||
.replace(/^\|/g, '^')
|
||||
.replace(/\|$/g, '$')
|
||||
.replace(/\*/g, '.*')
|
||||
;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var retextFromURLFilteringResult = function(result) {
|
||||
var regexFromURLFilteringResult = function(result) {
|
||||
var beg = result.indexOf(' ');
|
||||
var end = result.indexOf(' ', beg + 1);
|
||||
var url = result.slice(beg + 1, end);
|
||||
if ( url === '*' ) {
|
||||
return '^.*$';
|
||||
return new RegExp('^.*$', 'gi');
|
||||
}
|
||||
return '^' + url.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
return new RegExp('^' + url.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'gi');
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// Emphasize hostname in URL, as this is what matters in uMatrix's rules.
|
||||
|
||||
var nodeFromURL = function(url, filter) {
|
||||
var filterType = filter.charAt(0);
|
||||
if ( filterType !== 's' && filterType !== 'l' ) {
|
||||
var nodeFromURL = function(url, re) {
|
||||
if ( re instanceof RegExp === false ) {
|
||||
return document.createTextNode(url);
|
||||
}
|
||||
// make a regex out of the filter
|
||||
var retext = '';
|
||||
if ( filterType === 's' ) {
|
||||
retext = retextFromStaticFilteringResult(filter);
|
||||
} else if ( filterType === 'l' ) {
|
||||
retext = retextFromURLFilteringResult(filter);
|
||||
}
|
||||
if ( retext === '' ) {
|
||||
return document.createTextNode(url);
|
||||
}
|
||||
var re = new RegExp(retext, 'gi');
|
||||
var matches = re.exec(url);
|
||||
if ( matches === null || matches[0].length === 0 ) {
|
||||
return document.createTextNode(url);
|
||||
@ -173,6 +136,187 @@ var renderedURLTemplate = document.querySelector('#renderedURLTemplate > span');
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// Pretty much same logic as found in:
|
||||
// µBlock.staticNetFilteringEngine.filterStringFromCompiled
|
||||
// µBlock.staticNetFilteringEngine.filterRegexFromCompiled
|
||||
|
||||
var filterDecompiler = (function() {
|
||||
var typeValToTypeName = {
|
||||
1: 'stylesheet',
|
||||
2: 'image',
|
||||
3: 'object',
|
||||
4: 'script',
|
||||
5: 'xmlhttprequest',
|
||||
6: 'sub_frame',
|
||||
7: 'font',
|
||||
8: 'other',
|
||||
13: 'elemhide',
|
||||
14: 'inline-script',
|
||||
15: 'popup'
|
||||
};
|
||||
|
||||
var toString = function(compiled) {
|
||||
var opts = [];
|
||||
var vfields = compiled.split('\v');
|
||||
var filter = '';
|
||||
var bits = parseInt(vfields[1], 16) | 0;
|
||||
|
||||
if ( bits & 0x01 ) {
|
||||
filter += '@@';
|
||||
}
|
||||
|
||||
var fid = vfields[2] === '.' ? '.' : vfields[3];
|
||||
var tfields = fid !== '.' ? vfields[4].split('\t') : [];
|
||||
var tfield0 = tfields[0];
|
||||
|
||||
switch ( fid ) {
|
||||
case '.':
|
||||
filter += '||' + vfields[3] + '^';
|
||||
break;
|
||||
case 'a':
|
||||
case 'ah':
|
||||
case '0a':
|
||||
case '0ah':
|
||||
case '1a':
|
||||
case '1ah':
|
||||
case '_':
|
||||
case '_h':
|
||||
filter += tfield0;
|
||||
// If the filter resemble a regex, add a trailing `*` as is
|
||||
// customary to prevent ambiguity in logger.
|
||||
if ( tfield0.charAt(0) === '/' && tfield0.slice(-1) === '/' ) {
|
||||
filter += '*';
|
||||
}
|
||||
break;
|
||||
case '|a':
|
||||
case '|ah':
|
||||
filter += '|' + tfield0;
|
||||
break;
|
||||
case 'a|':
|
||||
case 'a|h':
|
||||
filter += tfield0 + '|';
|
||||
break;
|
||||
case '||a':
|
||||
case '||ah':
|
||||
case '||_':
|
||||
case '||_h':
|
||||
filter += '||' + tfield0;
|
||||
break;
|
||||
case '//':
|
||||
case '//h':
|
||||
filter += '/' + tfield0 + '/';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Domain option?
|
||||
switch ( fid ) {
|
||||
case '0ah':
|
||||
case '1ah':
|
||||
case '|ah':
|
||||
case 'a|h':
|
||||
case '||ah':
|
||||
case '||_h':
|
||||
case '//h':
|
||||
opts.push('domain=' + tfields[1]);
|
||||
break;
|
||||
case 'ah':
|
||||
case '_h':
|
||||
opts.push('domain=' + tfields[2]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Filter options
|
||||
if ( bits & 0x02 ) {
|
||||
opts.push('important');
|
||||
}
|
||||
if ( bits & 0x08 ) {
|
||||
opts.push('third-party');
|
||||
} else if ( bits & 0x04 ) {
|
||||
opts.push('first-party');
|
||||
}
|
||||
var typeVal = bits >>> 4 & 0x0F;
|
||||
if ( typeVal ) {
|
||||
opts.push(typeValToTypeName[typeVal]);
|
||||
// Because of the way `elemhide` is implemented
|
||||
if ( typeVal === 13 ) {
|
||||
filter = '@@' + filter;
|
||||
}
|
||||
}
|
||||
if ( opts.length !== 0 ) {
|
||||
filter += '$' + opts.join(',');
|
||||
}
|
||||
|
||||
return filter;
|
||||
};
|
||||
|
||||
var reEscape = /[.+?^${}()|[\]\\]/g;
|
||||
var reWildcards = /\*+/g;
|
||||
|
||||
var toRegex = function(compiled) {
|
||||
var vfields = compiled.split('\v');
|
||||
var fid = vfields[2] === '.' ? '.' : vfields[3];
|
||||
var tfields = fid !== '.' ? vfields[4].split('\t') : [];
|
||||
var reStr;
|
||||
|
||||
switch ( fid ) {
|
||||
case '.':
|
||||
reStr = vfields[3]
|
||||
.replace(reEscape, '\\$&');
|
||||
break;
|
||||
case 'a':
|
||||
case 'ah':
|
||||
case '0a':
|
||||
case '0ah':
|
||||
case '1a':
|
||||
case '1ah':
|
||||
case '_':
|
||||
case '_h':
|
||||
case '||a':
|
||||
case '||ah':
|
||||
case '||_':
|
||||
case '||_h':
|
||||
reStr = tfields[0]
|
||||
.replace(reEscape, '\\$&')
|
||||
.replace(reWildcards, '.*');
|
||||
break;
|
||||
case '|a':
|
||||
case '|ah':
|
||||
reStr = '^' + tfields[0].
|
||||
replace(reEscape, '\\$&')
|
||||
.replace(reWildcards, '.*');
|
||||
break;
|
||||
case 'a|':
|
||||
case 'a|h':
|
||||
reStr = tfields[0]
|
||||
.replace(reEscape, '\\$&')
|
||||
.replace(reWildcards, '.*') + '$';
|
||||
break;
|
||||
case '//':
|
||||
case '//h':
|
||||
reStr = tfields[0];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ( reStr === undefined) {
|
||||
return null;
|
||||
}
|
||||
return new RegExp(reStr, 'gi');
|
||||
};
|
||||
|
||||
return {
|
||||
toString: toString,
|
||||
toRegex: toRegex
|
||||
};
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var createCellAt = function(tr, index) {
|
||||
var td = tr.cells[index];
|
||||
var mustAppend = !td;
|
||||
@ -276,26 +420,31 @@ var renderNetLogEntry = function(tr, entry) {
|
||||
tr.setAttribute('data-hn-frame', entry.d4);
|
||||
}
|
||||
|
||||
// Cosmetic filter?
|
||||
var filterCat = filter.slice(0, 3);
|
||||
if ( filterCat.charAt(2) === ':' ) {
|
||||
tr.classList.add(filterCat.slice(0, 2));
|
||||
}
|
||||
|
||||
var filterText = filter.slice(3);
|
||||
if ( filter.lastIndexOf('sa', 0) === 0 ) {
|
||||
filterText = '@@' + filterText;
|
||||
var filteringType = filterCat.charAt(0);
|
||||
td = tr.cells[2];
|
||||
if ( filter !== '' ) {
|
||||
filter = filter.slice(3);
|
||||
if ( filteringType === 's' ) {
|
||||
td.textContent = filterDecompiler.toString(filter);
|
||||
} else {
|
||||
td.textContent = filter;
|
||||
}
|
||||
}
|
||||
tr.cells[2].textContent = filterText;
|
||||
|
||||
td = tr.cells[3];
|
||||
if ( filter.charAt(1) === 'b' ) {
|
||||
var filteringOp = filterCat.charAt(1);
|
||||
if ( filteringOp === 'b' ) {
|
||||
tr.classList.add('blocked');
|
||||
td.textContent = '--';
|
||||
} else if ( filter.charAt(1) === 'a' ) {
|
||||
} else if ( filteringOp === 'a' ) {
|
||||
tr.classList.add('allowed');
|
||||
td.textContent = '++';
|
||||
} else if ( filter.charAt(1) === 'n' ) {
|
||||
} else if ( filteringOp === 'n' ) {
|
||||
tr.classList.add('nooped');
|
||||
td.textContent = '**';
|
||||
} else {
|
||||
@ -303,7 +452,14 @@ var renderNetLogEntry = function(tr, entry) {
|
||||
}
|
||||
|
||||
tr.cells[4].textContent = (prettyRequestTypes[type] || type);
|
||||
tr.cells[5].appendChild(nodeFromURL(url, filter));
|
||||
|
||||
var re = null;
|
||||
if ( filteringType === 's' ) {
|
||||
re = filterDecompiler.toRegex(filter);
|
||||
} else if ( filteringType === 'l' ) {
|
||||
re = regexFromURLFilteringResult(filter);
|
||||
}
|
||||
tr.cells[5].appendChild(nodeFromURL(url, re));
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -114,7 +114,7 @@ NetFilteringResultCache.factory = function() {
|
||||
NetFilteringResultCache.prototype.init = function() {
|
||||
this.urls = {};
|
||||
this.count = 0;
|
||||
this.shelfLife = 60 * 1000;
|
||||
this.shelfLife = 15 * 1000;
|
||||
this.timer = null;
|
||||
this.boundPruneAsyncCallback = this.pruneAsyncCallback.bind(this);
|
||||
};
|
||||
@ -309,11 +309,22 @@ PageStore.prototype.init = function(tabId) {
|
||||
|
||||
// Support `elemhide` filter option. Called at this point so the required
|
||||
// context is all setup at this point.
|
||||
var context = this.createContextFromPage();
|
||||
this.skipCosmeticFiltering = µb.staticNetFilteringEngine
|
||||
.matchStringExactType(context, tabContext.normalURL, 'cosmetic-filtering')
|
||||
.charAt(1) === 'b';
|
||||
|
||||
this.skipCosmeticFiltering = µb.staticNetFilteringEngine.matchStringExactType(
|
||||
this.createContextFromPage(),
|
||||
tabContext.normalURL,
|
||||
'cosmetic-filtering'
|
||||
);
|
||||
if ( this.skipCosmeticFiltering && µb.logger.isEnabled() ) {
|
||||
µb.logger.writeOne(
|
||||
tabId,
|
||||
'net',
|
||||
µb.staticNetFilteringEngine.toResultString(true),
|
||||
'elemhide',
|
||||
tabContext.rawURL,
|
||||
this.tabHostname,
|
||||
this.tabHostname
|
||||
);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
@ -515,7 +526,9 @@ PageStore.prototype.filterRequest = function(context) {
|
||||
|
||||
// Static filtering never override dynamic filtering
|
||||
if ( result === '' || result.charAt(1) === 'n' ) {
|
||||
result = µb.staticNetFilteringEngine.matchString(context) || result;
|
||||
if ( µb.staticNetFilteringEngine.matchString(context) ) {
|
||||
result = µb.staticNetFilteringEngine.toResultString(µb.logger.isEnabled());
|
||||
}
|
||||
}
|
||||
|
||||
//console.debug('cache MISS: PageStore.filterRequest("%s")', context.requestURL);
|
||||
@ -555,7 +568,9 @@ PageStore.prototype.filterRequestNoCache = function(context) {
|
||||
|
||||
// Static filtering never override dynamic filtering
|
||||
if ( result === '' || result.charAt(1) === 'n' ) {
|
||||
result = µb.staticNetFilteringEngine.matchString(context) || result;
|
||||
if ( µb.staticNetFilteringEngine.matchString(context) ) {
|
||||
result = µb.staticNetFilteringEngine.toResultString(µb.logger.isEnabled());
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
|
||||
µBlock - a browser extension to block requests.
|
||||
Copyright (C) 2014 Raymond Hill
|
||||
uBlock - a browser extension to block requests.
|
||||
Copyright (C) 2014-2015 Raymond Hill
|
||||
|
||||
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
|
||||
@ -70,6 +70,20 @@ var typeNameToTypeValue = {
|
||||
};
|
||||
var typeOtherValue = typeNameToTypeValue.other;
|
||||
|
||||
var typeValueToTypeName = {
|
||||
1: 'stylesheet',
|
||||
2: 'image',
|
||||
3: 'object',
|
||||
4: 'script',
|
||||
5: 'xmlhttprequest',
|
||||
6: 'sub_frame',
|
||||
7: 'font',
|
||||
8: 'other',
|
||||
13: 'cosmetic-filtering',
|
||||
14: 'inline-script',
|
||||
15: 'popup'
|
||||
};
|
||||
|
||||
// All network request types to bitmap
|
||||
// bring origin to 0 (from 4 -- see typeNameToTypeValue)
|
||||
// left-shift 1 by the above-calculated value
|
||||
@ -175,7 +189,7 @@ var alwaysTruePseudoRegex = {
|
||||
}
|
||||
};
|
||||
|
||||
var strToRegex = function(s, anchor) {
|
||||
var strToRegex = function(s, anchor, flags) {
|
||||
// https://github.com/chrisaljoudi/uBlock/issues/1038
|
||||
// Special case: always match.
|
||||
if ( s === '*' ) {
|
||||
@ -193,7 +207,7 @@ var strToRegex = function(s, anchor) {
|
||||
}
|
||||
|
||||
//console.debug('µBlock.staticNetFilteringEngine: created RegExp("%s")', reStr);
|
||||
return new RegExp(reStr);
|
||||
return new RegExp(reStr, flags);
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
@ -235,15 +249,13 @@ FilterPlain.prototype.match = function(url, tokenBeg) {
|
||||
return url.substr(tokenBeg - this.tokenBeg, this.s.length) === this.s;
|
||||
};
|
||||
|
||||
FilterPlain.fid = FilterPlain.prototype.fid = 'a';
|
||||
FilterPlain.fid =
|
||||
FilterPlain.prototype.fid =
|
||||
FilterPlain.prototype.rtfid = 'a';
|
||||
|
||||
FilterPlain.prototype.toString = function() {
|
||||
return this.s;
|
||||
};
|
||||
|
||||
FilterPlain.prototype.toSelfie = function() {
|
||||
return this.s + '\t' +
|
||||
this.tokenBeg;
|
||||
FilterPlain.prototype.toSelfie =
|
||||
FilterPlain.prototype.rtCompile = function() {
|
||||
return this.s + '\t' + this.tokenBeg;
|
||||
};
|
||||
|
||||
FilterPlain.compile = function(details) {
|
||||
@ -268,22 +280,17 @@ FilterPlainHostname.prototype.match = function(url, tokenBeg) {
|
||||
url.substr(tokenBeg - this.tokenBeg, this.s.length) === this.s;
|
||||
};
|
||||
|
||||
FilterPlainHostname.fid = FilterPlainHostname.prototype.fid = 'ah';
|
||||
FilterPlainHostname.fid =
|
||||
FilterPlainHostname.prototype.fid =
|
||||
FilterPlainHostname.prototype.rtfid = 'ah';
|
||||
|
||||
FilterPlainHostname.prototype.toString = function() {
|
||||
return this.s + '$domain=' + this.hostname;
|
||||
};
|
||||
|
||||
FilterPlainHostname.prototype.toSelfie = function() {
|
||||
return this.s + '\t' +
|
||||
this.tokenBeg + '\t' +
|
||||
this.hostname;
|
||||
FilterPlainHostname.prototype.toSelfie =
|
||||
FilterPlainHostname.prototype.rtCompile = function() {
|
||||
return this.s + '\t' + this.tokenBeg + '\t' + this.hostname;
|
||||
};
|
||||
|
||||
FilterPlainHostname.compile = function(details, hostname) {
|
||||
return details.f + '\t' +
|
||||
details.tokenBeg + '\t' +
|
||||
hostname;
|
||||
return details.f + '\t' + details.tokenBeg + '\t' + hostname;
|
||||
};
|
||||
|
||||
FilterPlainHostname.fromSelfie = function(s) {
|
||||
@ -301,13 +308,12 @@ FilterPlainPrefix0.prototype.match = function(url, tokenBeg) {
|
||||
return url.substr(tokenBeg, this.s.length) === this.s;
|
||||
};
|
||||
|
||||
FilterPlainPrefix0.fid = FilterPlainPrefix0.prototype.fid = '0a';
|
||||
FilterPlainPrefix0.fid =
|
||||
FilterPlainPrefix0.prototype.fid =
|
||||
FilterPlainPrefix0.prototype.rtfid = '0a';
|
||||
|
||||
FilterPlainPrefix0.prototype.toString = function() {
|
||||
return this.s;
|
||||
};
|
||||
|
||||
FilterPlainPrefix0.prototype.toSelfie = function() {
|
||||
FilterPlainPrefix0.prototype.toSelfie =
|
||||
FilterPlainPrefix0.prototype.rtCompile = function() {
|
||||
return this.s;
|
||||
};
|
||||
|
||||
@ -331,15 +337,13 @@ FilterPlainPrefix0Hostname.prototype.match = function(url, tokenBeg) {
|
||||
url.substr(tokenBeg, this.s.length) === this.s;
|
||||
};
|
||||
|
||||
FilterPlainPrefix0Hostname.fid = FilterPlainPrefix0Hostname.prototype.fid = '0ah';
|
||||
FilterPlainPrefix0Hostname.fid =
|
||||
FilterPlainPrefix0Hostname.prototype.fid =
|
||||
FilterPlainPrefix0Hostname.prototype.rtfid = '0ah';
|
||||
|
||||
FilterPlainPrefix0Hostname.prototype.toString = function() {
|
||||
return this.s + '$domain=' + this.hostname;
|
||||
};
|
||||
|
||||
FilterPlainPrefix0Hostname.prototype.toSelfie = function() {
|
||||
return this.s + '\t' +
|
||||
this.hostname;
|
||||
FilterPlainPrefix0Hostname.prototype.toSelfie =
|
||||
FilterPlainPrefix0Hostname.prototype.rtCompile = function() {
|
||||
return this.s + '\t' + this.hostname;
|
||||
};
|
||||
|
||||
FilterPlainPrefix0Hostname.compile = function(details, hostname) {
|
||||
@ -361,13 +365,12 @@ FilterPlainPrefix1.prototype.match = function(url, tokenBeg) {
|
||||
return url.substr(tokenBeg - 1, this.s.length) === this.s;
|
||||
};
|
||||
|
||||
FilterPlainPrefix1.fid = FilterPlainPrefix1.prototype.fid = '1a';
|
||||
FilterPlainPrefix1.fid =
|
||||
FilterPlainPrefix1.prototype.fid =
|
||||
FilterPlainPrefix1.prototype.rtfid = '1a';
|
||||
|
||||
FilterPlainPrefix1.prototype.toString = function() {
|
||||
return this.s;
|
||||
};
|
||||
|
||||
FilterPlainPrefix1.prototype.toSelfie = function() {
|
||||
FilterPlainPrefix1.prototype.toSelfie =
|
||||
FilterPlainPrefix1.prototype.rtCompile = function() {
|
||||
return this.s;
|
||||
};
|
||||
|
||||
@ -391,15 +394,13 @@ FilterPlainPrefix1Hostname.prototype.match = function(url, tokenBeg) {
|
||||
url.substr(tokenBeg - 1, this.s.length) === this.s;
|
||||
};
|
||||
|
||||
FilterPlainPrefix1Hostname.fid = FilterPlainPrefix1Hostname.prototype.fid = '1ah';
|
||||
FilterPlainPrefix1Hostname.fid =
|
||||
FilterPlainPrefix1Hostname.prototype.fid =
|
||||
FilterPlainPrefix1Hostname.prototype.rtfid = '1ah';
|
||||
|
||||
FilterPlainPrefix1Hostname.prototype.toString = function() {
|
||||
return this.s + '$domain=' + this.hostname;
|
||||
};
|
||||
|
||||
FilterPlainPrefix1Hostname.prototype.toSelfie = function() {
|
||||
return this.s + '\t' +
|
||||
this.hostname;
|
||||
FilterPlainPrefix1Hostname.prototype.toSelfie =
|
||||
FilterPlainPrefix1Hostname.prototype.rtCompile = function() {
|
||||
return this.s + '\t' + this.hostname;
|
||||
};
|
||||
|
||||
FilterPlainPrefix1Hostname.compile = function(details, hostname) {
|
||||
@ -421,13 +422,12 @@ FilterPlainLeftAnchored.prototype.match = function(url) {
|
||||
return url.slice(0, this.s.length) === this.s;
|
||||
};
|
||||
|
||||
FilterPlainLeftAnchored.fid = FilterPlainLeftAnchored.prototype.fid = '|a';
|
||||
FilterPlainLeftAnchored.fid =
|
||||
FilterPlainLeftAnchored.prototype.fid =
|
||||
FilterPlainLeftAnchored.prototype.rtfid = '|a';
|
||||
|
||||
FilterPlainLeftAnchored.prototype.toString = function() {
|
||||
return '|' + this.s;
|
||||
};
|
||||
|
||||
FilterPlainLeftAnchored.prototype.toSelfie = function() {
|
||||
FilterPlainLeftAnchored.prototype.toSelfie =
|
||||
FilterPlainLeftAnchored.prototype.rtCompile = function() {
|
||||
return this.s;
|
||||
};
|
||||
|
||||
@ -451,15 +451,13 @@ FilterPlainLeftAnchoredHostname.prototype.match = function(url) {
|
||||
url.slice(0, this.s.length) === this.s;
|
||||
};
|
||||
|
||||
FilterPlainLeftAnchoredHostname.fid = FilterPlainLeftAnchoredHostname.prototype.fid = '|ah';
|
||||
FilterPlainLeftAnchoredHostname.fid =
|
||||
FilterPlainLeftAnchoredHostname.prototype.fid =
|
||||
FilterPlainLeftAnchoredHostname.prototype.rtfid = '|ah';
|
||||
|
||||
FilterPlainLeftAnchoredHostname.prototype.toString = function() {
|
||||
return '|' + this.s + '$domain=' + this.hostname;
|
||||
};
|
||||
|
||||
FilterPlainLeftAnchoredHostname.prototype.toSelfie = function() {
|
||||
return this.s + '\t' +
|
||||
this.hostname;
|
||||
FilterPlainLeftAnchoredHostname.prototype.toSelfie =
|
||||
FilterPlainLeftAnchoredHostname.prototype.rtCompile = function() {
|
||||
return this.s + '\t' + this.hostname;
|
||||
};
|
||||
|
||||
FilterPlainLeftAnchoredHostname.compile = function(details, hostname) {
|
||||
@ -481,13 +479,12 @@ FilterPlainRightAnchored.prototype.match = function(url) {
|
||||
return url.slice(-this.s.length) === this.s;
|
||||
};
|
||||
|
||||
FilterPlainRightAnchored.fid = FilterPlainRightAnchored.prototype.fid = 'a|';
|
||||
FilterPlainRightAnchored.fid =
|
||||
FilterPlainRightAnchored.prototype.fid =
|
||||
FilterPlainRightAnchored.prototype.rtfid = 'a|';
|
||||
|
||||
FilterPlainRightAnchored.prototype.toString = function() {
|
||||
return this.s + '|';
|
||||
};
|
||||
|
||||
FilterPlainRightAnchored.prototype.toSelfie = function() {
|
||||
FilterPlainRightAnchored.prototype.toSelfie =
|
||||
FilterPlainRightAnchored.prototype.rtCompile = function() {
|
||||
return this.s;
|
||||
};
|
||||
|
||||
@ -511,15 +508,13 @@ FilterPlainRightAnchoredHostname.prototype.match = function(url) {
|
||||
url.slice(-this.s.length) === this.s;
|
||||
};
|
||||
|
||||
FilterPlainRightAnchoredHostname.fid = FilterPlainRightAnchoredHostname.prototype.fid = 'a|h';
|
||||
FilterPlainRightAnchoredHostname.fid =
|
||||
FilterPlainRightAnchoredHostname.prototype.fid =
|
||||
FilterPlainRightAnchoredHostname.prototype.rtfid = 'a|h';
|
||||
|
||||
FilterPlainRightAnchoredHostname.prototype.toString = function() {
|
||||
return this.s + '|$domain=' + this.hostname;
|
||||
};
|
||||
|
||||
FilterPlainRightAnchoredHostname.prototype.toSelfie = function() {
|
||||
return this.s + '\t' +
|
||||
this.hostname;
|
||||
FilterPlainRightAnchoredHostname.prototype.toSelfie =
|
||||
FilterPlainRightAnchoredHostname.prototype.rtCompile = function() {
|
||||
return this.s + '\t' + this.hostname;
|
||||
};
|
||||
|
||||
FilterPlainRightAnchoredHostname.compile = function(details, hostname) {
|
||||
@ -550,13 +545,12 @@ FilterPlainHnAnchored.prototype.match = function(url, tokenBeg) {
|
||||
reURLPostHostnameAnchors.test(url.slice(pos + 3, tokenBeg)) === false;
|
||||
};
|
||||
|
||||
FilterPlainHnAnchored.fid = FilterPlainHnAnchored.prototype.fid = '||a';
|
||||
FilterPlainHnAnchored.fid =
|
||||
FilterPlainHnAnchored.prototype.fid =
|
||||
FilterPlainHnAnchored.prototype.rtfid = '||a';
|
||||
|
||||
FilterPlainHnAnchored.prototype.toString = function() {
|
||||
return '||' + this.s;
|
||||
};
|
||||
|
||||
FilterPlainHnAnchored.prototype.toSelfie = function() {
|
||||
FilterPlainHnAnchored.prototype.toSelfie =
|
||||
FilterPlainHnAnchored.prototype.rtCompile = function() {
|
||||
return this.s;
|
||||
};
|
||||
|
||||
@ -592,13 +586,12 @@ FilterPlainHnAnchoredHostname.prototype.match = function(url, tokenBeg) {
|
||||
reURLPostHostnameAnchors.test(url.slice(pos + 3, tokenBeg)) === false;
|
||||
};
|
||||
|
||||
FilterPlainHnAnchoredHostname.fid = FilterPlainHnAnchoredHostname.prototype.fid = '||ah';
|
||||
FilterPlainHnAnchoredHostname.fid =
|
||||
FilterPlainHnAnchoredHostname.prototype.fid =
|
||||
FilterPlainHnAnchoredHostname.prototype.rtfid = '||ah';
|
||||
|
||||
FilterPlainHnAnchoredHostname.prototype.toString = function() {
|
||||
return '||' + this.s;
|
||||
};
|
||||
|
||||
FilterPlainHnAnchoredHostname.prototype.toSelfie = function() {
|
||||
FilterPlainHnAnchoredHostname.prototype.toSelfie =
|
||||
FilterPlainHnAnchoredHostname.prototype.rtCompile = function() {
|
||||
return this.s + '\t' + this.hostname;
|
||||
};
|
||||
|
||||
@ -628,19 +621,12 @@ FilterGeneric.prototype.match = function(url) {
|
||||
return this.re.test(url);
|
||||
};
|
||||
|
||||
FilterGeneric.fid = FilterGeneric.prototype.fid = '_';
|
||||
FilterGeneric.fid =
|
||||
FilterGeneric.prototype.fid =
|
||||
FilterGeneric.prototype.rtfid = '_';
|
||||
|
||||
FilterGeneric.prototype.toString = function() {
|
||||
if ( this.anchor === 0 ) {
|
||||
return this.s;
|
||||
}
|
||||
if ( this.anchor < 0 ) {
|
||||
return '|' + this.s;
|
||||
}
|
||||
return this.s + '|';
|
||||
};
|
||||
|
||||
FilterGeneric.prototype.toSelfie = function() {
|
||||
FilterGeneric.prototype.toSelfie =
|
||||
FilterGeneric.prototype.rtCompile = function() {
|
||||
return this.s + '\t' + this.anchor;
|
||||
};
|
||||
|
||||
@ -671,13 +657,12 @@ FilterGenericHostname.prototype.match = function(url) {
|
||||
return FilterGeneric.prototype.match.call(this, url);
|
||||
};
|
||||
|
||||
FilterGenericHostname.fid = FilterGenericHostname.prototype.fid = '_h';
|
||||
FilterGenericHostname.fid =
|
||||
FilterGenericHostname.prototype.fid =
|
||||
FilterGenericHostname.prototype.rtfid = '_h';
|
||||
|
||||
FilterGenericHostname.prototype.toString = function() {
|
||||
return FilterGeneric.prototype.toString.call(this) + '$domain=' + this.hostname;
|
||||
};
|
||||
|
||||
FilterGenericHostname.prototype.toSelfie = function() {
|
||||
FilterGenericHostname.prototype.toSelfie =
|
||||
FilterGenericHostname.prototype.rtCompile = function() {
|
||||
return FilterGeneric.prototype.toSelfie.call(this) + '\t' + this.hostname;
|
||||
};
|
||||
|
||||
@ -717,13 +702,12 @@ FilterGenericHnAnchored.prototype.match = function(url) {
|
||||
reURLPostHostnameAnchors.test(url.slice(pos + 3, match.index)) === false;
|
||||
};
|
||||
|
||||
FilterGenericHnAnchored.fid = FilterGenericHnAnchored.prototype.fid = '||_';
|
||||
FilterGenericHnAnchored.fid =
|
||||
FilterGenericHnAnchored.prototype.fid =
|
||||
FilterGenericHnAnchored.prototype.rtfid = '||_';
|
||||
|
||||
FilterGenericHnAnchored.prototype.toString = function() {
|
||||
return '||' + this.s;
|
||||
};
|
||||
|
||||
FilterGenericHnAnchored.prototype.toSelfie = function() {
|
||||
FilterGenericHnAnchored.prototype.toSelfie =
|
||||
FilterGenericHnAnchored.prototype.rtCompile = function() {
|
||||
return this.s;
|
||||
};
|
||||
|
||||
@ -751,13 +735,12 @@ FilterGenericHnAnchoredHostname.prototype.match = function(url) {
|
||||
return FilterGenericHnAnchored.prototype.match.call(this, url);
|
||||
};
|
||||
|
||||
FilterGenericHnAnchoredHostname.fid = FilterGenericHnAnchoredHostname.prototype.fid = '||_h';
|
||||
FilterGenericHnAnchoredHostname.fid =
|
||||
FilterGenericHnAnchoredHostname.prototype.fid =
|
||||
FilterGenericHnAnchoredHostname.prototype.rtfid = '||_h';
|
||||
|
||||
FilterGenericHnAnchoredHostname.prototype.toString = function() {
|
||||
return '||' + this.s + '$domain=' + this.hostname;
|
||||
};
|
||||
|
||||
FilterGenericHnAnchoredHostname.prototype.toSelfie = function() {
|
||||
FilterGenericHnAnchoredHostname.prototype.toSelfie =
|
||||
FilterGenericHnAnchoredHostname.prototype.rtCompile = function() {
|
||||
return this.s + '\t' + this.hostname;
|
||||
};
|
||||
|
||||
@ -782,13 +765,12 @@ FilterRegex.prototype.match = function(url) {
|
||||
return this.re.test(url);
|
||||
};
|
||||
|
||||
FilterRegex.fid = FilterRegex.prototype.fid = '//';
|
||||
FilterRegex.fid =
|
||||
FilterRegex.prototype.fid =
|
||||
FilterRegex.prototype.rtfid = '//';
|
||||
|
||||
FilterRegex.prototype.toString = function() {
|
||||
return '/' + this.re.source + '/';
|
||||
};
|
||||
|
||||
FilterRegex.prototype.toSelfie = function() {
|
||||
FilterRegex.prototype.toSelfie =
|
||||
FilterRegex.prototype.rtCompile = function() {
|
||||
return this.re.source;
|
||||
};
|
||||
|
||||
@ -813,13 +795,12 @@ FilterRegexHostname.prototype.match = function(url) {
|
||||
this.re.test(url);
|
||||
};
|
||||
|
||||
FilterRegexHostname.fid = FilterRegexHostname.prototype.fid = '//h';
|
||||
FilterRegexHostname.fid =
|
||||
FilterRegexHostname.prototype.fid =
|
||||
FilterRegexHostname.prototype.rtfid = '//h';
|
||||
|
||||
FilterRegexHostname.prototype.toString = function() {
|
||||
return '/' + this.re.source + '/$domain=' + this.hostname;
|
||||
};
|
||||
|
||||
FilterRegexHostname.prototype.toSelfie = function() {
|
||||
FilterRegexHostname.prototype.toSelfie =
|
||||
FilterRegexHostname.prototype.rtCompile = function() {
|
||||
return this.re.source + '\t' + this.hostname;
|
||||
};
|
||||
|
||||
@ -1004,13 +985,15 @@ FilterHostnameDict.prototype.match = function() {
|
||||
}
|
||||
hostname = hostname.slice(pos + 1);
|
||||
}
|
||||
this.h = '||' + hostname + '^';
|
||||
this.h = hostname;
|
||||
return this;
|
||||
};
|
||||
|
||||
FilterHostnameDict.fid = FilterHostnameDict.prototype.fid = '{h}';
|
||||
FilterHostnameDict.fid =
|
||||
FilterHostnameDict.prototype.fid = '{h}';
|
||||
FilterHostnameDict.rtfid = '.';
|
||||
|
||||
FilterHostnameDict.prototype.toString = function() {
|
||||
FilterHostnameDict.prototype.rtCompile = function() {
|
||||
return this.h;
|
||||
};
|
||||
|
||||
@ -1075,6 +1058,12 @@ var FilterBucket = function(a, b) {
|
||||
this.filters[1] = b;
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(this, 'rtfid', {
|
||||
get: function() {
|
||||
return this.f.rtfid;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
FilterBucket.prototype.add = function(a) {
|
||||
@ -1106,7 +1095,7 @@ FilterBucket.prototype.match = function(url, tokenBeg) {
|
||||
var filters = this.filters;
|
||||
var n = filters.length;
|
||||
for ( var i = 0; i < n; i++ ) {
|
||||
if ( filters[i].match(url, tokenBeg) !== false ) {
|
||||
if ( filters[i].match(url, tokenBeg) ) {
|
||||
this.f = filters[i];
|
||||
if ( i >= this.vip ) {
|
||||
this.promote(i);
|
||||
@ -1119,17 +1108,15 @@ FilterBucket.prototype.match = function(url, tokenBeg) {
|
||||
|
||||
FilterBucket.prototype.fid = '[]';
|
||||
|
||||
FilterBucket.prototype.toString = function() {
|
||||
if ( this.f !== null ) {
|
||||
return this.f.toString();
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
FilterBucket.prototype.toSelfie = function() {
|
||||
return this.filters.length.toString();
|
||||
};
|
||||
|
||||
// Not supposed to be called without a valid filter hit.
|
||||
FilterBucket.prototype.rtCompile = function() {
|
||||
return this.f.rtCompile();
|
||||
};
|
||||
|
||||
FilterBucket.fromSelfie = function() {
|
||||
return new FilterBucket();
|
||||
};
|
||||
@ -1601,6 +1588,11 @@ FilterContainer.prototype.reset = function() {
|
||||
this.categories = Object.create(null);
|
||||
this.filterParser.reset();
|
||||
this.filterCounts = {};
|
||||
|
||||
// Runtime registers
|
||||
this.keyRegister = undefined;
|
||||
this.tokenRegister = undefined;
|
||||
this.fRegister = null;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
@ -2019,6 +2011,140 @@ FilterContainer.prototype.fromCompiledContent = function(text, lineBeg) {
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
FilterContainer.prototype.filterStringFromCompiled = function(compiled) {
|
||||
var opts = [];
|
||||
var vfields = compiled.split('\v');
|
||||
var filter = '';
|
||||
var bits = parseInt(vfields[1], 16) | 0;
|
||||
|
||||
if ( bits & 0x01 ) {
|
||||
filter += '@@';
|
||||
}
|
||||
|
||||
var rfid = vfields[2] === '.' ? '.' : vfields[3];
|
||||
var tfields = rfid !== '.' ? vfields[4].split('\t') : [];
|
||||
|
||||
switch ( rfid ) {
|
||||
case '.':
|
||||
filter += '||' + vfields[3] + '^';
|
||||
break;
|
||||
case 'a':
|
||||
case 'ah':
|
||||
case '0a':
|
||||
case '0ah':
|
||||
case '1a':
|
||||
case '1ah':
|
||||
case '_':
|
||||
case '_h':
|
||||
filter += tfields[0];
|
||||
break;
|
||||
case '|a':
|
||||
case '|ah':
|
||||
filter += '|' + tfields[0];
|
||||
break;
|
||||
case 'a|':
|
||||
case 'a|h':
|
||||
filter += tfields[0] + '|';
|
||||
break;
|
||||
case '||a':
|
||||
case '||ah':
|
||||
case '||_':
|
||||
case '||_h':
|
||||
filter += '||' + tfields[0];
|
||||
break;
|
||||
case '//':
|
||||
case '//h':
|
||||
filter += '/' + tfields[0] + '/';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Domain option?
|
||||
switch ( rfid ) {
|
||||
case '0ah':
|
||||
case '1ah':
|
||||
case '|ah':
|
||||
case 'a|h':
|
||||
case '||ah':
|
||||
case '||_h':
|
||||
case '//h':
|
||||
opts.push('domain=' + tfields[1]);
|
||||
break;
|
||||
case 'ah':
|
||||
case '_h':
|
||||
opts.push('domain=' + tfields[2]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Filter options
|
||||
if ( bits & 0x02 ) {
|
||||
opts.push('important');
|
||||
}
|
||||
if ( bits & 0x08 ) {
|
||||
opts.push('third-party');
|
||||
} else if ( bits & 0x04 ) {
|
||||
opts.push('first-party');
|
||||
}
|
||||
if ( bits & 0xF0 ) {
|
||||
opts.push(typeValueToTypeName[bits >>> 4]);
|
||||
}
|
||||
if ( opts.length !== 0 ) {
|
||||
filter += '$' + opts.join(',');
|
||||
}
|
||||
|
||||
return filter;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
FilterContainer.prototype.filterRegexFromCompiled = function(compiled, flags) {
|
||||
var vfields = compiled.split('\v');
|
||||
var rfid = vfields[2] === '.' ? '.' : vfields[3];
|
||||
var tfields = rfid !== '.' ? vfields[4].split('\t') : [];
|
||||
var re = null;
|
||||
|
||||
switch ( rfid ) {
|
||||
case '.':
|
||||
re = strToRegex(vfields[3], 0, flags);
|
||||
break;
|
||||
case 'a':
|
||||
case 'ah':
|
||||
case '0a':
|
||||
case '0ah':
|
||||
case '1a':
|
||||
case '1ah':
|
||||
case '_':
|
||||
case '_h':
|
||||
case '||a':
|
||||
case '||ah':
|
||||
case '||_':
|
||||
case '||_h':
|
||||
re = strToRegex(tfields[0], 0, flags);
|
||||
break;
|
||||
case '|a':
|
||||
case '|ah':
|
||||
re = strToRegex(tfields[0], -1, flags);
|
||||
break;
|
||||
case 'a|':
|
||||
case 'a|h':
|
||||
re = strToRegex(tfields[0], 1, flags);
|
||||
break;
|
||||
case '//':
|
||||
case '//h':
|
||||
re = new RegExp(tfields[0]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return re;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// Since the addition of the `important` evaluation, this means it is now
|
||||
// likely that the url will have to be scanned more than once. So this is
|
||||
// to ensure we do it once only, and reuse results.
|
||||
@ -2058,8 +2184,10 @@ FilterContainer.prototype.tokenize = function(url) {
|
||||
FilterContainer.prototype.matchTokens = function(bucket, url) {
|
||||
// Hostname-only filters
|
||||
var f = bucket['.'];
|
||||
if ( f !== undefined && f.match() !== false ) {
|
||||
return f;
|
||||
if ( f !== undefined && f.match() ) {
|
||||
this.tokenRegister = '.';
|
||||
this.fRegister = f;
|
||||
return true;
|
||||
}
|
||||
|
||||
var tokens = this.tokens;
|
||||
@ -2072,15 +2200,19 @@ FilterContainer.prototype.matchTokens = function(bucket, url) {
|
||||
break;
|
||||
}
|
||||
f = bucket[token];
|
||||
if ( f !== undefined && f.match(url, tokenEntry.beg) !== false ) {
|
||||
return f;
|
||||
if ( f !== undefined && f.match(url, tokenEntry.beg) ) {
|
||||
this.tokenRegister = token;
|
||||
this.fRegister = f;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Regex-based filters
|
||||
f = bucket['*'];
|
||||
if ( f !== undefined && f.match(url) !== false ) {
|
||||
return f;
|
||||
if ( f !== undefined && f.match(url) ) {
|
||||
this.tokenRegister = '*';
|
||||
this.fRegister = f;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -2106,60 +2238,66 @@ FilterContainer.prototype.matchStringExactType = function(context, requestURL, r
|
||||
// Be prepared to support unknown types
|
||||
var type = typeNameToTypeValue[requestType] || 0;
|
||||
if ( type === 0 ) {
|
||||
return '';
|
||||
return false;
|
||||
}
|
||||
|
||||
var categories = this.categories;
|
||||
var bf = false, bucket;
|
||||
var bucket;
|
||||
|
||||
// Tokenize only once
|
||||
this.tokenize(url);
|
||||
|
||||
this.fRegister = null;
|
||||
|
||||
// https://github.com/chrisaljoudi/uBlock/issues/139
|
||||
// Test against important block filters
|
||||
if ( bucket = categories[this.makeCategoryKey(BlockAnyParty | Important | type)] ) {
|
||||
bf = this.matchTokens(bucket, url);
|
||||
if ( bf !== false ) {
|
||||
return 'sb:' + bf.toString();
|
||||
if ( this.matchTokens(bucket, url) ) {
|
||||
this.keyRegister = BlockAnyParty | Important | type;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if ( bucket = categories[this.makeCategoryKey(BlockAction | Important | type | party)] ) {
|
||||
bf = this.matchTokens(bucket, url);
|
||||
if ( bf !== false ) {
|
||||
return 'sb:' + bf.toString();
|
||||
if ( this.matchTokens(bucket, url) ) {
|
||||
this.keyRegister = BlockAction | Important | type | party;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Test against block filters
|
||||
if ( bucket = categories[this.makeCategoryKey(BlockAnyParty | type)] ) {
|
||||
bf = this.matchTokens(bucket, url);
|
||||
if ( this.matchTokens(bucket, url) ) {
|
||||
this.keyRegister = BlockAnyParty | type;
|
||||
}
|
||||
if ( bf === false ) {
|
||||
}
|
||||
if ( this.fRegister === null ) {
|
||||
if ( bucket = categories[this.makeCategoryKey(BlockAction | type | party)] ) {
|
||||
bf = this.matchTokens(bucket, url);
|
||||
if ( this.matchTokens(bucket, url) ) {
|
||||
this.keyRegister = BlockAction | type | party;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there is no block filter, no need to test against allow filters
|
||||
if ( bf === false ) {
|
||||
return '';
|
||||
if ( this.fRegister === null ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Test against allow filters
|
||||
var af;
|
||||
if ( bucket = categories[this.makeCategoryKey(AllowAnyParty | type)] ) {
|
||||
af = this.matchTokens(bucket, url);
|
||||
if ( af !== false ) {
|
||||
return 'sa:' + af.toString();
|
||||
if ( this.matchTokens(bucket, url) ) {
|
||||
this.keyRegister = AllowAnyParty | type;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ( bucket = categories[this.makeCategoryKey(AllowAction | type | party)] ) {
|
||||
af = this.matchTokens(bucket, url);
|
||||
if ( af !== false ) {
|
||||
return 'sa:' + af.toString();
|
||||
if ( this.matchTokens(bucket, url) ) {
|
||||
this.keyRegister = AllowAction | type | party;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return 'sb:' + bf.toString();
|
||||
return true;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
@ -2212,7 +2350,7 @@ FilterContainer.prototype.matchString = function(context) {
|
||||
// Tokenize only once
|
||||
this.tokenize(url);
|
||||
|
||||
var bf = false;
|
||||
this.fRegister = null;
|
||||
|
||||
// https://github.com/chrisaljoudi/uBlock/issues/139
|
||||
// Test against important block filters.
|
||||
@ -2220,86 +2358,113 @@ FilterContainer.prototype.matchString = function(context) {
|
||||
// evaluation. Normally, it is "evaluate block then evaluate allow", with
|
||||
// the `important` property it is "evaluate allow then evaluate block".
|
||||
if ( bucket = filterClasses[this.makeCategoryKey(BlockAnyTypeAnyParty | Important)] ) {
|
||||
bf = this.matchTokens(bucket, url);
|
||||
if ( bf !== false ) {
|
||||
return 'sb:' + bf.toString() + '$important';
|
||||
if ( this.matchTokens(bucket, url) ) {
|
||||
this.keyRegister = BlockAnyTypeAnyParty | Important;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if ( bucket = filterClasses[this.makeCategoryKey(BlockAnyType | Important | party)] ) {
|
||||
bf = this.matchTokens(bucket, url);
|
||||
if ( bf !== false ) {
|
||||
return 'sb:' + bf.toString() + '$important';
|
||||
if ( this.matchTokens(bucket, url) ) {
|
||||
this.keyRegister = BlockAnyType | Important | party;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if ( bucket = filterClasses[this.makeCategoryKey(BlockAnyParty | Important | type)] ) {
|
||||
bf = this.matchTokens(bucket, url);
|
||||
if ( bf !== false ) {
|
||||
return 'sb:' + bf.toString() + '$important';
|
||||
if ( this.matchTokens(bucket, url) ) {
|
||||
this.keyRegister = BlockAnyParty | Important | type;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if ( bucket = filterClasses[this.makeCategoryKey(BlockAction | Important | type | party)] ) {
|
||||
bf = this.matchTokens(bucket, url);
|
||||
if ( bf !== false ) {
|
||||
return 'sb:' + bf.toString() + '$important';
|
||||
if ( this.matchTokens(bucket, url) ) {
|
||||
this.keyRegister = BlockAction | Important | type | party;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Test against block filters
|
||||
if ( bf === false ) {
|
||||
if ( bucket = filterClasses[this.makeCategoryKey(BlockAnyTypeAnyParty)] ) {
|
||||
bf = this.matchTokens(bucket, url);
|
||||
if ( this.matchTokens(bucket, url) ) {
|
||||
this.keyRegister = BlockAnyTypeAnyParty;
|
||||
}
|
||||
}
|
||||
if ( bf === false ) {
|
||||
if ( this.fRegister === null ) {
|
||||
if ( bucket = filterClasses[this.makeCategoryKey(BlockAnyType | party)] ) {
|
||||
bf = this.matchTokens(bucket, url);
|
||||
if ( this.matchTokens(bucket, url) ) {
|
||||
this.keyRegister = BlockAnyType | party;
|
||||
}
|
||||
}
|
||||
if ( bf === false ) {
|
||||
if ( this.fRegister === null ) {
|
||||
if ( bucket = filterClasses[this.makeCategoryKey(BlockAnyParty | type)] ) {
|
||||
bf = this.matchTokens(bucket, url);
|
||||
if ( this.matchTokens(bucket, url) ) {
|
||||
this.keyRegister = BlockAnyParty | type;
|
||||
}
|
||||
}
|
||||
if ( bf === false ) {
|
||||
if ( this.fRegister === null ) {
|
||||
if ( bucket = filterClasses[this.makeCategoryKey(BlockAction | type | party)] ) {
|
||||
bf = this.matchTokens(bucket, url);
|
||||
if ( this.matchTokens(bucket, url) ) {
|
||||
this.keyRegister = BlockAction | type | party;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there is no block filter, no need to test against allow filters
|
||||
if ( bf === false ) {
|
||||
return '';
|
||||
if ( this.fRegister === null ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Test against allow filters
|
||||
var af;
|
||||
|
||||
if ( bucket = filterClasses[this.makeCategoryKey(AllowAnyTypeAnyParty)] ) {
|
||||
af = this.matchTokens(bucket, url);
|
||||
if ( af !== false ) {
|
||||
return 'sa:' + af.toString();
|
||||
if ( this.matchTokens(bucket, url) ) {
|
||||
this.keyRegister = AllowAnyTypeAnyParty;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ( bucket = filterClasses[this.makeCategoryKey(AllowAnyType | party)] ) {
|
||||
af = this.matchTokens(bucket, url);
|
||||
if ( af !== false ) {
|
||||
return 'sa:' + af.toString();
|
||||
if ( this.matchTokens(bucket, url) ) {
|
||||
this.keyRegister = AllowAnyType | party;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ( bucket = filterClasses[this.makeCategoryKey(AllowAnyParty | type)] ) {
|
||||
af = this.matchTokens(bucket, url);
|
||||
if ( af !== false ) {
|
||||
return 'sa:' + af.toString();
|
||||
if ( this.matchTokens(bucket, url) ) {
|
||||
this.keyRegister = AllowAnyParty | type;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ( bucket = filterClasses[this.makeCategoryKey(AllowAction | type | party)] ) {
|
||||
af = this.matchTokens(bucket, url);
|
||||
if ( af !== false ) {
|
||||
return 'sa:' + af.toString();
|
||||
if ( this.matchTokens(bucket, url) ) {
|
||||
this.keyRegister = AllowAction | type | party;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return 'sb:' + bf.toString();
|
||||
return true;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// The `verbose` argment tells whether to return a short or long version of
|
||||
// the filter string. Typically, if the logger is not enabled, there is no
|
||||
// point in returning the long version: this saves overhead.
|
||||
|
||||
FilterContainer.prototype.toResultString = function(verbose) {
|
||||
if ( this.fRegister === null ) {
|
||||
return '';
|
||||
}
|
||||
var s = this.keyRegister & 0x01 ? 'sa:' : 'sb:';
|
||||
if ( !verbose ) {
|
||||
return s;
|
||||
}
|
||||
s += 'n\v' + this.makeCategoryKey(this.keyRegister) + '\v' + this.tokenRegister + '\v';
|
||||
if ( this.tokenRegister === '.' ) {
|
||||
s += this.fRegister.rtCompile();
|
||||
} else {
|
||||
s += this.fRegister.rtfid + '\v' + this.fRegister.rtCompile();
|
||||
}
|
||||
return s;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
|
||||
µBlock - a browser extension to block requests.
|
||||
Copyright (C) 2014 Raymond Hill
|
||||
uBlock - a browser extension to block requests.
|
||||
Copyright (C) 2014-2015 Raymond Hill
|
||||
|
||||
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
|
||||
@ -492,6 +492,7 @@ vAPI.tabs.onPopup = function(details) {
|
||||
};
|
||||
|
||||
var result = '';
|
||||
var loggerEnabled = µb.logger.isEnabled();
|
||||
|
||||
// Check user switch first
|
||||
if ( µb.hnSwitches.evaluateZ('no-popups', openerHostname) ) {
|
||||
@ -506,7 +507,9 @@ vAPI.tabs.onPopup = function(details) {
|
||||
µb.getNetFilteringSwitch(openerURL) &&
|
||||
µb.getNetFilteringSwitch(targetURL)
|
||||
) {
|
||||
result = µb.staticNetFilteringEngine.matchStringExactType(context, targetURL, 'popup');
|
||||
if ( µb.staticNetFilteringEngine.matchStringExactType(context, targetURL, 'popup') ) {
|
||||
result = µb.staticNetFilteringEngine.toResultString(loggerEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/chrisaljoudi/uBlock/issues/91
|
||||
@ -514,6 +517,7 @@ vAPI.tabs.onPopup = function(details) {
|
||||
if ( pageStore ) {
|
||||
pageStore.logRequest(context, result);
|
||||
}
|
||||
if ( loggerEnabled ) {
|
||||
µb.logger.writeOne(
|
||||
details.openerTabId,
|
||||
'net',
|
||||
@ -523,6 +527,7 @@ vAPI.tabs.onPopup = function(details) {
|
||||
openerHostname,
|
||||
openerHostname
|
||||
);
|
||||
}
|
||||
|
||||
// Not blocked
|
||||
if ( µb.isAllowResult(result) ) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
|
||||
µBlock - a browser extension to block requests.
|
||||
Copyright (C) 2014 Raymond Hill
|
||||
uBlock - a browser extension to block requests.
|
||||
Copyright (C) 2014-2015 Raymond Hill
|
||||
|
||||
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
|
||||
@ -185,13 +185,16 @@ var onBeforeRootFrameRequest = function(details) {
|
||||
|
||||
// Filtering
|
||||
if ( result === '' ) {
|
||||
result = µb.staticNetFilteringEngine.matchString(context);
|
||||
if ( µb.staticNetFilteringEngine.matchString(context) ) {
|
||||
// We always need the long-form result here.
|
||||
result = µb.staticNetFilteringEngine.toResultString(true);
|
||||
// https://github.com/chrisaljoudi/uBlock/issues/1128
|
||||
// Do not block if the match begins after the hostname.
|
||||
if ( result !== '' ) {
|
||||
if ( result.charAt(1) === 'b' ) {
|
||||
result = toBlockDocResult(requestURL, requestHostname, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Log
|
||||
var pageStore = µb.bindTabToPageStats(tabId, 'beforeRequest');
|
||||
@ -221,7 +224,7 @@ var onBeforeRootFrameRequest = function(details) {
|
||||
url: requestURL,
|
||||
hn: requestHostname,
|
||||
dn: requestDomain,
|
||||
why: result
|
||||
why: µb.staticNetFilteringEngine.filterStringFromCompiled(result.slice(3))
|
||||
}));
|
||||
|
||||
vAPI.tabs.replace(tabId, vAPI.getURL('document-blocked.html?details=') + query);
|
||||
@ -232,32 +235,12 @@ var onBeforeRootFrameRequest = function(details) {
|
||||
/******************************************************************************/
|
||||
|
||||
var toBlockDocResult = function(url, hostname, result) {
|
||||
if ( result.charAt(1) !== 'b' ) {
|
||||
// Make a regex out of the result
|
||||
var re = µBlock.staticNetFilteringEngine
|
||||
.filterRegexFromCompiled(result.slice(3), 'gi');
|
||||
if ( re === null ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Make a regex out of the result
|
||||
var reText = result.slice(3);
|
||||
var pos = reText.indexOf('$');
|
||||
if ( pos > 0 ) {
|
||||
reText = reText.slice(0, pos);
|
||||
}
|
||||
|
||||
// We are going to have to take the long way to find out
|
||||
if ( reText.charAt(0) === '/' && reText.slice(-1) === '/' ) {
|
||||
reText = reText.slice(1, -1);
|
||||
} else {
|
||||
reText = reText
|
||||
.replace(/\./g, '\\.')
|
||||
.replace(/\?/g, '\\?')
|
||||
.replace(/^\|\|/, '')
|
||||
.replace(/\^/g, '.')
|
||||
.replace(/^\|/g, '^')
|
||||
.replace(/\|$/g, '$')
|
||||
.replace(/\*/g, '.*');
|
||||
}
|
||||
|
||||
var re = new RegExp(reText, 'gi');
|
||||
var matches = re.exec(url);
|
||||
if ( matches === null ) {
|
||||
return '';
|
||||
|
Loading…
Reference in New Issue
Block a user