this fixes #59: now accurately reporting static filters in logger

This commit is contained in:
gorhill 2015-06-09 10:27:08 -04:00
parent 323378fb38
commit 2234933b82
6 changed files with 646 additions and 322 deletions

View File

@ -104,7 +104,7 @@ var proceedPermanent = function() {
/******************************************************************************/ /******************************************************************************/
uDom('.what').text(details.url); uDom('.what').text(details.url);
uDom('#why').text(details.why.slice(3)); uDom('#why').text(details.why);
if ( window.history.length > 1 ) { if ( window.history.length > 1 ) {
uDom('#back').on('click', function() { window.history.back(); }); uDom('#back').on('click', function() { window.history.back(); });

View File

@ -103,61 +103,24 @@ var tabIdFromClassName = function(className) {
/******************************************************************************/ /******************************************************************************/
var retextFromStaticFilteringResult = function(result) { var regexFromURLFilteringResult = 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 beg = result.indexOf(' '); var beg = result.indexOf(' ');
var end = result.indexOf(' ', beg + 1); var end = result.indexOf(' ', beg + 1);
var url = result.slice(beg + 1, end); var url = result.slice(beg + 1, end);
if ( url === '*' ) { 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. // Emphasize hostname in URL, as this is what matters in uMatrix's rules.
var nodeFromURL = function(url, filter) { var nodeFromURL = function(url, re) {
var filterType = filter.charAt(0); if ( re instanceof RegExp === false ) {
if ( filterType !== 's' && filterType !== 'l' ) {
return document.createTextNode(url); 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); var matches = re.exec(url);
if ( matches === null || matches[0].length === 0 ) { if ( matches === null || matches[0].length === 0 ) {
return document.createTextNode(url); 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 createCellAt = function(tr, index) {
var td = tr.cells[index]; var td = tr.cells[index];
var mustAppend = !td; var mustAppend = !td;
@ -276,26 +420,31 @@ var renderNetLogEntry = function(tr, entry) {
tr.setAttribute('data-hn-frame', entry.d4); tr.setAttribute('data-hn-frame', entry.d4);
} }
// Cosmetic filter?
var filterCat = filter.slice(0, 3); var filterCat = filter.slice(0, 3);
if ( filterCat.charAt(2) === ':' ) { if ( filterCat.charAt(2) === ':' ) {
tr.classList.add(filterCat.slice(0, 2)); tr.classList.add(filterCat.slice(0, 2));
} }
var filterText = filter.slice(3); var filteringType = filterCat.charAt(0);
if ( filter.lastIndexOf('sa', 0) === 0 ) { td = tr.cells[2];
filterText = '@@' + filterText; 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]; td = tr.cells[3];
if ( filter.charAt(1) === 'b' ) { var filteringOp = filterCat.charAt(1);
if ( filteringOp === 'b' ) {
tr.classList.add('blocked'); tr.classList.add('blocked');
td.textContent = '--'; td.textContent = '--';
} else if ( filter.charAt(1) === 'a' ) { } else if ( filteringOp === 'a' ) {
tr.classList.add('allowed'); tr.classList.add('allowed');
td.textContent = '++'; td.textContent = '++';
} else if ( filter.charAt(1) === 'n' ) { } else if ( filteringOp === 'n' ) {
tr.classList.add('nooped'); tr.classList.add('nooped');
td.textContent = '**'; td.textContent = '**';
} else { } else {
@ -303,7 +452,14 @@ var renderNetLogEntry = function(tr, entry) {
} }
tr.cells[4].textContent = (prettyRequestTypes[type] || type); 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));
}; };
/******************************************************************************/ /******************************************************************************/

View File

@ -114,7 +114,7 @@ NetFilteringResultCache.factory = function() {
NetFilteringResultCache.prototype.init = function() { NetFilteringResultCache.prototype.init = function() {
this.urls = {}; this.urls = {};
this.count = 0; this.count = 0;
this.shelfLife = 60 * 1000; this.shelfLife = 15 * 1000;
this.timer = null; this.timer = null;
this.boundPruneAsyncCallback = this.pruneAsyncCallback.bind(this); 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 // Support `elemhide` filter option. Called at this point so the required
// context is all setup at this point. // context is all setup at this point.
var context = this.createContextFromPage(); this.skipCosmeticFiltering = µb.staticNetFilteringEngine.matchStringExactType(
this.skipCosmeticFiltering = µb.staticNetFilteringEngine this.createContextFromPage(),
.matchStringExactType(context, tabContext.normalURL, 'cosmetic-filtering') tabContext.normalURL,
.charAt(1) === 'b'; '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; return this;
}; };
@ -515,7 +526,9 @@ PageStore.prototype.filterRequest = function(context) {
// Static filtering never override dynamic filtering // Static filtering never override dynamic filtering
if ( result === '' || result.charAt(1) === 'n' ) { 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); //console.debug('cache MISS: PageStore.filterRequest("%s")', context.requestURL);
@ -555,7 +568,9 @@ PageStore.prototype.filterRequestNoCache = function(context) {
// Static filtering never override dynamic filtering // Static filtering never override dynamic filtering
if ( result === '' || result.charAt(1) === 'n' ) { 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; return result;

View File

@ -1,7 +1,7 @@
/******************************************************************************* /*******************************************************************************
µBlock - a browser extension to block requests. uBlock - a browser extension to block requests.
Copyright (C) 2014 Raymond Hill Copyright (C) 2014-2015 Raymond Hill
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -70,6 +70,20 @@ var typeNameToTypeValue = {
}; };
var typeOtherValue = typeNameToTypeValue.other; 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 // All network request types to bitmap
// bring origin to 0 (from 4 -- see typeNameToTypeValue) // bring origin to 0 (from 4 -- see typeNameToTypeValue)
// left-shift 1 by the above-calculated value // 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 // https://github.com/chrisaljoudi/uBlock/issues/1038
// Special case: always match. // Special case: always match.
if ( s === '*' ) { if ( s === '*' ) {
@ -193,7 +207,7 @@ var strToRegex = function(s, anchor) {
} }
//console.debug('µBlock.staticNetFilteringEngine: created RegExp("%s")', reStr); //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; 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() { FilterPlain.prototype.toSelfie =
return this.s; FilterPlain.prototype.rtCompile = function() {
}; return this.s + '\t' + this.tokenBeg;
FilterPlain.prototype.toSelfie = function() {
return this.s + '\t' +
this.tokenBeg;
}; };
FilterPlain.compile = function(details) { FilterPlain.compile = function(details) {
@ -268,22 +280,17 @@ 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.fid = FilterPlainHostname.prototype.fid = 'ah'; FilterPlainHostname.fid =
FilterPlainHostname.prototype.fid =
FilterPlainHostname.prototype.rtfid = 'ah';
FilterPlainHostname.prototype.toString = function() { FilterPlainHostname.prototype.toSelfie =
return this.s + '$domain=' + this.hostname; FilterPlainHostname.prototype.rtCompile = function() {
}; return this.s + '\t' + this.tokenBeg + '\t' + this.hostname;
FilterPlainHostname.prototype.toSelfie = function() {
return this.s + '\t' +
this.tokenBeg + '\t' +
this.hostname;
}; };
FilterPlainHostname.compile = function(details, hostname) { FilterPlainHostname.compile = function(details, hostname) {
return details.f + '\t' + return details.f + '\t' + details.tokenBeg + '\t' + hostname;
details.tokenBeg + '\t' +
hostname;
}; };
FilterPlainHostname.fromSelfie = function(s) { FilterPlainHostname.fromSelfie = function(s) {
@ -301,13 +308,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.fid = FilterPlainPrefix0.prototype.fid = '0a'; FilterPlainPrefix0.fid =
FilterPlainPrefix0.prototype.fid =
FilterPlainPrefix0.prototype.rtfid = '0a';
FilterPlainPrefix0.prototype.toString = function() { FilterPlainPrefix0.prototype.toSelfie =
return this.s; FilterPlainPrefix0.prototype.rtCompile = function() {
};
FilterPlainPrefix0.prototype.toSelfie = function() {
return this.s; return this.s;
}; };
@ -331,15 +337,13 @@ FilterPlainPrefix0Hostname.prototype.match = function(url, tokenBeg) {
url.substr(tokenBeg, this.s.length) === this.s; 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() { FilterPlainPrefix0Hostname.prototype.toSelfie =
return this.s + '$domain=' + this.hostname; FilterPlainPrefix0Hostname.prototype.rtCompile = function() {
}; return this.s + '\t' + this.hostname;
FilterPlainPrefix0Hostname.prototype.toSelfie = function() {
return this.s + '\t' +
this.hostname;
}; };
FilterPlainPrefix0Hostname.compile = function(details, 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; 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() { FilterPlainPrefix1.prototype.toSelfie =
return this.s; FilterPlainPrefix1.prototype.rtCompile = function() {
};
FilterPlainPrefix1.prototype.toSelfie = function() {
return this.s; return this.s;
}; };
@ -391,15 +394,13 @@ 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.fid = FilterPlainPrefix1Hostname.prototype.fid = '1ah'; FilterPlainPrefix1Hostname.fid =
FilterPlainPrefix1Hostname.prototype.fid =
FilterPlainPrefix1Hostname.prototype.rtfid = '1ah';
FilterPlainPrefix1Hostname.prototype.toString = function() { FilterPlainPrefix1Hostname.prototype.toSelfie =
return this.s + '$domain=' + this.hostname; FilterPlainPrefix1Hostname.prototype.rtCompile = function() {
}; return this.s + '\t' + this.hostname;
FilterPlainPrefix1Hostname.prototype.toSelfie = function() {
return this.s + '\t' +
this.hostname;
}; };
FilterPlainPrefix1Hostname.compile = function(details, hostname) { FilterPlainPrefix1Hostname.compile = function(details, hostname) {
@ -421,13 +422,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.fid = FilterPlainLeftAnchored.prototype.fid = '|a'; FilterPlainLeftAnchored.fid =
FilterPlainLeftAnchored.prototype.fid =
FilterPlainLeftAnchored.prototype.rtfid = '|a';
FilterPlainLeftAnchored.prototype.toString = function() { FilterPlainLeftAnchored.prototype.toSelfie =
return '|' + this.s; FilterPlainLeftAnchored.prototype.rtCompile = function() {
};
FilterPlainLeftAnchored.prototype.toSelfie = function() {
return this.s; return this.s;
}; };
@ -451,15 +451,13 @@ FilterPlainLeftAnchoredHostname.prototype.match = function(url) {
url.slice(0, this.s.length) === this.s; 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() { FilterPlainLeftAnchoredHostname.prototype.toSelfie =
return '|' + this.s + '$domain=' + this.hostname; FilterPlainLeftAnchoredHostname.prototype.rtCompile = function() {
}; return this.s + '\t' + this.hostname;
FilterPlainLeftAnchoredHostname.prototype.toSelfie = function() {
return this.s + '\t' +
this.hostname;
}; };
FilterPlainLeftAnchoredHostname.compile = function(details, hostname) { FilterPlainLeftAnchoredHostname.compile = function(details, hostname) {
@ -481,13 +479,12 @@ FilterPlainRightAnchored.prototype.match = function(url) {
return url.slice(-this.s.length) === this.s; 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() { FilterPlainRightAnchored.prototype.toSelfie =
return this.s + '|'; FilterPlainRightAnchored.prototype.rtCompile = function() {
};
FilterPlainRightAnchored.prototype.toSelfie = function() {
return this.s; return this.s;
}; };
@ -511,15 +508,13 @@ FilterPlainRightAnchoredHostname.prototype.match = function(url) {
url.slice(-this.s.length) === this.s; 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() { FilterPlainRightAnchoredHostname.prototype.toSelfie =
return this.s + '|$domain=' + this.hostname; FilterPlainRightAnchoredHostname.prototype.rtCompile = function() {
}; return this.s + '\t' + this.hostname;
FilterPlainRightAnchoredHostname.prototype.toSelfie = function() {
return this.s + '\t' +
this.hostname;
}; };
FilterPlainRightAnchoredHostname.compile = function(details, hostname) { FilterPlainRightAnchoredHostname.compile = function(details, hostname) {
@ -550,13 +545,12 @@ FilterPlainHnAnchored.prototype.match = function(url, tokenBeg) {
reURLPostHostnameAnchors.test(url.slice(pos + 3, tokenBeg)) === false; 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() { FilterPlainHnAnchored.prototype.toSelfie =
return '||' + this.s; FilterPlainHnAnchored.prototype.rtCompile = function() {
};
FilterPlainHnAnchored.prototype.toSelfie = function() {
return this.s; return this.s;
}; };
@ -592,13 +586,12 @@ FilterPlainHnAnchoredHostname.prototype.match = function(url, tokenBeg) {
reURLPostHostnameAnchors.test(url.slice(pos + 3, tokenBeg)) === false; 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() { FilterPlainHnAnchoredHostname.prototype.toSelfie =
return '||' + this.s; FilterPlainHnAnchoredHostname.prototype.rtCompile = function() {
};
FilterPlainHnAnchoredHostname.prototype.toSelfie = function() {
return this.s + '\t' + this.hostname; return this.s + '\t' + this.hostname;
}; };
@ -628,19 +621,12 @@ FilterGeneric.prototype.match = function(url) {
return this.re.test(url); return this.re.test(url);
}; };
FilterGeneric.fid = FilterGeneric.prototype.fid = '_'; FilterGeneric.fid =
FilterGeneric.prototype.fid =
FilterGeneric.prototype.rtfid = '_';
FilterGeneric.prototype.toString = function() { FilterGeneric.prototype.toSelfie =
if ( this.anchor === 0 ) { FilterGeneric.prototype.rtCompile = function() {
return this.s;
}
if ( this.anchor < 0 ) {
return '|' + this.s;
}
return this.s + '|';
};
FilterGeneric.prototype.toSelfie = function() {
return this.s + '\t' + this.anchor; return this.s + '\t' + this.anchor;
}; };
@ -671,13 +657,12 @@ FilterGenericHostname.prototype.match = function(url) {
return FilterGeneric.prototype.match.call(this, 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() { FilterGenericHostname.prototype.toSelfie =
return FilterGeneric.prototype.toString.call(this) + '$domain=' + this.hostname; FilterGenericHostname.prototype.rtCompile = function() {
};
FilterGenericHostname.prototype.toSelfie = function() {
return FilterGeneric.prototype.toSelfie.call(this) + '\t' + this.hostname; 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; 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() { FilterGenericHnAnchored.prototype.toSelfie =
return '||' + this.s; FilterGenericHnAnchored.prototype.rtCompile = function() {
};
FilterGenericHnAnchored.prototype.toSelfie = function() {
return this.s; return this.s;
}; };
@ -751,13 +735,12 @@ FilterGenericHnAnchoredHostname.prototype.match = function(url) {
return FilterGenericHnAnchored.prototype.match.call(this, 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() { FilterGenericHnAnchoredHostname.prototype.toSelfie =
return '||' + this.s + '$domain=' + this.hostname; FilterGenericHnAnchoredHostname.prototype.rtCompile = function() {
};
FilterGenericHnAnchoredHostname.prototype.toSelfie = function() {
return this.s + '\t' + this.hostname; return this.s + '\t' + this.hostname;
}; };
@ -782,13 +765,12 @@ FilterRegex.prototype.match = function(url) {
return this.re.test(url); return this.re.test(url);
}; };
FilterRegex.fid = FilterRegex.prototype.fid = '//'; FilterRegex.fid =
FilterRegex.prototype.fid =
FilterRegex.prototype.rtfid = '//';
FilterRegex.prototype.toString = function() { FilterRegex.prototype.toSelfie =
return '/' + this.re.source + '/'; FilterRegex.prototype.rtCompile = function() {
};
FilterRegex.prototype.toSelfie = function() {
return this.re.source; return this.re.source;
}; };
@ -813,13 +795,12 @@ FilterRegexHostname.prototype.match = function(url) {
this.re.test(url); this.re.test(url);
}; };
FilterRegexHostname.fid = FilterRegexHostname.prototype.fid = '//h'; FilterRegexHostname.fid =
FilterRegexHostname.prototype.fid =
FilterRegexHostname.prototype.rtfid = '//h';
FilterRegexHostname.prototype.toString = function() { FilterRegexHostname.prototype.toSelfie =
return '/' + this.re.source + '/$domain=' + this.hostname; FilterRegexHostname.prototype.rtCompile = function() {
};
FilterRegexHostname.prototype.toSelfie = function() {
return this.re.source + '\t' + this.hostname; return this.re.source + '\t' + this.hostname;
}; };
@ -1004,13 +985,15 @@ FilterHostnameDict.prototype.match = function() {
} }
hostname = hostname.slice(pos + 1); hostname = hostname.slice(pos + 1);
} }
this.h = '||' + hostname + '^'; this.h = hostname;
return this; 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; return this.h;
}; };
@ -1075,6 +1058,12 @@ var FilterBucket = function(a, b) {
this.filters[1] = b; this.filters[1] = b;
} }
} }
Object.defineProperty(this, 'rtfid', {
get: function() {
return this.f.rtfid;
}
});
}; };
FilterBucket.prototype.add = function(a) { FilterBucket.prototype.add = function(a) {
@ -1106,7 +1095,7 @@ FilterBucket.prototype.match = function(url, tokenBeg) {
var filters = this.filters; var filters = this.filters;
var n = filters.length; var n = filters.length;
for ( var i = 0; i < n; i++ ) { for ( var i = 0; i < n; i++ ) {
if ( filters[i].match(url, tokenBeg) !== false ) { if ( filters[i].match(url, tokenBeg) ) {
this.f = filters[i]; this.f = filters[i];
if ( i >= this.vip ) { if ( i >= this.vip ) {
this.promote(i); this.promote(i);
@ -1119,17 +1108,15 @@ FilterBucket.prototype.match = function(url, tokenBeg) {
FilterBucket.prototype.fid = '[]'; FilterBucket.prototype.fid = '[]';
FilterBucket.prototype.toString = function() {
if ( this.f !== null ) {
return this.f.toString();
}
return '';
};
FilterBucket.prototype.toSelfie = function() { FilterBucket.prototype.toSelfie = function() {
return this.filters.length.toString(); 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() { FilterBucket.fromSelfie = function() {
return new FilterBucket(); return new FilterBucket();
}; };
@ -1601,6 +1588,11 @@ FilterContainer.prototype.reset = function() {
this.categories = Object.create(null); this.categories = Object.create(null);
this.filterParser.reset(); this.filterParser.reset();
this.filterCounts = {}; 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 // 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 // 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. // 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) { FilterContainer.prototype.matchTokens = function(bucket, url) {
// Hostname-only filters // Hostname-only filters
var f = bucket['.']; var f = bucket['.'];
if ( f !== undefined && f.match() !== false ) { if ( f !== undefined && f.match() ) {
return f; this.tokenRegister = '.';
this.fRegister = f;
return true;
} }
var tokens = this.tokens; var tokens = this.tokens;
@ -2072,15 +2200,19 @@ FilterContainer.prototype.matchTokens = function(bucket, url) {
break; break;
} }
f = bucket[token]; f = bucket[token];
if ( f !== undefined && f.match(url, tokenEntry.beg) !== false ) { if ( f !== undefined && f.match(url, tokenEntry.beg) ) {
return f; this.tokenRegister = token;
this.fRegister = f;
return true;
} }
} }
// Regex-based filters // Regex-based filters
f = bucket['*']; f = bucket['*'];
if ( f !== undefined && f.match(url) !== false ) { if ( f !== undefined && f.match(url) ) {
return f; this.tokenRegister = '*';
this.fRegister = f;
return true;
} }
return false; return false;
@ -2106,60 +2238,66 @@ FilterContainer.prototype.matchStringExactType = function(context, requestURL, r
// Be prepared to support unknown types // Be prepared to support unknown types
var type = typeNameToTypeValue[requestType] || 0; var type = typeNameToTypeValue[requestType] || 0;
if ( type === 0 ) { if ( type === 0 ) {
return ''; return false;
} }
var categories = this.categories; var categories = this.categories;
var bf = false, bucket; var bucket;
// Tokenize only once // Tokenize only once
this.tokenize(url); this.tokenize(url);
this.fRegister = null;
// https://github.com/chrisaljoudi/uBlock/issues/139 // https://github.com/chrisaljoudi/uBlock/issues/139
// Test against important block filters // Test against important block filters
if ( bucket = categories[this.makeCategoryKey(BlockAnyParty | Important | type)] ) { if ( bucket = categories[this.makeCategoryKey(BlockAnyParty | Important | type)] ) {
bf = this.matchTokens(bucket, url); if ( this.matchTokens(bucket, url) ) {
if ( bf !== false ) { this.keyRegister = BlockAnyParty | Important | type;
return 'sb:' + bf.toString(); return true;
} }
} }
if ( bucket = categories[this.makeCategoryKey(BlockAction | Important | type | party)] ) { if ( bucket = categories[this.makeCategoryKey(BlockAction | Important | type | party)] ) {
bf = this.matchTokens(bucket, url); if ( this.matchTokens(bucket, url) ) {
if ( bf !== false ) { this.keyRegister = BlockAction | Important | type | party;
return 'sb:' + bf.toString(); return true;
} }
} }
// Test against block filters // Test against block filters
if ( bucket = categories[this.makeCategoryKey(BlockAnyParty | type)] ) { 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 ( bucket = categories[this.makeCategoryKey(BlockAction | type | party)] ) {
bf = this.matchTokens(bucket, url);
} }
} }
if ( this.fRegister === null ) {
if ( bucket = categories[this.makeCategoryKey(BlockAction | type | party)] ) {
if ( this.matchTokens(bucket, url) ) {
this.keyRegister = BlockAction | type | party;
}
}
}
// 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 ( bf === false ) { if ( this.fRegister === null ) {
return ''; return false;
} }
// Test against allow filters // Test against allow filters
var af;
if ( bucket = categories[this.makeCategoryKey(AllowAnyParty | type)] ) { if ( bucket = categories[this.makeCategoryKey(AllowAnyParty | type)] ) {
af = this.matchTokens(bucket, url); if ( this.matchTokens(bucket, url) ) {
if ( af !== false ) { this.keyRegister = AllowAnyParty | type;
return 'sa:' + af.toString(); return false;
} }
} }
if ( bucket = categories[this.makeCategoryKey(AllowAction | type | party)] ) { if ( bucket = categories[this.makeCategoryKey(AllowAction | type | party)] ) {
af = this.matchTokens(bucket, url); if ( this.matchTokens(bucket, url) ) {
if ( af !== false ) { this.keyRegister = AllowAction | type | party;
return 'sa:' + af.toString(); return false;
} }
} }
return 'sb:' + bf.toString(); return true;
}; };
/******************************************************************************/ /******************************************************************************/
@ -2212,7 +2350,7 @@ FilterContainer.prototype.matchString = function(context) {
// Tokenize only once // Tokenize only once
this.tokenize(url); this.tokenize(url);
var bf = false; this.fRegister = null;
// https://github.com/chrisaljoudi/uBlock/issues/139 // https://github.com/chrisaljoudi/uBlock/issues/139
// Test against important block filters. // Test against important block filters.
@ -2220,86 +2358,113 @@ FilterContainer.prototype.matchString = function(context) {
// evaluation. Normally, it is "evaluate block then evaluate allow", with // evaluation. Normally, it is "evaluate block then evaluate allow", with
// the `important` property it is "evaluate allow then evaluate block". // the `important` property it is "evaluate allow then evaluate block".
if ( bucket = filterClasses[this.makeCategoryKey(BlockAnyTypeAnyParty | Important)] ) { if ( bucket = filterClasses[this.makeCategoryKey(BlockAnyTypeAnyParty | Important)] ) {
bf = this.matchTokens(bucket, url); if ( this.matchTokens(bucket, url) ) {
if ( bf !== false ) { this.keyRegister = BlockAnyTypeAnyParty | Important;
return 'sb:' + bf.toString() + '$important'; return true;
} }
} }
if ( bucket = filterClasses[this.makeCategoryKey(BlockAnyType | Important | party)] ) { if ( bucket = filterClasses[this.makeCategoryKey(BlockAnyType | Important | party)] ) {
bf = this.matchTokens(bucket, url); if ( this.matchTokens(bucket, url) ) {
if ( bf !== false ) { this.keyRegister = BlockAnyType | Important | party;
return 'sb:' + bf.toString() + '$important'; return true;
} }
} }
if ( bucket = filterClasses[this.makeCategoryKey(BlockAnyParty | Important | type)] ) { if ( bucket = filterClasses[this.makeCategoryKey(BlockAnyParty | Important | type)] ) {
bf = this.matchTokens(bucket, url); if ( this.matchTokens(bucket, url) ) {
if ( bf !== false ) { this.keyRegister = BlockAnyParty | Important | type;
return 'sb:' + bf.toString() + '$important'; return true;
} }
} }
if ( bucket = filterClasses[this.makeCategoryKey(BlockAction | Important | type | party)] ) { if ( bucket = filterClasses[this.makeCategoryKey(BlockAction | Important | type | party)] ) {
bf = this.matchTokens(bucket, url); if ( this.matchTokens(bucket, url) ) {
if ( bf !== false ) { this.keyRegister = BlockAction | Important | type | party;
return 'sb:' + bf.toString() + '$important'; return true;
} }
} }
// Test against block filters // Test against block filters
if ( bf === false ) { if ( bucket = filterClasses[this.makeCategoryKey(BlockAnyTypeAnyParty)] ) {
if ( bucket = filterClasses[this.makeCategoryKey(BlockAnyTypeAnyParty)] ) { if ( this.matchTokens(bucket, url) ) {
bf = this.matchTokens(bucket, url); this.keyRegister = BlockAnyTypeAnyParty;
} }
} }
if ( bf === false ) { if ( this.fRegister === null ) {
if ( bucket = filterClasses[this.makeCategoryKey(BlockAnyType | party)] ) { if ( bucket = filterClasses[this.makeCategoryKey(BlockAnyType | party)] ) {
bf = this.matchTokens(bucket, url); if ( this.matchTokens(bucket, url) ) {
this.keyRegister = BlockAnyType | party;
}
} }
} if ( this.fRegister === null ) {
if ( bf === false ) { if ( bucket = filterClasses[this.makeCategoryKey(BlockAnyParty | type)] ) {
if ( bucket = filterClasses[this.makeCategoryKey(BlockAnyParty | type)] ) { if ( this.matchTokens(bucket, url) ) {
bf = this.matchTokens(bucket, url); this.keyRegister = BlockAnyParty | type;
} }
} }
if ( bf === false ) { if ( this.fRegister === null ) {
if ( bucket = filterClasses[this.makeCategoryKey(BlockAction | type | party)] ) { 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 there is no block filter, no need to test against allow filters
if ( bf === false ) { if ( this.fRegister === null ) {
return ''; return false;
} }
// Test against allow filters // Test against allow filters
var af;
if ( bucket = filterClasses[this.makeCategoryKey(AllowAnyTypeAnyParty)] ) { if ( bucket = filterClasses[this.makeCategoryKey(AllowAnyTypeAnyParty)] ) {
af = this.matchTokens(bucket, url); if ( this.matchTokens(bucket, url) ) {
if ( af !== false ) { this.keyRegister = AllowAnyTypeAnyParty;
return 'sa:' + af.toString(); return false;
} }
} }
if ( bucket = filterClasses[this.makeCategoryKey(AllowAnyType | party)] ) { if ( bucket = filterClasses[this.makeCategoryKey(AllowAnyType | party)] ) {
af = this.matchTokens(bucket, url); if ( this.matchTokens(bucket, url) ) {
if ( af !== false ) { this.keyRegister = AllowAnyType | party;
return 'sa:' + af.toString(); return false;
} }
} }
if ( bucket = filterClasses[this.makeCategoryKey(AllowAnyParty | type)] ) { if ( bucket = filterClasses[this.makeCategoryKey(AllowAnyParty | type)] ) {
af = this.matchTokens(bucket, url); if ( this.matchTokens(bucket, url) ) {
if ( af !== false ) { this.keyRegister = AllowAnyParty | type;
return 'sa:' + af.toString(); return false;
} }
} }
if ( bucket = filterClasses[this.makeCategoryKey(AllowAction | type | party)] ) { if ( bucket = filterClasses[this.makeCategoryKey(AllowAction | type | party)] ) {
af = this.matchTokens(bucket, url); if ( this.matchTokens(bucket, url) ) {
if ( af !== false ) { this.keyRegister = AllowAction | type | party;
return 'sa:' + af.toString(); 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;
}; };
/******************************************************************************/ /******************************************************************************/

View File

@ -1,7 +1,7 @@
/******************************************************************************* /*******************************************************************************
µBlock - a browser extension to block requests. uBlock - a browser extension to block requests.
Copyright (C) 2014 Raymond Hill Copyright (C) 2014-2015 Raymond Hill
This program is free software: you can redistribute it and/or modify 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 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 result = '';
var loggerEnabled = µb.logger.isEnabled();
// Check user switch first // Check user switch first
if ( µb.hnSwitches.evaluateZ('no-popups', openerHostname) ) { if ( µb.hnSwitches.evaluateZ('no-popups', openerHostname) ) {
@ -506,7 +507,9 @@ vAPI.tabs.onPopup = function(details) {
µb.getNetFilteringSwitch(openerURL) && µb.getNetFilteringSwitch(openerURL) &&
µb.getNetFilteringSwitch(targetURL) µ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 // https://github.com/chrisaljoudi/uBlock/issues/91
@ -514,15 +517,17 @@ vAPI.tabs.onPopup = function(details) {
if ( pageStore ) { if ( pageStore ) {
pageStore.logRequest(context, result); pageStore.logRequest(context, result);
} }
µb.logger.writeOne( if ( loggerEnabled ) {
details.openerTabId, µb.logger.writeOne(
'net', details.openerTabId,
result, 'net',
'popup', result,
targetURL, 'popup',
openerHostname, targetURL,
openerHostname openerHostname,
); openerHostname
);
}
// Not blocked // Not blocked
if ( µb.isAllowResult(result) ) { if ( µb.isAllowResult(result) ) {

View File

@ -1,7 +1,7 @@
/******************************************************************************* /*******************************************************************************
µBlock - a browser extension to block requests. uBlock - a browser extension to block requests.
Copyright (C) 2014 Raymond Hill Copyright (C) 2014-2015 Raymond Hill
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -185,11 +185,14 @@ var onBeforeRootFrameRequest = function(details) {
// Filtering // Filtering
if ( result === '' ) { if ( result === '' ) {
result = µb.staticNetFilteringEngine.matchString(context); if ( µb.staticNetFilteringEngine.matchString(context) ) {
// https://github.com/chrisaljoudi/uBlock/issues/1128 // We always need the long-form result here.
// Do not block if the match begins after the hostname. result = µb.staticNetFilteringEngine.toResultString(true);
if ( result !== '' ) { // https://github.com/chrisaljoudi/uBlock/issues/1128
result = toBlockDocResult(requestURL, requestHostname, result); // Do not block if the match begins after the hostname.
if ( result.charAt(1) === 'b' ) {
result = toBlockDocResult(requestURL, requestHostname, result);
}
} }
} }
@ -221,7 +224,7 @@ var onBeforeRootFrameRequest = function(details) {
url: requestURL, url: requestURL,
hn: requestHostname, hn: requestHostname,
dn: requestDomain, dn: requestDomain,
why: result why: µb.staticNetFilteringEngine.filterStringFromCompiled(result.slice(3))
})); }));
vAPI.tabs.replace(tabId, vAPI.getURL('document-blocked.html?details=') + query); 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) { 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 ''; 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); var matches = re.exec(url);
if ( matches === null ) { if ( matches === null ) {
return ''; return '';