add pre-processor directives to filter list compiler (https://github.com/AdguardTeam/AdguardBrowserExtension/issues/917)

This commit is contained in:
Raymond Hill 2018-04-05 07:29:15 -04:00
parent 5729950779
commit 93f49a61d7
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
9 changed files with 135 additions and 43 deletions

View File

@ -499,7 +499,10 @@ vAPI.tabs.open = function(details) {
// https://github.com/gorhill/uBlock/issues/3053#issuecomment-332276818
// - Do not try to lookup uBO's own pages with FF 55 or less.
if ( /^Mozilla-Firefox-5[2-5]\./.test(vAPI.webextFlavor) ) {
if (
vAPI.webextFlavor.soup.has('firefox') &&
vAPI.webextFlavor.major < 56
) {
wrapper();
return;
}
@ -1139,7 +1142,7 @@ vAPI.cloud = (function() {
var evalMaxChunkSize = function() {
return Math.floor(
(chrome.storage.sync.QUOTA_BYTES_PER_ITEM || 8192) *
(vAPI.webextFlavor.startsWith('Mozilla-Firefox-') ? 0.6 : 0.75)
(vAPI.webextFlavor.soup.has('firefox') ? 0.6 : 0.75)
);
};
@ -1247,7 +1250,7 @@ vAPI.cloud = (function() {
// until such cases are reported for other browsers, we will
// reset the (now corrupted) content of the cloud storage
// only on Firefox.
if ( vAPI.webextFlavor.startsWith('Mozilla-Firefox-') ) {
if ( vAPI.webextFlavor.soup.has('firefox') ) {
chunkCount = 0;
}
}

View File

@ -1,7 +1,7 @@
/*******************************************************************************
uBlock Origin - a browser extension to block requests.
Copyright (C) 2014-2017 The uBlock Origin authors
Copyright (C) 2014-2018 The uBlock Origin authors
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
@ -36,46 +36,67 @@ vAPI.setTimeout = vAPI.setTimeout || self.setTimeout.bind(self);
/******************************************************************************/
vAPI.webextFlavor = (function() {
vAPI.webextFlavor = {
major: 0,
soup: new Set()
};
(function() {
var ua = navigator.userAgent,
match, reEx;
match, reEx,
flavor = vAPI.webextFlavor;
var dispatch = function() {
window.dispatchEvent(new CustomEvent('webextFlavor'));
};
// Order of tests is important!
if ( /\bMobile\b/.test(ua) ) {
flavor.soup.add('mobile');
}
// Asynchronous
if (
self.browser instanceof Object &&
typeof self.browser.runtime.getBrowserInfo === 'function'
) {
self.browser.runtime.getBrowserInfo().then(function(info) {
vAPI.webextFlavor =
info.vendor + '-' + info.name + '-' + info.version;
flavor.major = parseInt(info.version, 10) || 0;
flavor.soup.add(info.vendor.toLowerCase())
.add(info.name.toLowerCase());
dispatch();
});
match = /Firefox\/([\d.]+)/.exec(ua);
return match !== null ? 'Mozilla-Firefox-' + match[1] : '';
if ( match !== null ) {
flavor.major = parseInt(match[1], 10) || 0;
flavor.soup.add('mozilla').add('firefox');
}
return;
}
// Synchronous
/* Don't starve potential listeners: */ vAPI.setTimeout(dispatch, 97);
match = /OPR\/([\d.]+)/.exec(ua);
if ( match !== null ) {
reEx = /Chrom(?:e|ium)\/([\d.]+)/;
if ( reEx.test(ua) ) { match = reEx.exec(ua); }
return 'Opera-Chromium-' + match[1];
flavor.major = parseInt(match[1], 10) || 0;
flavor.soup.add('opera').add('chromium');
return;
}
match = /Chromium\/([\d.]+)/.exec(ua);
if ( match !== null ) {
return 'Chromium-Chromium-' + match[1];
flavor.major = parseInt(match[1], 10) || 0;
flavor.soup.add('chromium');
return;
}
match = /Chrome\/([\d.]+)/.exec(ua);
if ( match !== null ) {
return 'Google-Chromium-' + match[1];
flavor.major = parseInt(match[1], 10) || 0;
flavor.soup.add('google').add('chromium');
return;
}
return '';
})();
/******************************************************************************/
@ -121,7 +142,7 @@ setScriptDirection(vAPI.i18n('@@ui_locale'));
// `window.open('', '_self').close()`.
vAPI.closePopup = function() {
if ( /^Mozilla-Firefox-/.test(vAPI.webextFlavor) ) {
if ( vAPI.webextFlavor.soup.has('firefox') ) {
window.close();
return;
}

View File

@ -41,10 +41,11 @@ vAPI.net = {
vAPI.net.registerListeners = function() {
// https://github.com/gorhill/uBlock/issues/2950
// Firefox 55 does not normalize URLs to ASCII, uBO must do this itself.
// Firefox 56 does not normalize URLs to ASCII, uBO must do this itself.
// https://bugzilla.mozilla.org/show_bug.cgi?id=945240
let evalMustPunycode = function() {
return /^Mozilla-Firefox-5[0-6]/.test(vAPI.webextFlavor);
return vAPI.webextFlavor.soup.has('firefox') &&
vAPI.webextFlavor.major < 57;
};
let mustPunycode = evalMustPunycode();

View File

@ -177,7 +177,24 @@ api.fetchFilterList = function(mainlistURL, onLoad, onError) {
pendingSublistURLs = new Set([ mainlistURL ]),
loadedSublistURLs = new Set(),
toParsedURL = api.fetchFilterList.toParsedURL,
parsedMainURL = toParsedURL(mainlistURL);
parsedURL = toParsedURL(mainlistURL);
var processIncludeDirectives = function(details) {
var reInclude = /^!#include +(\S+)/gm;
for (;;) {
var match = reInclude.exec(details.content);
if ( match === null ) { break; }
if ( toParsedURL(match[1]) !== undefined ) { continue; }
if ( match[1].indexOf('..') !== -1 ) { continue; }
var subURL =
parsedURL.origin +
parsedURL.pathname.replace(/[^/]+$/, match[1]);
if ( pendingSublistURLs.has(subURL) ) { continue; }
if ( loadedSublistURLs.has(subURL) ) { continue; }
pendingSublistURLs.add(subURL);
api.fetchText(subURL, onLocalLoadSuccess, onLocalLoadError);
}
};
var onLocalLoadSuccess = function(details) {
if ( errored ) { return; }
@ -189,24 +206,8 @@ api.fetchFilterList = function(mainlistURL, onLoad, onError) {
if ( isSublist ) { content.push('\n! ' + '>>>>>>>> ' + details.url); }
content.push(details.content.trim());
if ( isSublist ) { content.push('! <<<<<<<< ' + details.url); }
if (
parsedMainURL !== undefined &&
parsedMainURL.pathname.length > 0
) {
var reInclude = /^!#include +(\S+)/gm;
for (;;) {
var match = reInclude.exec(details.content);
if ( match === null ) { break; }
if ( toParsedURL(match[1]) !== undefined ) { continue; }
if ( match[1].indexOf('..') !== -1 ) { continue; }
var subURL =
parsedMainURL.origin +
parsedMainURL.pathname.replace(/[^/]+$/, match[1]);
if ( pendingSublistURLs.has(subURL) ) { continue; }
if ( loadedSublistURLs.has(subURL) ) { continue; }
pendingSublistURLs.add(subURL);
api.fetchText(subURL, onLocalLoadSuccess, onLocalLoadError);
}
if ( parsedURL !== undefined && parsedURL.pathname.length > 0 ) {
processIncludeDirectives(details);
}
if ( pendingSublistURLs.size !== 0 ) { return; }
@ -912,7 +913,7 @@ var updateFirst = function() {
typeof browser === 'object' &&
browser.runtime.getManifest();
noRemoteResources =
/^Mozilla-Firefox-/.test(vAPI.webextFlavor) &&
vAPI.webextFlavor.soup.has('firefox') &&
manifest instanceof Object &&
manifest.applications instanceof Object &&
manifest.applications.gecko instanceof Object &&

View File

@ -26,6 +26,14 @@
/******************************************************************************/
// Not all platforms may have properly declared vAPI.webextFlavor.
if ( vAPI.webextFlavor === undefined ) {
vAPI.webextFlavor = { major: 0, soup: new Set() };
}
/******************************************************************************/
var µBlock = (function() { // jshint ignore:line
var oneSecond = 1000,
@ -111,6 +119,7 @@ var µBlock = (function() { // jshint ignore:line
'moz-extension-scheme',
'opera-scheme',
'vivaldi-scheme',
'wyciwyg-scheme', // Firefox's "What-You-Cache-Is-What-You-Get"
''
].join('\n'),

View File

@ -109,7 +109,7 @@ var onVersionReady = function(lastVersion) {
// new version is detected, as resources.txt may have changed since last
// release. This will be done only for release versions of Firefox.
if (
/^Mozilla-Firefox-/.test(vAPI.webextFlavor) &&
vAPI.webextFlavor.soup.has('firefox') &&
/(b|rc)\d+$/.test(vAPI.app.version) === false
) {
µb.redirectEngine.invalidateResourcesSelfie();

View File

@ -1605,7 +1605,10 @@ FilterParser.prototype.translate = function() {
this.dataStr = "connect-src https: http:";
// https://bugs.chromium.org/p/chromium/issues/detail?id=669086
// TODO: remove when most users are beyond Chromium v56
if ( /-Chromium-(?:4|5[0-6])/.test(vAPI.webextFlavor) ) {
if (
vAPI.webextFlavor.soup.has('chromium') &&
vAPI.webextFlavor.major < 57
) {
this.dataStr += '; frame-src *';
}
return;

View File

@ -778,15 +778,13 @@
reIsLocalhostRedirect = /\s+(?:broadcasthost|local|localhost|localhost\.localdomain)\b/,
reLocalIp = /^(?:0\.0\.0\.0|127\.0\.0\.1|::1|fe80::1%lo0)/,
line, c, pos,
lineIter = new this.LineIterator(rawText);
lineIter = new this.LineIterator(this.processDirectives(rawText));
while ( lineIter.eot() === false ) {
line = lineIter.next().trim();
// rhill 2014-04-18: The trim is important here, as without it there
// could be a lingering `\r` which would cause problems in the
// following parsing code.
line = lineIter.next().trim();
if ( line.length === 0 ) { continue; }
// Strip comments
@ -851,6 +849,61 @@
/******************************************************************************/
// https://github.com/AdguardTeam/AdguardBrowserExtension/issues/917
µBlock.processDirectives = function(content) {
var reIf = /^!#(if|endif)\b([^\n]*)/gm,
parts = [],
beg = 0, depth = 0, discard = false;
while ( beg < content.length ) {
var match = reIf.exec(content);
if ( match === null ) { break; }
if ( match[1] === 'if' ) {
var expr = match[2].trim();
var target = expr.startsWith('!');
if ( target ) { expr = expr.slice(1); }
var token = this.processDirectives.tokens.get(expr);
if (
depth === 0 &&
discard === false &&
token !== undefined &&
vAPI.webextFlavor.soup.has(token) === target
) {
parts.push(content.slice(beg, match.index));
discard = true;
}
depth += 1;
continue;
}
depth -= 1;
if ( depth < 0 ) { break; }
if ( depth === 0 && discard ) {
beg = match.index + match[0].length + 1;
discard = false;
}
}
if ( depth === 0 && parts.length !== 0 ) {
parts.push(content.slice(beg));
content = parts.join('\n');
}
return content.trim();
};
µBlock.processDirectives.tokens = new Map([
[ 'ext_chromium', 'chromium' ],
[ 'ext_edge', 'edge' ],
[ 'ext_firefox', 'firefox' ],
[ 'ext_mobile', 'mobile' ],
[ 'ext_safari', 'safari' ],
[ 'adguard_ext_chromium', 'chromium' ],
[ 'adguard_ext_edge', 'edge' ],
[ 'adguard_ext_firefox', 'firefox' ],
[ 'adguard_ext_mobile', 'mobile' ],
[ 'adguard_ext_safari', 'safari' ],
]);
/******************************************************************************/
µBlock.loadRedirectResources = function(updatedContent) {
var µb = this,
content = '';

View File

@ -1127,7 +1127,8 @@ var injectCSP = function(pageStore, details) {
// https://github.com/gorhill/uMatrix/issues/967#issuecomment-373002011
// This can be removed once Firefox 60 ESR is released.
var evalCantMergeCSPHeaders = function() {
return /^Mozilla-Firefox-5[2-8]/.test(vAPI.webextFlavor);
return vAPI.webextFlavor.soup.has('firefox') &&
vAPI.webextFlavor.major < 59;
};
var cantMergeCSPHeaders = evalCantMergeCSPHeaders();