mirror of
https://github.com/gorhill/uBlock.git
synced 2024-11-06 19:02:30 +01:00
Squashed commit of the following:
commit 7c6cacc59b27660fabacb55d668ef099b222a9e6 Author: Raymond Hill <rhill@raymondhill.net> Date: Sat Nov 3 08:52:51 2018 -0300 code review: finalize support for wasm-based hntrie commit 8596ed80e3bdac2c36e3c860b51e7189f6bc8487 Merge: cbe1f2e000eb82
Author: Raymond Hill <rhill@raymondhill.net> Date: Sat Nov 3 08:41:40 2018 -0300 Merge branch 'master' of github.com:gorhill/uBlock into trie-wasm commit cbe1f2e2f38484d42af3204ec7f1b5decd30f99e Merge: 270fc7fdbb7e80
Author: Raymond Hill <rhill@raymondhill.net> Date: Fri Nov 2 17:43:20 2018 -0300 Merge branch 'master' of github.com:gorhill/uBlock into trie-wasm commit 270fc7f9b3b73d79e6355522c1a42ce782fe7e5c Merge: d2a89cfd693d4f
Author: Raymond Hill <rhill@raymondhill.net> Date: Fri Nov 2 16:21:08 2018 -0300 Merge branch 'master' of github.com:gorhill/uBlock into trie-wasm commit d2a89cf28f0816ffd4617c2c7b4ccfcdcc30e1b4 Merge: d7afc78649f82f
Author: Raymond Hill <rhill@raymondhill.net> Date: Fri Nov 2 14:54:58 2018 -0300 Merge branch 'master' of github.com:gorhill/uBlock into trie-wasm commit d7afc78b5f5675d7d34c5a1d0ec3099a77caef49 Author: Raymond Hill <rhill@raymondhill.net> Date: Fri Nov 2 13:56:11 2018 -0300 finalize wasm-based hntrie implementation commit e7b9e043cf36ad055791713e34eb0322dec84627 Author: Raymond Hill <rhill@raymondhill.net> Date: Fri Nov 2 08:14:02 2018 -0300 add first-pass implementation of wasm version of hntrie commit 1015cb34624f3ef73ace58b58fe4e03dfc59897f Author: Raymond Hill <rhill@raymondhill.net> Date: Wed Oct 31 17:16:47 2018 -0300 back up draft work toward experimenting with wasm hntries
This commit is contained in:
parent
000eb82f08
commit
d7d544cda0
@ -33,12 +33,12 @@ if ( vAPI.webextFlavor === undefined ) {
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var µBlock = (function() { // jshint ignore:line
|
const µBlock = (function() { // jshint ignore:line
|
||||||
|
|
||||||
var oneSecond = 1000,
|
const oneSecond = 1000,
|
||||||
oneMinute = 60 * oneSecond;
|
oneMinute = 60 * oneSecond;
|
||||||
|
|
||||||
var hiddenSettingsDefault = {
|
const hiddenSettingsDefault = {
|
||||||
assetFetchTimeout: 30,
|
assetFetchTimeout: 30,
|
||||||
autoUpdateAssetFetchPeriod: 120,
|
autoUpdateAssetFetchPeriod: 120,
|
||||||
autoUpdatePeriod: 7,
|
autoUpdatePeriod: 7,
|
||||||
@ -56,7 +56,7 @@ var µBlock = (function() { // jshint ignore:line
|
|||||||
userResourcesLocation: 'unset'
|
userResourcesLocation: 'unset'
|
||||||
};
|
};
|
||||||
|
|
||||||
var whitelistDefault = [
|
const whitelistDefault = [
|
||||||
'about-scheme',
|
'about-scheme',
|
||||||
'chrome-extension-scheme',
|
'chrome-extension-scheme',
|
||||||
'chrome-scheme',
|
'chrome-scheme',
|
||||||
|
974
src/js/hntrie.js
974
src/js/hntrie.js
File diff suppressed because it is too large
Load Diff
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var µb = µBlock;
|
const µb = µBlock;
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
@ -287,7 +287,12 @@ var onFirstFetchReady = function(fetched) {
|
|||||||
onVersionReady(fetched.version);
|
onVersionReady(fetched.version);
|
||||||
onCommandShortcutsReady(fetched.commandShortcuts);
|
onCommandShortcutsReady(fetched.commandShortcuts);
|
||||||
|
|
||||||
µb.loadPublicSuffixList(onPSLReady);
|
Promise.all([
|
||||||
|
µb.loadPublicSuffixList(),
|
||||||
|
µb.staticNetFilteringEngine.readyToUse()
|
||||||
|
]).then(( ) => {
|
||||||
|
onPSLReady();
|
||||||
|
});
|
||||||
µb.loadRedirectResources();
|
µb.loadRedirectResources();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* jshint bitwise: false */
|
/* jshint bitwise: false */
|
||||||
/* global punycode, HNTrieBuilder */
|
/* global punycode, hnTrieManager */
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var µb = µBlock;
|
const µb = µBlock;
|
||||||
|
|
||||||
// fedcba9876543210
|
// fedcba9876543210
|
||||||
// | | |||
|
// | | |||
|
||||||
@ -43,15 +43,15 @@ var µb = µBlock;
|
|||||||
// | +-------- bit 4- 8: type [0 - 31]
|
// | +-------- bit 4- 8: type [0 - 31]
|
||||||
// +------------- bit 9-15: unused
|
// +------------- bit 9-15: unused
|
||||||
|
|
||||||
var BlockAction = 0 << 0;
|
const BlockAction = 0 << 0;
|
||||||
var AllowAction = 1 << 0;
|
const AllowAction = 1 << 0;
|
||||||
var Important = 1 << 1;
|
const Important = 1 << 1;
|
||||||
var AnyParty = 0 << 2;
|
const AnyParty = 0 << 2;
|
||||||
var FirstParty = 1 << 2;
|
const FirstParty = 1 << 2;
|
||||||
var ThirdParty = 2 << 2;
|
const ThirdParty = 2 << 2;
|
||||||
|
|
||||||
var AnyType = 0 << 4;
|
const AnyType = 0 << 4;
|
||||||
var typeNameToTypeValue = {
|
const typeNameToTypeValue = {
|
||||||
'no_type': 0 << 4,
|
'no_type': 0 << 4,
|
||||||
'stylesheet': 1 << 4,
|
'stylesheet': 1 << 4,
|
||||||
'image': 2 << 4,
|
'image': 2 << 4,
|
||||||
@ -75,9 +75,9 @@ var typeNameToTypeValue = {
|
|||||||
'webrtc': 19 << 4,
|
'webrtc': 19 << 4,
|
||||||
'unsupported': 20 << 4
|
'unsupported': 20 << 4
|
||||||
};
|
};
|
||||||
var otherTypeBitValue = typeNameToTypeValue.other;
|
const otherTypeBitValue = typeNameToTypeValue.other;
|
||||||
|
|
||||||
var typeValueToTypeName = {
|
const typeValueToTypeName = {
|
||||||
1: 'stylesheet',
|
1: 'stylesheet',
|
||||||
2: 'image',
|
2: 'image',
|
||||||
3: 'object',
|
3: 'object',
|
||||||
@ -100,16 +100,16 @@ var typeValueToTypeName = {
|
|||||||
20: 'unsupported'
|
20: 'unsupported'
|
||||||
};
|
};
|
||||||
|
|
||||||
var BlockAnyTypeAnyParty = BlockAction | AnyType | AnyParty;
|
const BlockAnyTypeAnyParty = BlockAction | AnyType | AnyParty;
|
||||||
var BlockAnyType = BlockAction | AnyType;
|
const BlockAnyType = BlockAction | AnyType;
|
||||||
var BlockAnyParty = BlockAction | AnyParty;
|
const BlockAnyParty = BlockAction | AnyParty;
|
||||||
|
|
||||||
var AllowAnyTypeAnyParty = AllowAction | AnyType | AnyParty;
|
const AllowAnyTypeAnyParty = AllowAction | AnyType | AnyParty;
|
||||||
var AllowAnyType = AllowAction | AnyType;
|
const AllowAnyType = AllowAction | AnyType;
|
||||||
var AllowAnyParty = AllowAction | AnyParty;
|
const AllowAnyParty = AllowAction | AnyParty;
|
||||||
|
|
||||||
var genericHideException = AllowAction | AnyParty | typeNameToTypeValue.generichide,
|
const genericHideException = AllowAction | AnyParty | typeNameToTypeValue.generichide,
|
||||||
genericHideImportant = BlockAction | AnyParty | typeNameToTypeValue.generichide | Important;
|
genericHideImportant = BlockAction | AnyParty | typeNameToTypeValue.generichide | Important;
|
||||||
|
|
||||||
// ABP filters: https://adblockplus.org/en/filters
|
// ABP filters: https://adblockplus.org/en/filters
|
||||||
// regex tester: http://regex101.com/
|
// regex tester: http://regex101.com/
|
||||||
@ -119,7 +119,7 @@ var genericHideException = AllowAction | AnyParty | typeNameToTypeValue.generich
|
|||||||
// See the following as short-lived registers, used during evaluation. They are
|
// See the following as short-lived registers, used during evaluation. They are
|
||||||
// valid until the next evaluation.
|
// valid until the next evaluation.
|
||||||
|
|
||||||
var pageHostnameRegister = '',
|
let pageHostnameRegister = '',
|
||||||
requestHostnameRegister = '';
|
requestHostnameRegister = '';
|
||||||
//var filterRegister = null;
|
//var filterRegister = null;
|
||||||
//var categoryRegister = '';
|
//var categoryRegister = '';
|
||||||
@ -127,13 +127,13 @@ var pageHostnameRegister = '',
|
|||||||
// Local helpers
|
// Local helpers
|
||||||
|
|
||||||
// Be sure to not confuse 'example.com' with 'anotherexample.com'
|
// Be sure to not confuse 'example.com' with 'anotherexample.com'
|
||||||
var isFirstParty = function(domain, hostname) {
|
const isFirstParty = function(domain, hostname) {
|
||||||
return hostname.endsWith(domain) &&
|
return hostname.endsWith(domain) &&
|
||||||
(hostname.length === domain.length ||
|
(hostname.length === domain.length ||
|
||||||
hostname.charCodeAt(hostname.length - domain.length - 1) === 0x2E /* '.' */);
|
hostname.charCodeAt(hostname.length - domain.length - 1) === 0x2E /* '.' */);
|
||||||
};
|
};
|
||||||
|
|
||||||
var normalizeRegexSource = function(s) {
|
const normalizeRegexSource = function(s) {
|
||||||
try {
|
try {
|
||||||
var re = new RegExp(s);
|
var re = new RegExp(s);
|
||||||
return re.source;
|
return re.source;
|
||||||
@ -143,12 +143,12 @@ var normalizeRegexSource = function(s) {
|
|||||||
return '';
|
return '';
|
||||||
};
|
};
|
||||||
|
|
||||||
var rawToRegexStr = function(s, anchor) {
|
const rawToRegexStr = function(s, anchor) {
|
||||||
var me = rawToRegexStr;
|
let me = rawToRegexStr;
|
||||||
// https://www.loggly.com/blog/five-invaluable-techniques-to-improve-regex-performance/
|
// https://www.loggly.com/blog/five-invaluable-techniques-to-improve-regex-performance/
|
||||||
// https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions
|
// https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions
|
||||||
// Also: remove leading/trailing wildcards -- there is no point.
|
// Also: remove leading/trailing wildcards -- there is no point.
|
||||||
var reStr = s.replace(me.escape1, '\\$&')
|
let reStr = s.replace(me.escape1, '\\$&')
|
||||||
.replace(me.escape2, '(?:[^%.0-9a-z_-]|$)')
|
.replace(me.escape2, '(?:[^%.0-9a-z_-]|$)')
|
||||||
.replace(me.escape3, '')
|
.replace(me.escape3, '')
|
||||||
.replace(me.escape4, '[^ ]*?');
|
.replace(me.escape4, '[^ ]*?');
|
||||||
@ -175,7 +175,7 @@ rawToRegexStr.reTextHostnameAnchor2 = '^[a-z-]+://(?:[^/?#]+)?';
|
|||||||
|
|
||||||
const filterDataSerialize = µb.CompiledLineIO.serialize;
|
const filterDataSerialize = µb.CompiledLineIO.serialize;
|
||||||
|
|
||||||
var toLogDataInternal = function(categoryBits, tokenHash, filter) {
|
const toLogDataInternal = function(categoryBits, tokenHash, filter) {
|
||||||
if ( filter === null ) { return undefined; }
|
if ( filter === null ) { return undefined; }
|
||||||
let logData = filter.logData();
|
let logData = filter.logData();
|
||||||
logData.compiled = filterDataSerialize([
|
logData.compiled = filterDataSerialize([
|
||||||
@ -209,7 +209,7 @@ var toLogDataInternal = function(categoryBits, tokenHash, filter) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// First character of match must be within the hostname part of the url.
|
// First character of match must be within the hostname part of the url.
|
||||||
var isHnAnchored = function(url, matchStart) {
|
const isHnAnchored = function(url, matchStart) {
|
||||||
var hnStart = url.indexOf('://');
|
var hnStart = url.indexOf('://');
|
||||||
if ( hnStart === -1 ) { return false; }
|
if ( hnStart === -1 ) { return false; }
|
||||||
hnStart += 3;
|
hnStart += 3;
|
||||||
@ -222,9 +222,9 @@ var isHnAnchored = function(url, matchStart) {
|
|||||||
return url.charCodeAt(matchStart - 1) === 0x2E;
|
return url.charCodeAt(matchStart - 1) === 0x2E;
|
||||||
};
|
};
|
||||||
|
|
||||||
var reURLPostHostnameAnchors = /[\/?#]/;
|
const reURLPostHostnameAnchors = /[\/?#]/;
|
||||||
|
|
||||||
var arrayStrictEquals = function(a, b) {
|
const arrayStrictEquals = function(a, b) {
|
||||||
var n = a.length;
|
var n = a.length;
|
||||||
if ( n !== b.length ) { return false; }
|
if ( n !== b.length ) { return false; }
|
||||||
var isArray, x, y;
|
var isArray, x, y;
|
||||||
@ -251,22 +251,22 @@ var arrayStrictEquals = function(a, b) {
|
|||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
var filterClasses = [],
|
const filterClasses = [];
|
||||||
filterClassIdGenerator = 0;
|
let filterClassIdGenerator = 0;
|
||||||
|
|
||||||
var registerFilterClass = function(ctor) {
|
const registerFilterClass = function(ctor) {
|
||||||
var fid = filterClassIdGenerator++;
|
let fid = filterClassIdGenerator++;
|
||||||
ctor.fid = ctor.prototype.fid = fid;
|
ctor.fid = ctor.prototype.fid = fid;
|
||||||
filterClasses[fid] = ctor;
|
filterClasses[fid] = ctor;
|
||||||
};
|
};
|
||||||
|
|
||||||
var filterFromCompiledData = function(args) {
|
const filterFromCompiledData = function(args) {
|
||||||
return filterClasses[args[0]].load(args);
|
return filterClasses[args[0]].load(args);
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterTrue = function() {
|
const FilterTrue = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterTrue.prototype.match = function() {
|
FilterTrue.prototype.match = function() {
|
||||||
@ -297,7 +297,7 @@ registerFilterClass(FilterTrue);
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterPlain = function(s, tokenBeg) {
|
const FilterPlain = function(s, tokenBeg) {
|
||||||
this.s = s;
|
this.s = s;
|
||||||
this.tokenBeg = tokenBeg;
|
this.tokenBeg = tokenBeg;
|
||||||
};
|
};
|
||||||
@ -330,7 +330,7 @@ registerFilterClass(FilterPlain);
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterPlainPrefix0 = function(s) {
|
const FilterPlainPrefix0 = function(s) {
|
||||||
this.s = s;
|
this.s = s;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -362,7 +362,7 @@ registerFilterClass(FilterPlainPrefix0);
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterPlainPrefix1 = function(s) {
|
const FilterPlainPrefix1 = function(s) {
|
||||||
this.s = s;
|
this.s = s;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -394,7 +394,7 @@ registerFilterClass(FilterPlainPrefix1);
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterPlainHostname = function(s) {
|
const FilterPlainHostname = function(s) {
|
||||||
this.s = s;
|
this.s = s;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -429,7 +429,7 @@ registerFilterClass(FilterPlainHostname);
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterPlainLeftAnchored = function(s) {
|
const FilterPlainLeftAnchored = function(s) {
|
||||||
this.s = s;
|
this.s = s;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -461,7 +461,7 @@ registerFilterClass(FilterPlainLeftAnchored);
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterPlainRightAnchored = function(s) {
|
const FilterPlainRightAnchored = function(s) {
|
||||||
this.s = s;
|
this.s = s;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -493,7 +493,7 @@ registerFilterClass(FilterPlainRightAnchored);
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterExactMatch = function(s) {
|
const FilterExactMatch = function(s) {
|
||||||
this.s = s;
|
this.s = s;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -525,7 +525,7 @@ registerFilterClass(FilterExactMatch);
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterPlainHnAnchored = function(s) {
|
const FilterPlainHnAnchored = function(s) {
|
||||||
this.s = s;
|
this.s = s;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -558,7 +558,7 @@ registerFilterClass(FilterPlainHnAnchored);
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterGeneric = function(s, anchor) {
|
const FilterGeneric = function(s, anchor) {
|
||||||
this.s = s;
|
this.s = s;
|
||||||
this.anchor = anchor;
|
this.anchor = anchor;
|
||||||
};
|
};
|
||||||
@ -603,7 +603,7 @@ registerFilterClass(FilterGeneric);
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterGenericHnAnchored = function(s) {
|
const FilterGenericHnAnchored = function(s) {
|
||||||
this.s = s;
|
this.s = s;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -642,7 +642,7 @@ registerFilterClass(FilterGenericHnAnchored);
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterGenericHnAndRightAnchored = function(s) {
|
const FilterGenericHnAndRightAnchored = function(s) {
|
||||||
FilterGenericHnAnchored.call(this, s);
|
FilterGenericHnAnchored.call(this, s);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -682,7 +682,7 @@ registerFilterClass(FilterGenericHnAndRightAnchored);
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterRegex = function(s) {
|
const FilterRegex = function(s) {
|
||||||
this.re = s;
|
this.re = s;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -723,7 +723,7 @@ registerFilterClass(FilterRegex);
|
|||||||
|
|
||||||
// Filtering according to the origin.
|
// Filtering according to the origin.
|
||||||
|
|
||||||
var FilterOrigin = function() {
|
const FilterOrigin = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterOrigin.prototype.wrapped = {
|
FilterOrigin.prototype.wrapped = {
|
||||||
@ -766,7 +766,7 @@ FilterOrigin.prototype.compile = function() {
|
|||||||
|
|
||||||
// *** start of specialized origin matchers
|
// *** start of specialized origin matchers
|
||||||
|
|
||||||
var FilterOriginHit = function(domainOpt) {
|
const FilterOriginHit = function(domainOpt) {
|
||||||
FilterOrigin.call(this);
|
FilterOrigin.call(this);
|
||||||
this.hostname = domainOpt;
|
this.hostname = domainOpt;
|
||||||
};
|
};
|
||||||
@ -792,7 +792,7 @@ FilterOriginHit.prototype = Object.create(FilterOrigin.prototype, {
|
|||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
var FilterOriginMiss = function(domainOpt) {
|
const FilterOriginMiss = function(domainOpt) {
|
||||||
FilterOrigin.call(this);
|
FilterOrigin.call(this);
|
||||||
this.hostname = domainOpt.slice(1);
|
this.hostname = domainOpt.slice(1);
|
||||||
};
|
};
|
||||||
@ -811,14 +811,15 @@ FilterOriginMiss.prototype = Object.create(FilterOrigin.prototype, {
|
|||||||
var needle = this.hostname, haystack = pageHostnameRegister;
|
var needle = this.hostname, haystack = pageHostnameRegister;
|
||||||
if ( haystack.endsWith(needle) === false ) { return true; }
|
if ( haystack.endsWith(needle) === false ) { return true; }
|
||||||
var offset = haystack.length - needle.length;
|
var offset = haystack.length - needle.length;
|
||||||
return offset !== 0 && haystack.charCodeAt(offset - 1) !== 0x2E /* '.' */;
|
return offset !== 0 &&
|
||||||
|
haystack.charCodeAt(offset - 1) !== 0x2E /* '.' */;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
var FilterOriginHitSet = function(domainOpt) {
|
const FilterOriginHitSet = function(domainOpt) {
|
||||||
FilterOrigin.call(this);
|
FilterOrigin.call(this);
|
||||||
this.domainOpt = domainOpt.length < 128
|
this.domainOpt = domainOpt.length < 128
|
||||||
? domainOpt
|
? domainOpt
|
||||||
@ -840,17 +841,17 @@ FilterOriginHitSet.prototype = Object.create(FilterOrigin.prototype, {
|
|||||||
},
|
},
|
||||||
matchOrigin: {
|
matchOrigin: {
|
||||||
value: function() {
|
value: function() {
|
||||||
if ( this.oneOf === null ) {
|
if ( hnTrieManager.isValidRef(this.oneOf) === false ) {
|
||||||
this.oneOf = HNTrieBuilder.fromDomainOpt(this.domainOpt);
|
this.oneOf = hnTrieManager.fromDomainOpt(this.domainOpt);
|
||||||
}
|
}
|
||||||
return this.oneOf.matches(pageHostnameRegister);
|
return this.oneOf.matches(pageHostnameRegister) === 1;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
var FilterOriginMissSet = function(domainOpt) {
|
const FilterOriginMissSet = function(domainOpt) {
|
||||||
FilterOrigin.call(this);
|
FilterOrigin.call(this);
|
||||||
this.domainOpt = domainOpt.length < 128
|
this.domainOpt = domainOpt.length < 128
|
||||||
? domainOpt
|
? domainOpt
|
||||||
@ -872,17 +873,19 @@ FilterOriginMissSet.prototype = Object.create(FilterOrigin.prototype, {
|
|||||||
},
|
},
|
||||||
matchOrigin: {
|
matchOrigin: {
|
||||||
value: function() {
|
value: function() {
|
||||||
if ( this.noneOf === null ) {
|
if ( hnTrieManager.isValidRef(this.noneOf) === false ) {
|
||||||
this.noneOf = HNTrieBuilder.fromDomainOpt(this.domainOpt.replace(/~/g, ''));
|
this.noneOf = hnTrieManager.fromDomainOpt(
|
||||||
|
this.domainOpt.replace(/~/g, '')
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return this.noneOf.matches(pageHostnameRegister) === false;
|
return this.noneOf.matches(pageHostnameRegister) === 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
var FilterOriginMixedSet = function(domainOpt) {
|
const FilterOriginMixedSet = function(domainOpt) {
|
||||||
FilterOrigin.call(this);
|
FilterOrigin.call(this);
|
||||||
this.domainOpt = domainOpt.length < 128
|
this.domainOpt = domainOpt.length < 128
|
||||||
? domainOpt
|
? domainOpt
|
||||||
@ -903,20 +906,16 @@ FilterOriginMixedSet.prototype = Object.create(FilterOrigin.prototype, {
|
|||||||
},
|
},
|
||||||
init: {
|
init: {
|
||||||
value: function() {
|
value: function() {
|
||||||
var oneOf = [], noneOf = [],
|
let oneOf = [], noneOf = [];
|
||||||
hostnames = this.domainOpt.split('|'),
|
for ( let hostname of this.domainOpt.split('|') ) {
|
||||||
i = hostnames.length,
|
|
||||||
hostname;
|
|
||||||
while ( i-- ) {
|
|
||||||
hostname = hostnames[i];
|
|
||||||
if ( hostname.charCodeAt(0) === 0x7E /* '~' */ ) {
|
if ( hostname.charCodeAt(0) === 0x7E /* '~' */ ) {
|
||||||
noneOf.push(hostname.slice(1));
|
noneOf.push(hostname.slice(1));
|
||||||
} else {
|
} else {
|
||||||
oneOf.push(hostname);
|
oneOf.push(hostname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.oneOf = HNTrieBuilder.fromIterable(oneOf);
|
this.oneOf = hnTrieManager.fromIterable(oneOf);
|
||||||
this.noneOf = HNTrieBuilder.fromIterable(noneOf);
|
this.noneOf = hnTrieManager.fromIterable(noneOf);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
toDomainOpt: {
|
toDomainOpt: {
|
||||||
@ -926,10 +925,12 @@ FilterOriginMixedSet.prototype = Object.create(FilterOrigin.prototype, {
|
|||||||
},
|
},
|
||||||
matchOrigin: {
|
matchOrigin: {
|
||||||
value: function() {
|
value: function() {
|
||||||
if ( this.oneOf === null ) { this.init(); }
|
if ( hnTrieManager.isValidRef(this.oneOf) === false ) {
|
||||||
var needle = pageHostnameRegister;
|
this.init();
|
||||||
return this.oneOf.matches(needle) &&
|
}
|
||||||
this.noneOf.matches(needle) === false;
|
let needle = pageHostnameRegister;
|
||||||
|
return this.oneOf.matches(needle) === 1 &&
|
||||||
|
this.noneOf.matches(needle) === 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -981,7 +982,7 @@ registerFilterClass(FilterOrigin);
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterDataHolder = function(dataType, dataStr) {
|
const FilterDataHolder = function(dataType, dataStr) {
|
||||||
this.dataType = dataType;
|
this.dataType = dataType;
|
||||||
this.dataStr = dataStr;
|
this.dataStr = dataStr;
|
||||||
this.wrapped = undefined;
|
this.wrapped = undefined;
|
||||||
@ -1024,7 +1025,7 @@ registerFilterClass(FilterDataHolder);
|
|||||||
|
|
||||||
// Helper class for storing instances of FilterDataHolder.
|
// Helper class for storing instances of FilterDataHolder.
|
||||||
|
|
||||||
var FilterDataHolderEntry = function(categoryBits, tokenHash, fdata) {
|
const FilterDataHolderEntry = function(categoryBits, tokenHash, fdata) {
|
||||||
this.categoryBits = categoryBits;
|
this.categoryBits = categoryBits;
|
||||||
this.tokenHash = tokenHash;
|
this.tokenHash = tokenHash;
|
||||||
this.filter = filterFromCompiledData(fdata);
|
this.filter = filterFromCompiledData(fdata);
|
||||||
@ -1047,7 +1048,7 @@ FilterDataHolderEntry.load = function(data) {
|
|||||||
|
|
||||||
// Dictionary of hostnames
|
// Dictionary of hostnames
|
||||||
//
|
//
|
||||||
var FilterHostnameDict = function() {
|
const FilterHostnameDict = function() {
|
||||||
this.h = ''; // short-lived register
|
this.h = ''; // short-lived register
|
||||||
this.dict = new Set();
|
this.dict = new Set();
|
||||||
};
|
};
|
||||||
@ -1138,7 +1139,7 @@ registerFilterClass(FilterHostnameDict);
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterPair = function(a, b) {
|
const FilterPair = function(a, b) {
|
||||||
this.f1 = a;
|
this.f1 = a;
|
||||||
this.f2 = b;
|
this.f2 = b;
|
||||||
this.f = null;
|
this.f = null;
|
||||||
@ -1217,7 +1218,7 @@ registerFilterClass(FilterPair);
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterBucket = function(a, b, c) {
|
const FilterBucket = function(a, b, c) {
|
||||||
this.filters = [];
|
this.filters = [];
|
||||||
this.f = null;
|
this.f = null;
|
||||||
if ( a !== undefined ) {
|
if ( a !== undefined ) {
|
||||||
@ -1315,7 +1316,7 @@ registerFilterClass(FilterBucket);
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterParser = function() {
|
const FilterParser = function() {
|
||||||
this.cantWebsocket = vAPI.cantWebsocket;
|
this.cantWebsocket = vAPI.cantWebsocket;
|
||||||
this.reBadDomainOptChars = /[*+?^${}()[\]\\]/;
|
this.reBadDomainOptChars = /[*+?^${}()[\]\\]/;
|
||||||
this.reHostnameRule1 = /^[0-9a-z][0-9a-z.-]*[0-9a-z]$/i;
|
this.reHostnameRule1 = /^[0-9a-z][0-9a-z.-]*[0-9a-z]$/i;
|
||||||
@ -1933,7 +1934,7 @@ FilterParser.prototype.makeToken = function() {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var FilterContainer = function() {
|
const FilterContainer = function() {
|
||||||
this.reIsGeneric = /[\^\*]/;
|
this.reIsGeneric = /[\^\*]/;
|
||||||
this.filterParser = new FilterParser();
|
this.filterParser = new FilterParser();
|
||||||
this.urlTokenizer = µb.urlTokenizer;
|
this.urlTokenizer = µb.urlTokenizer;
|
||||||
@ -1960,6 +1961,9 @@ FilterContainer.prototype.reset = function() {
|
|||||||
this.dataFilters = new Map();
|
this.dataFilters = new Map();
|
||||||
this.filterParser.reset();
|
this.filterParser.reset();
|
||||||
|
|
||||||
|
// This will invalidate all hn tries throughout uBO:
|
||||||
|
hnTrieManager.reset();
|
||||||
|
|
||||||
// Runtime registers
|
// Runtime registers
|
||||||
this.cbRegister = undefined;
|
this.cbRegister = undefined;
|
||||||
this.thRegister = undefined;
|
this.thRegister = undefined;
|
||||||
@ -2052,6 +2056,15 @@ FilterContainer.prototype.freeze = function() {
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
// This is necessary for when the filtering engine readiness will depend
|
||||||
|
// on asynchronous operations (ex.: when loading a wasm module).
|
||||||
|
|
||||||
|
FilterContainer.prototype.readyToUse = function() {
|
||||||
|
return hnTrieManager.readyToUse();
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
FilterContainer.prototype.toSelfie = function() {
|
FilterContainer.prototype.toSelfie = function() {
|
||||||
let categoriesToSelfie = function(categoryMap) {
|
let categoriesToSelfie = function(categoryMap) {
|
||||||
let selfie = [];
|
let selfie = [];
|
||||||
@ -2250,7 +2263,7 @@ FilterContainer.prototype.compileToAtomicFilter = function(
|
|||||||
|
|
||||||
// Only static filter with an explicit type can be redirected. If we reach
|
// Only static filter with an explicit type can be redirected. If we reach
|
||||||
// this point, it's because there is one or more explicit type.
|
// this point, it's because there is one or more explicit type.
|
||||||
if ( parsed.badFilter === false && parsed.redirect ) {
|
if ( parsed.redirect ) {
|
||||||
let redirects = µb.redirectEngine.compileRuleFromStaticFilter(parsed.raw);
|
let redirects = µb.redirectEngine.compileRuleFromStaticFilter(parsed.raw);
|
||||||
if ( Array.isArray(redirects) ) {
|
if ( Array.isArray(redirects) ) {
|
||||||
for ( let redirect of redirects ) {
|
for ( let redirect of redirects ) {
|
||||||
@ -2292,26 +2305,24 @@ FilterContainer.prototype.fromCompiledContent = function(reader) {
|
|||||||
FilterContainer.prototype.matchAndFetchData = function(dataType, requestURL, out, outlog) {
|
FilterContainer.prototype.matchAndFetchData = function(dataType, requestURL, out, outlog) {
|
||||||
if ( this.dataFilters.length === 0 ) { return; }
|
if ( this.dataFilters.length === 0 ) { return; }
|
||||||
|
|
||||||
var url = this.urlTokenizer.setURL(requestURL);
|
let url = this.urlTokenizer.setURL(requestURL);
|
||||||
|
|
||||||
requestHostnameRegister = µb.URI.hostnameFromURI(url);
|
pageHostnameRegister = requestHostnameRegister = µb.URI.hostnameFromURI(url);
|
||||||
|
|
||||||
// We need to visit ALL the matching filters.
|
// We need to visit ALL the matching filters.
|
||||||
var toAddImportant = new Map(),
|
let toAddImportant = new Map(),
|
||||||
toAdd = new Map(),
|
toAdd = new Map(),
|
||||||
toRemove = new Map();
|
toRemove = new Map();
|
||||||
|
|
||||||
var entry, f,
|
let tokenHashes = this.urlTokenizer.getTokens(),
|
||||||
tokenHashes = this.urlTokenizer.getTokens(),
|
|
||||||
tokenHash, tokenOffset,
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while ( i < 32 ) {
|
while ( i < 32 ) {
|
||||||
tokenHash = tokenHashes[i++];
|
let tokenHash = tokenHashes[i++];
|
||||||
if ( tokenHash === 0 ) { break; }
|
if ( tokenHash === 0 ) { break; }
|
||||||
tokenOffset = tokenHashes[i++];
|
let tokenOffset = tokenHashes[i++];
|
||||||
entry = this.dataFilters.get(tokenHash);
|
let entry = this.dataFilters.get(tokenHash);
|
||||||
while ( entry !== undefined ) {
|
while ( entry !== undefined ) {
|
||||||
f = entry.filter;
|
let f = entry.filter;
|
||||||
if ( f.match(url, tokenOffset) === true ) {
|
if ( f.match(url, tokenOffset) === true ) {
|
||||||
if ( entry.categoryBits & 0x001 ) {
|
if ( entry.categoryBits & 0x001 ) {
|
||||||
toRemove.set(f.dataStr, entry);
|
toRemove.set(f.dataStr, entry);
|
||||||
@ -2324,9 +2335,9 @@ FilterContainer.prototype.matchAndFetchData = function(dataType, requestURL, out
|
|||||||
entry = entry.next;
|
entry = entry.next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
entry = this.dataFilters.get(this.noTokenHash);
|
let entry = this.dataFilters.get(this.noTokenHash);
|
||||||
while ( entry !== undefined ) {
|
while ( entry !== undefined ) {
|
||||||
f = entry.filter;
|
let f = entry.filter;
|
||||||
if ( f.match(url) === true ) {
|
if ( f.match(url) === true ) {
|
||||||
if ( entry.categoryBits & 0x001 ) {
|
if ( entry.categoryBits & 0x001 ) {
|
||||||
toRemove.set(f.dataStr, entry);
|
toRemove.set(f.dataStr, entry);
|
||||||
@ -2342,12 +2353,11 @@ FilterContainer.prototype.matchAndFetchData = function(dataType, requestURL, out
|
|||||||
if ( toAddImportant.size === 0 && toAdd.size === 0 ) { return; }
|
if ( toAddImportant.size === 0 && toAdd.size === 0 ) { return; }
|
||||||
|
|
||||||
// Remove entries overriden by other filters.
|
// Remove entries overriden by other filters.
|
||||||
var key;
|
for ( let key of toAddImportant.keys() ) {
|
||||||
for ( key of toAddImportant.keys() ) {
|
|
||||||
toAdd.delete(key);
|
toAdd.delete(key);
|
||||||
toRemove.delete(key);
|
toRemove.delete(key);
|
||||||
}
|
}
|
||||||
for ( key of toRemove.keys() ) {
|
for ( let key of toRemove.keys() ) {
|
||||||
if ( key === '' ) {
|
if ( key === '' ) {
|
||||||
toAdd.clear();
|
toAdd.clear();
|
||||||
break;
|
break;
|
||||||
@ -2355,26 +2365,25 @@ FilterContainer.prototype.matchAndFetchData = function(dataType, requestURL, out
|
|||||||
toAdd.delete(key);
|
toAdd.delete(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
var logData;
|
for ( let entry of toAddImportant ) {
|
||||||
for ( entry of toAddImportant ) {
|
|
||||||
out.push(entry[0]);
|
out.push(entry[0]);
|
||||||
if ( outlog === undefined ) { continue; }
|
if ( outlog === undefined ) { continue; }
|
||||||
logData = entry[1].logData();
|
let logData = entry[1].logData();
|
||||||
logData.source = 'static';
|
logData.source = 'static';
|
||||||
logData.result = 1;
|
logData.result = 1;
|
||||||
outlog.push(logData);
|
outlog.push(logData);
|
||||||
}
|
}
|
||||||
for ( entry of toAdd ) {
|
for ( let entry of toAdd ) {
|
||||||
out.push(entry[0]);
|
out.push(entry[0]);
|
||||||
if ( outlog === undefined ) { continue; }
|
if ( outlog === undefined ) { continue; }
|
||||||
logData = entry[1].logData();
|
let logData = entry[1].logData();
|
||||||
logData.source = 'static';
|
logData.source = 'static';
|
||||||
logData.result = 1;
|
logData.result = 1;
|
||||||
outlog.push(logData);
|
outlog.push(logData);
|
||||||
}
|
}
|
||||||
if ( outlog !== undefined ) {
|
if ( outlog !== undefined ) {
|
||||||
for ( entry of toRemove.values()) {
|
for ( let entry of toRemove.values()) {
|
||||||
logData = entry.logData();
|
let logData = entry.logData();
|
||||||
logData.source = 'static';
|
logData.source = 'static';
|
||||||
logData.result = 2;
|
logData.result = 2;
|
||||||
outlog.push(logData);
|
outlog.push(logData);
|
||||||
@ -2389,20 +2398,19 @@ FilterContainer.prototype.matchAndFetchData = function(dataType, requestURL, out
|
|||||||
|
|
||||||
FilterContainer.prototype.matchTokens = function(bucket, url) {
|
FilterContainer.prototype.matchTokens = function(bucket, url) {
|
||||||
// Hostname-only filters
|
// Hostname-only filters
|
||||||
var f = bucket.get(this.dotTokenHash);
|
let f = bucket.get(this.dotTokenHash);
|
||||||
if ( f !== undefined && f.match() === true ) {
|
if ( f !== undefined && f.match() === true ) {
|
||||||
this.thRegister = this.dotTokenHash;
|
this.thRegister = this.dotTokenHash;
|
||||||
this.fRegister = f;
|
this.fRegister = f;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tokenHashes = this.urlTokenizer.getTokens(),
|
let tokenHashes = this.urlTokenizer.getTokens(),
|
||||||
tokenHash, tokenOffset,
|
|
||||||
i = 0;
|
i = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
tokenHash = tokenHashes[i++];
|
let tokenHash = tokenHashes[i++];
|
||||||
if ( tokenHash === 0 ) { break; }
|
if ( tokenHash === 0 ) { break; }
|
||||||
tokenOffset = tokenHashes[i++];
|
let tokenOffset = tokenHashes[i++];
|
||||||
f = bucket.get(tokenHash);
|
f = bucket.get(tokenHash);
|
||||||
if ( f !== undefined && f.match(url, tokenOffset) === true ) {
|
if ( f !== undefined && f.match(url, tokenOffset) === true ) {
|
||||||
this.thRegister = tokenHash;
|
this.thRegister = tokenHash;
|
||||||
@ -2437,8 +2445,10 @@ FilterContainer.prototype.matchStringGenericHide = function(requestURL) {
|
|||||||
let url = this.urlTokenizer.setURL(requestURL);
|
let url = this.urlTokenizer.setURL(requestURL);
|
||||||
|
|
||||||
// https://github.com/gorhill/uBlock/issues/2225
|
// https://github.com/gorhill/uBlock/issues/2225
|
||||||
// Important: this is used by FilterHostnameDict.match().
|
// Important:
|
||||||
requestHostnameRegister = µb.URI.hostnameFromURI(url);
|
// - `pageHostnameRegister` is used by FilterOrigin.matchOrigin().
|
||||||
|
// - `requestHostnameRegister` is used by FilterHostnameDict.match().
|
||||||
|
pageHostnameRegister = requestHostnameRegister = µb.URI.hostnameFromURI(url);
|
||||||
|
|
||||||
let bucket = this.categories.get(genericHideException);
|
let bucket = this.categories.get(genericHideException);
|
||||||
if ( !bucket || this.matchTokens(bucket, url) === false ) {
|
if ( !bucket || this.matchTokens(bucket, url) === false ) {
|
||||||
@ -2548,7 +2558,7 @@ FilterContainer.prototype.matchString = function(context) {
|
|||||||
// https://github.com/chrisaljoudi/uBlock/issues/519
|
// https://github.com/chrisaljoudi/uBlock/issues/519
|
||||||
// Use exact type match for anything beyond `other`
|
// Use exact type match for anything beyond `other`
|
||||||
// Also, be prepared to support unknown types
|
// Also, be prepared to support unknown types
|
||||||
var type = typeNameToTypeValue[context.requestType];
|
let type = typeNameToTypeValue[context.requestType];
|
||||||
if ( type === undefined ) {
|
if ( type === undefined ) {
|
||||||
type = otherTypeBitValue;
|
type = otherTypeBitValue;
|
||||||
} else if ( type === 0 || type > otherTypeBitValue ) {
|
} else if ( type === 0 || type > otherTypeBitValue ) {
|
||||||
@ -2577,7 +2587,7 @@ FilterContainer.prototype.matchString = function(context) {
|
|||||||
// filter.
|
// filter.
|
||||||
|
|
||||||
// Prime tokenizer: we get a normalized URL in return.
|
// Prime tokenizer: we get a normalized URL in return.
|
||||||
var url = this.urlTokenizer.setURL(context.requestURL);
|
let url = this.urlTokenizer.setURL(context.requestURL);
|
||||||
|
|
||||||
// These registers will be used by various filters
|
// These registers will be used by various filters
|
||||||
pageHostnameRegister = context.pageHostname || '';
|
pageHostnameRegister = context.pageHostname || '';
|
||||||
@ -2585,10 +2595,10 @@ FilterContainer.prototype.matchString = function(context) {
|
|||||||
|
|
||||||
this.fRegister = null;
|
this.fRegister = null;
|
||||||
|
|
||||||
var party = isFirstParty(context.pageDomain, context.requestHostname)
|
let party = isFirstParty(context.pageDomain, context.requestHostname)
|
||||||
? FirstParty
|
? FirstParty
|
||||||
: ThirdParty;
|
: ThirdParty;
|
||||||
var categories = this.categories,
|
let categories = this.categories,
|
||||||
catBits, bucket;
|
catBits, bucket;
|
||||||
|
|
||||||
// https://github.com/chrisaljoudi/uBlock/issues/139
|
// https://github.com/chrisaljoudi/uBlock/issues/139
|
||||||
|
@ -604,9 +604,7 @@
|
|||||||
|
|
||||||
µBlock.loadFilterLists = function(callback) {
|
µBlock.loadFilterLists = function(callback) {
|
||||||
// Callers are expected to check this first.
|
// Callers are expected to check this first.
|
||||||
if ( this.loadingFilterLists ) {
|
if ( this.loadingFilterLists ) { return; }
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.loadingFilterLists = true;
|
this.loadingFilterLists = true;
|
||||||
|
|
||||||
var µb = this,
|
var µb = this,
|
||||||
@ -961,38 +959,31 @@
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
µBlock.loadPublicSuffixList = function(callback) {
|
µBlock.loadPublicSuffixList = function() {
|
||||||
var µb = this,
|
return new Promise(resolve => {
|
||||||
assetKey = µb.pslAssetKey,
|
// start of executor
|
||||||
compiledAssetKey = 'compiled/' + assetKey;
|
this.assets.get('compiled/' + this.pslAssetKey, details => {
|
||||||
|
let selfie;
|
||||||
if ( typeof callback !== 'function' ) {
|
|
||||||
callback = this.noopFunc;
|
|
||||||
}
|
|
||||||
var onRawListLoaded = function(details) {
|
|
||||||
if ( details.content !== '' ) {
|
|
||||||
µb.compilePublicSuffixList(details.content);
|
|
||||||
}
|
|
||||||
callback();
|
|
||||||
};
|
|
||||||
|
|
||||||
var onCompiledListLoaded = function(details) {
|
|
||||||
var selfie;
|
|
||||||
try {
|
try {
|
||||||
selfie = JSON.parse(details.content);
|
selfie = JSON.parse(details.content);
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
selfie === undefined ||
|
selfie instanceof Object &&
|
||||||
publicSuffixList.fromSelfie(selfie) === false
|
publicSuffixList.fromSelfie(selfie)
|
||||||
) {
|
) {
|
||||||
µb.assets.get(assetKey, onRawListLoaded);
|
resolve();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
callback();
|
this.assets.get(this.pslAssetKey, details => {
|
||||||
};
|
if ( details.content !== '' ) {
|
||||||
|
this.compilePublicSuffixList(details.content);
|
||||||
this.assets.get(compiledAssetKey, onCompiledListLoaded);
|
}
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// end of executor
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
24
src/js/wasm/README.md
Normal file
24
src/js/wasm/README.md
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
### For code reviewers
|
||||||
|
|
||||||
|
All `wasm` files in that directory where created by compiling the
|
||||||
|
corresponding `wat` file using the command (using `hntrie.wat`/`hntrie.wasm`
|
||||||
|
as example):
|
||||||
|
|
||||||
|
wat2wasm hntrie.wat -o hntrie.wasm
|
||||||
|
|
||||||
|
Assuming:
|
||||||
|
|
||||||
|
- The command is executed from within the present directory.
|
||||||
|
|
||||||
|
### `wat2wasm` tool
|
||||||
|
|
||||||
|
The `wat2wasm` tool can be downloaded from an official WebAssembly project:
|
||||||
|
<https://github.com/WebAssembly/wabt/releases>.
|
||||||
|
|
||||||
|
### `wat2wasm` tool online
|
||||||
|
|
||||||
|
You can also use the following online `wat2wasm` tool:
|
||||||
|
<https://webassembly.github.io/wabt/demo/wat2wasm/>.
|
||||||
|
|
||||||
|
Just paste the whole content of the `wat` file to compile into the WAT pane.
|
||||||
|
Click "Download" button to retrieve the resulting `wasm` file.
|
BIN
src/js/wasm/hntrie.wasm
Normal file
BIN
src/js/wasm/hntrie.wasm
Normal file
Binary file not shown.
200
src/js/wasm/hntrie.wat
Normal file
200
src/js/wasm/hntrie.wat
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
;;
|
||||||
|
;; uBlock Origin - a browser extension to block requests.
|
||||||
|
;; Copyright (C) 2018-present 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
|
||||||
|
;; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
;; (at your option) any later version.
|
||||||
|
;;
|
||||||
|
;; This program is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
;;
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||||
|
;;
|
||||||
|
;; Home: https://github.com/gorhill/uBlock
|
||||||
|
;; File: hntrie.wat
|
||||||
|
;; Description: WebAssembly code used by src/js/hntrie.js
|
||||||
|
;; How to compile: See README.md in this directory.
|
||||||
|
|
||||||
|
(module
|
||||||
|
;;
|
||||||
|
;; module start
|
||||||
|
;;
|
||||||
|
|
||||||
|
;; (func $log (import "imports" "log") (param i32 i32 i32))
|
||||||
|
|
||||||
|
(memory (import "imports" "memory") 1)
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Public functions
|
||||||
|
;;
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; unsigned int matches(offset)
|
||||||
|
;;
|
||||||
|
;; Test whether the currently set needle matches the trie at specified offset.
|
||||||
|
;;
|
||||||
|
;; Memory layout, byte offset:
|
||||||
|
;; 0-254: encoded needle (ASCII)
|
||||||
|
;; 255 : needle length
|
||||||
|
;; 256- : tries
|
||||||
|
;;
|
||||||
|
(func (export "matches")
|
||||||
|
(param $itrie i32)
|
||||||
|
(result i32) ;; result: 0 = miss, 1 = hit
|
||||||
|
(local $ineedle i32) ;; current needle offset
|
||||||
|
(local $nchar i32) ;; needle char being processed
|
||||||
|
(local $tchar i32) ;; trie char being processed
|
||||||
|
(local $lxtra i32)
|
||||||
|
(local $ixtra i32)
|
||||||
|
i32.const 255
|
||||||
|
i32.load8_u
|
||||||
|
set_local $ineedle
|
||||||
|
loop $nextNeedleChar
|
||||||
|
;; ineedle -= 1;
|
||||||
|
get_local $ineedle
|
||||||
|
i32.const -1
|
||||||
|
i32.add
|
||||||
|
tee_local $ineedle
|
||||||
|
;; let nchar = ineedle === -1 ? 0 : buf[ineedle];
|
||||||
|
i32.const 0
|
||||||
|
i32.lt_s
|
||||||
|
if
|
||||||
|
i32.const 0
|
||||||
|
set_local $nchar
|
||||||
|
else
|
||||||
|
get_local $ineedle
|
||||||
|
i32.load8_u
|
||||||
|
set_local $nchar
|
||||||
|
end
|
||||||
|
block $trieCharEqNeedleChar loop $nextTrieChar
|
||||||
|
;; let tchar = buf[itrie+8];
|
||||||
|
get_local $itrie
|
||||||
|
i32.load8_u offset=8
|
||||||
|
tee_local $tchar
|
||||||
|
;; if ( tchar === nchar ) { break; }
|
||||||
|
get_local $nchar
|
||||||
|
i32.eq
|
||||||
|
br_if $trieCharEqNeedleChar
|
||||||
|
;; if ( tchar === 0 && nchar === 0x2E ) { return 1; }
|
||||||
|
get_local $tchar
|
||||||
|
i32.eqz
|
||||||
|
if
|
||||||
|
get_local $nchar
|
||||||
|
i32.const 0x2E
|
||||||
|
i32.eq
|
||||||
|
if
|
||||||
|
i32.const 1
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
;; itrie = buf32[itrie >>> 2];
|
||||||
|
get_local $itrie
|
||||||
|
i32.load
|
||||||
|
tee_local $itrie
|
||||||
|
;; if ( itrie === 0 ) { return 0; }
|
||||||
|
i32.eqz
|
||||||
|
if
|
||||||
|
i32.const 0
|
||||||
|
return
|
||||||
|
end
|
||||||
|
br $nextTrieChar
|
||||||
|
end end
|
||||||
|
;; if ( nchar === 0 ) { return 1; }
|
||||||
|
get_local $nchar
|
||||||
|
i32.eqz
|
||||||
|
if
|
||||||
|
i32.const 1
|
||||||
|
return
|
||||||
|
end
|
||||||
|
;; let lxtra = buf[itrie+9];
|
||||||
|
get_local $itrie
|
||||||
|
i32.load8_u offset=9
|
||||||
|
tee_local $lxtra
|
||||||
|
i32.eqz
|
||||||
|
if else
|
||||||
|
;; if ( lxtra > ineedle ) { return 0; }
|
||||||
|
get_local $lxtra
|
||||||
|
get_local $ineedle
|
||||||
|
i32.gt_u
|
||||||
|
if
|
||||||
|
i32.const 0
|
||||||
|
return
|
||||||
|
end
|
||||||
|
;; let ixtra = itrie + 10;
|
||||||
|
get_local $itrie
|
||||||
|
i32.const 10
|
||||||
|
i32.add
|
||||||
|
tee_local $ixtra
|
||||||
|
;; lxtra += ixtra;
|
||||||
|
get_local $lxtra
|
||||||
|
i32.add
|
||||||
|
set_local $lxtra
|
||||||
|
;; do {
|
||||||
|
block $noMoreExtraChars loop
|
||||||
|
;; ineedle -= 1;
|
||||||
|
get_local $ineedle
|
||||||
|
i32.const -1
|
||||||
|
i32.add
|
||||||
|
tee_local $ineedle
|
||||||
|
;; if ( buf[ineedle] !== buf[ixtra] ) { return 0; }
|
||||||
|
i32.load8_u
|
||||||
|
get_local $ixtra
|
||||||
|
i32.load8_u
|
||||||
|
i32.ne
|
||||||
|
if
|
||||||
|
i32.const 0
|
||||||
|
return
|
||||||
|
end
|
||||||
|
;; ixtra += 1;
|
||||||
|
get_local $ixtra
|
||||||
|
i32.const 1
|
||||||
|
i32.add
|
||||||
|
tee_local $ixtra
|
||||||
|
;; while ( ixtra !== lxtra ) {
|
||||||
|
get_local $lxtra
|
||||||
|
i32.eq
|
||||||
|
br_if $noMoreExtraChars
|
||||||
|
br 0
|
||||||
|
end end
|
||||||
|
end
|
||||||
|
;; itrie = buf32[itrie + 4 >>> 2];
|
||||||
|
get_local $itrie
|
||||||
|
i32.load offset=4
|
||||||
|
tee_local $itrie
|
||||||
|
;; if ( itrie === 0 ) {
|
||||||
|
i32.eqz
|
||||||
|
if
|
||||||
|
;; return ineedle === 0 || buf[ineedle-1] === 0x2E ? 1 : 0;
|
||||||
|
get_local $ineedle
|
||||||
|
i32.eqz
|
||||||
|
if
|
||||||
|
i32.const 1
|
||||||
|
return
|
||||||
|
end
|
||||||
|
get_local $ineedle
|
||||||
|
i32.const -1
|
||||||
|
i32.add
|
||||||
|
i32.load8_u
|
||||||
|
i32.const 0x2E
|
||||||
|
i32.eq
|
||||||
|
if
|
||||||
|
i32.const 1
|
||||||
|
return
|
||||||
|
end
|
||||||
|
i32.const 0
|
||||||
|
return
|
||||||
|
end
|
||||||
|
br 0
|
||||||
|
end
|
||||||
|
i32.const 0
|
||||||
|
)
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; module end
|
||||||
|
;;
|
||||||
|
)
|
479
test/hnset-benchmark.html
Normal file
479
test/hnset-benchmark.html
Normal file
File diff suppressed because one or more lines are too long
45866
test/hntrie-test.html
Normal file
45866
test/hntrie-test.html
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user