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 d644ffec21b802b4efb76365a576b86f assets/ublock/unbreak.txt
e65fbcaa573c028770f1d0afada55672 assets/ublock/redirect-resources.txt
7a04294b44b88baa34cf3e4bfe0e59db assets/ublock/privacy.txt 7a04294b44b88baa34cf3e4bfe0e59db assets/ublock/privacy.txt
b2dbf435507aa0262b289c67cbef2142 assets/ublock/filters.txt b2dbf435507aa0262b289c67cbef2142 assets/ublock/filters.txt
146704ad1c0393e342afdb416762c183 assets/ublock/badware.txt 146704ad1c0393e342afdb416762c183 assets/ublock/badware.txt
4b3df06f0b27c57cea0006ae559e078b assets/ublock/redirect.txt 4b3df06f0b27c57cea0006ae559e078b assets/ublock/redirect.txt
c9c5cc56bec563bc1885847f925b9be2 assets/ublock/mirror-candidates.txt c9c5cc56bec563bc1885847f925b9be2 assets/ublock/mirror-candidates.txt
f9455a47b5024cc08ff3675ce79b58a9 assets/ublock/filter-lists.json f9455a47b5024cc08ff3675ce79b58a9 assets/ublock/filter-lists.json
b7781a2ab4094b0ffa363caa6e29801d assets/ublock/redirect-rules.txt
94c0a3eab74c42783855f07b22a429cf assets/thirdparties/home.fredfiber.no/langsholt/adblock.txt 94c0a3eab74c42783855f07b22a429cf assets/thirdparties/home.fredfiber.no/langsholt/adblock.txt
a82cb5ba5caf035ce00e97de81db5de7 assets/thirdparties/www.zoso.ro/pages/rolist.txt a82cb5ba5caf035ce00e97de81db5de7 assets/thirdparties/www.zoso.ro/pages/rolist.txt
72373316d0e7ad22604d307c2d93e7cc assets/thirdparties/adblock.gardar.net/is.abp.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 hd-main.js application/javascript
var L = (function(){ var L = (function(){
@ -11,3 +19,6 @@ var L = (function(){
return l; 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() { var RedirectEngine = function() {
this.redirects = Object.create(null); this.resources = Object.create(null);
this.reset(); this.reset();
}; };
@ -77,7 +77,7 @@ RedirectEngine.prototype.lookup = function(context) {
while ( i-- ) { while ( i-- ) {
entry = entries[i]; entry = entries[i];
if ( entry.c.test(reqURL) ) { 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) { RedirectEngine.prototype.addRule = function(src, des, type, pattern, redirect) {
var typeEntry = this.rules[type]; var typeEntry = this.rules[type];
if ( typeEntry === undefined ) { 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 ''; return '';
} }
@ -172,12 +176,13 @@ RedirectEngine.prototype.compileRuleFromStaticFilter = function(line) {
} }
var out = []; var out = [];
var i = srcs.length, j; var i = srcs.length, src;
while ( i-- ) { while ( i-- ) {
j = types.length; src = srcs[i];
while ( j-- ) { if ( src.charAt(0) === '~' ) {
out.push(srcs[i] + '\t' + des + '\t' + types[j] + '\t' + pattern + '\t' + redirect); continue;
} }
out.push(srcs[i] + '\t' + des + '\t' + types[0] + '\t' + pattern + '\t' + redirect);
} }
return out; return out;
@ -203,12 +208,12 @@ RedirectEngine.prototype.supportedTypes = (function() {
// TODO: combine same key-redirect pairs into a single regex. // 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 textEnd = text.length;
var lineBeg = 0, lineEnd; 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 ) { while ( lineBeg < textEnd ) {
lineEnd = text.indexOf('\n', lineBeg); lineEnd = text.indexOf('\n', lineBeg);
@ -225,37 +230,31 @@ RedirectEngine.prototype.redirectDataFromString = function(text) {
continue; continue;
} }
if ( line.slice(-1) === ':' ) { if ( resource === undefined ) {
mode = line.slice(0, -1);
continue;
}
if ( mode === 'redirects' ) {
fields = line.split(/\s+/); fields = line.split(/\s+/);
if ( fields.length !== 2 ) { if ( fields.length !== 2 ) {
continue; continue;
} }
mode = 'redirects/redirect'; resource = fields;
modeData = fields;
continue; continue;
} }
if ( mode === 'redirects/redirect' ) {
if ( line !== '' ) { if ( line !== '' ) {
modeData.push(line); resource.push(line);
continue; continue;
} }
encoded = modeData[1].indexOf(';') !== -1;
data = modeData.slice(2).join(encoded ? '' : '\n'); // No more data, store the resource.
this.redirects[modeData[0]] = encoded = resource[1].indexOf(';') !== -1;
data = resource.slice(2).join(encoded ? '' : '\n');
this.resources[resource[0]] =
'data:' + 'data:' +
modeData[1] + resource[1] +
(encoded ? '' : ';base64') + (encoded ? '' : ';base64') +
',' + ',' +
(encoded ? data : btoa(data)); (encoded ? data : btoa(data));
mode = 'redirects';
continue; resource = undefined;
}
} }
}; };

View File

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

View File

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

View File

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