redirection engine: code review

This commit is contained in:
gorhill 2015-11-23 23:34:03 -05:00
parent e96719f051
commit ba8b9ba008
6 changed files with 60 additions and 43 deletions

View File

@ -1,11 +1,11 @@
d644ffec21b802b4efb76365a576b86f assets/ublock/unbreak.txt
e65fbcaa573c028770f1d0afada55672 assets/ublock/redirect-resources.txt
7a04294b44b88baa34cf3e4bfe0e59db assets/ublock/privacy.txt
b2dbf435507aa0262b289c67cbef2142 assets/ublock/filters.txt
146704ad1c0393e342afdb416762c183 assets/ublock/badware.txt
4b3df06f0b27c57cea0006ae559e078b assets/ublock/redirect.txt
c9c5cc56bec563bc1885847f925b9be2 assets/ublock/mirror-candidates.txt
f9455a47b5024cc08ff3675ce79b58a9 assets/ublock/filter-lists.json
b7781a2ab4094b0ffa363caa6e29801d assets/ublock/redirect-rules.txt
94c0a3eab74c42783855f07b22a429cf assets/thirdparties/home.fredfiber.no/langsholt/adblock.txt
a82cb5ba5caf035ce00e97de81db5de7 assets/thirdparties/www.zoso.ro/pages/rolist.txt
72373316d0e7ad22604d307c2d93e7cc assets/thirdparties/adblock.gardar.net/is.abp.txt

View File

@ -1,4 +1,12 @@
redirects:
# Resources to be used as redirect destinations.
#
# - Each distinct resource entry is separated by an empty line.
# - The first line in a resource entry is: token mime-type[;encoding]
# - All following lines are the data. An empty line signals the end of the
# data.
#
# If the encoding is absent, the data will be converted to base64, and the
# encoding will be set to `;base64`.
hd-main.js application/javascript
var L = (function(){
@ -11,3 +19,6 @@ var L = (function(){
return l;
})();
# http://probablyprogramming.com/2009/03/15/the-tiniest-gif-ever
handtinytrans.gif image/gif;base64
R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==

View File

@ -40,7 +40,7 @@ var toBroaderHostname = function(hostname) {
/******************************************************************************/
var RedirectEngine = function() {
this.redirects = Object.create(null);
this.resources = Object.create(null);
this.reset();
};
@ -77,7 +77,7 @@ RedirectEngine.prototype.lookup = function(context) {
while ( i-- ) {
entry = entries[i];
if ( entry.c.test(reqURL) ) {
return this.redirects[entry.r];
return this.resources[entry.r];
}
}
}
@ -96,8 +96,6 @@ RedirectEngine.prototype.lookup = function(context) {
/******************************************************************************/
// TODO: combine same key-redirect pairs into a single regex.
RedirectEngine.prototype.addRule = function(src, des, type, pattern, redirect) {
var typeEntry = this.rules[type];
if ( typeEntry === undefined ) {
@ -159,7 +157,13 @@ RedirectEngine.prototype.compileRuleFromStaticFilter = function(line) {
}
}
if ( redirect === '' || types.length === 0 ) {
// Need a resource token.
if ( redirect === '' ) {
return '';
}
// Need one single type (not negated).
if ( types.length !== 1 || types[0].charAt(0) === '~' ) {
return '';
}
@ -172,12 +176,13 @@ RedirectEngine.prototype.compileRuleFromStaticFilter = function(line) {
}
var out = [];
var i = srcs.length, j;
var i = srcs.length, src;
while ( i-- ) {
j = types.length;
while ( j-- ) {
out.push(srcs[i] + '\t' + des + '\t' + types[j] + '\t' + pattern + '\t' + redirect);
src = srcs[i];
if ( src.charAt(0) === '~' ) {
continue;
}
out.push(srcs[i] + '\t' + des + '\t' + types[0] + '\t' + pattern + '\t' + redirect);
}
return out;
@ -203,12 +208,12 @@ RedirectEngine.prototype.supportedTypes = (function() {
// TODO: combine same key-redirect pairs into a single regex.
RedirectEngine.prototype.redirectDataFromString = function(text) {
RedirectEngine.prototype.resourcesFromString = function(text) {
var textEnd = text.length;
var lineBeg = 0, lineEnd;
var mode, modeData, line, fields, encoded, data;
var line, fields, resource, encoded, data;
this.redirects = Object.create(null);
this.resources = Object.create(null);
while ( lineBeg < textEnd ) {
lineEnd = text.indexOf('\n', lineBeg);
@ -225,37 +230,31 @@ RedirectEngine.prototype.redirectDataFromString = function(text) {
continue;
}
if ( line.slice(-1) === ':' ) {
mode = line.slice(0, -1);
continue;
}
if ( mode === 'redirects' ) {
if ( resource === undefined ) {
fields = line.split(/\s+/);
if ( fields.length !== 2 ) {
continue;
}
mode = 'redirects/redirect';
modeData = fields;
resource = fields;
continue;
}
if ( mode === 'redirects/redirect' ) {
if ( line !== '' ) {
modeData.push(line);
continue;
}
encoded = modeData[1].indexOf(';') !== -1;
data = modeData.slice(2).join(encoded ? '' : '\n');
this.redirects[modeData[0]] =
'data:' +
modeData[1] +
(encoded ? '' : ';base64') +
',' +
(encoded ? data : btoa(data));
mode = 'redirects';
if ( line !== '' ) {
resource.push(line);
continue;
}
// No more data, store the resource.
encoded = resource[1].indexOf(';') !== -1;
data = resource.slice(2).join(encoded ? '' : '\n');
this.resources[resource[0]] =
'data:' +
resource[1] +
(encoded ? '' : ';base64') +
',' +
(encoded ? data : btoa(data));
resource = undefined;
}
};

View File

@ -211,7 +211,7 @@ var onFirstFetchReady = function(fetched) {
fromFetch(µb.restoreBackupSettings, fetched);
onNetWhitelistReady(fetched.netWhitelist);
onVersionReady(fetched.version);
µb.loadRedirectRules();
µb.loadRedirectResources();
// If we have a selfie, skip loading PSL, filters
if ( onSelfieReady(fetched.selfie) ) {

View File

@ -1503,9 +1503,15 @@ FilterParser.prototype.parseOptions = function(s) {
continue;
}
if ( opt.lastIndexOf('redirect=', 0) === 0 ) {
this.redirect = true;
continue;
if ( this.action === BlockAction ) {
this.redirect = true;
continue;
}
this.unsupported = true;
break;
}
// Unrecognized filter option: ignore whole filter.
this.unsupported = true;
break;
}

View File

@ -650,20 +650,21 @@
// TODO: toSelfie/fromSelfie.
µBlock.loadRedirectRules = function(callback) {
µBlock.loadRedirectResources = function(callback) {
var µb = this;
if ( typeof callback !== 'function' ) {
callback = this.noopFunc;
}
var onRulesLoaded = function(details) {
var onResourcesLoaded = function(details) {
if ( details.content !== '' ) {
µb.redirectEngine.redirectDataFromString(details.content);
µb.redirectEngine.resourcesFromString(details.content);
}
callback();
};
this.assets.get('assets/ublock/redirect-rules.txt', onRulesLoaded);
this.assets.get('assets/ublock/redirect-resources.txt', onResourcesLoaded);
};
/******************************************************************************/