mirror of https://github.com/gorhill/uBlock.git
Add ability for scriptlets to share local data
Related issue: - https://github.com/uBlockOrigin/uBlock-issues/issues/1741 As a result of the new capability, usage of RegExp API in `aost` scriptlet has been shielded from the webpage tampering with the API.
This commit is contained in:
parent
c7c748862e
commit
5c9c87e485
|
@ -22,6 +22,9 @@
|
|||
web page context.
|
||||
*/
|
||||
|
||||
// Externally added to the private namespace in which scriptlets execute.
|
||||
/* global sriptletGlobals */
|
||||
|
||||
'use strict';
|
||||
|
||||
export const builtinScriptlets = [];
|
||||
|
@ -34,6 +37,25 @@ export const builtinScriptlets = [];
|
|||
|
||||
*******************************************************************************/
|
||||
|
||||
builtinScriptlets.push({
|
||||
name: 'safe-self.fn',
|
||||
fn: safeSelf,
|
||||
});
|
||||
function safeSelf() {
|
||||
if ( sriptletGlobals.has('safeSelf') ) {
|
||||
return sriptletGlobals.get('safeSelf');
|
||||
}
|
||||
const safe = {
|
||||
'RegExp': self.RegExp,
|
||||
'RegExp_test': self.RegExp.prototype.test,
|
||||
'RegExp_exec': self.RegExp.prototype.exec,
|
||||
};
|
||||
sriptletGlobals.set('safeSelf', safe);
|
||||
return safe;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
builtinScriptlets.push({
|
||||
name: 'pattern-to-regex.fn',
|
||||
fn: patternToRegex,
|
||||
|
@ -257,6 +279,7 @@ builtinScriptlets.push({
|
|||
aliases: [ 'aost.js' ],
|
||||
fn: abortOnStackTrace,
|
||||
dependencies: [
|
||||
'safe-self.fn',
|
||||
'pattern-to-regex.fn',
|
||||
'get-exception-token.fn',
|
||||
],
|
||||
|
@ -268,6 +291,7 @@ function abortOnStackTrace(
|
|||
logLevel = ''
|
||||
) {
|
||||
if ( typeof chain !== 'string' ) { return; }
|
||||
const safe = safeSelf();
|
||||
const reNeedle = patternToRegex(needle);
|
||||
const exceptionToken = getExceptionToken();
|
||||
const log = console.log.bind(console);
|
||||
|
@ -279,11 +303,12 @@ function abortOnStackTrace(
|
|||
docURL = docURL.slice(0, pos);
|
||||
}
|
||||
// Normalize stack trace
|
||||
const reLine = /(.*?@)?(\S+)(:\d+):\d+\)?$/;
|
||||
const lines = [];
|
||||
for ( let line of err.stack.split(/[\n\r]+/) ) {
|
||||
if ( line.includes(exceptionToken) ) { continue; }
|
||||
line = line.trim();
|
||||
let match = /(.*?@)?(\S+)(:\d+):\d+\)?$/.exec(line);
|
||||
let match = safe.RegExp_exec.call(reLine, line);
|
||||
if ( match === null ) { continue; }
|
||||
let url = match[2];
|
||||
if ( url.startsWith('(') ) { url = url.slice(1); }
|
||||
|
@ -301,7 +326,7 @@ function abortOnStackTrace(
|
|||
}
|
||||
lines[0] = `stackDepth:${lines.length-1}`;
|
||||
const stack = lines.join('\t');
|
||||
const r = reNeedle.test(stack);
|
||||
const r = safe.RegExp_test.call(reNeedle, stack);
|
||||
if (
|
||||
logLevel === '1' ||
|
||||
logLevel === '2' && r ||
|
||||
|
|
|
@ -379,22 +379,20 @@ scriptletFilteringEngine.retrieve = function(request, options = {}) {
|
|||
|
||||
if ( cacheDetails.code === '' ) { return; }
|
||||
|
||||
const out = [ cacheDetails.code ];
|
||||
|
||||
if ( µb.hiddenSettings.debugScriptlets ) {
|
||||
out.unshift('debugger;');
|
||||
}
|
||||
|
||||
out.unshift(
|
||||
const out = [
|
||||
'(function() {',
|
||||
'// >>>> start of private namespace',
|
||||
''
|
||||
);
|
||||
out.push(
|
||||
'',
|
||||
µb.hiddenSettings.debugScriptlets ? 'debugger;' : ';',
|
||||
'',
|
||||
// For use by scriptlets to share local data among themselves
|
||||
'const sriptletGlobals = new Map();',
|
||||
'',
|
||||
cacheDetails.code,
|
||||
'',
|
||||
'// <<<< end of private namespace',
|
||||
'})();'
|
||||
);
|
||||
'})();',
|
||||
];
|
||||
|
||||
return out.join('\n');
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue