mirror of
https://github.com/gorhill/uBlock.git
synced 2024-07-08 04:49:12 +02:00
Improve trusted-prune-inbound-object
scriptlet
Trap incoming argument only if it matches the properties to prune and matches. If there is no match, the inbound object is passed through untouched.
This commit is contained in:
parent
9829ee12a5
commit
fc40393c81
@ -630,6 +630,7 @@ builtinScriptlets.push({
|
||||
fn: objectPruneFn,
|
||||
dependencies: [
|
||||
'matches-stack-trace.fn',
|
||||
'object-find-owner.fn',
|
||||
'safe-self.fn',
|
||||
'should-log.fn',
|
||||
],
|
||||
@ -662,8 +663,50 @@ function objectPruneFn(
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ( objectPruneFn.findOwner === undefined ) {
|
||||
objectPruneFn.findOwner = (root, path, prune = false) => {
|
||||
if ( objectPruneFn.mustProcess === undefined ) {
|
||||
objectPruneFn.mustProcess = (root, needlePaths) => {
|
||||
for ( const needlePath of needlePaths ) {
|
||||
if ( objectFindOwnerFn(root, needlePath) === false ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
objectPruneFn.logJson = (json, msg, reNeedle) => {
|
||||
if ( reNeedle.test(json) === false ) { return; }
|
||||
safeSelf().uboLog(`objectPrune()`, msg, location.hostname, json);
|
||||
};
|
||||
}
|
||||
const jsonBefore = logLevel ? safe.JSON_stringify(obj, null, 2) : '';
|
||||
if ( logLevel === true || logLevel === 'all' ) {
|
||||
objectPruneFn.logJson(jsonBefore, `prune:"${rawPrunePaths}" log:"${logLevel}"`, reLogNeedle);
|
||||
}
|
||||
if ( prunePaths.length === 0 ) { return; }
|
||||
let outcome = 'nomatch';
|
||||
if ( objectPruneFn.mustProcess(obj, needlePaths) ) {
|
||||
for ( const path of prunePaths ) {
|
||||
if ( objectFindOwnerFn(obj, path, true) ) {
|
||||
outcome = 'match';
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( logLevel === outcome ) {
|
||||
objectPruneFn.logJson(jsonBefore, `prune:"${rawPrunePaths}" log:"${logLevel}"`, reLogNeedle);
|
||||
}
|
||||
if ( outcome === 'match' ) { return obj; }
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
builtinScriptlets.push({
|
||||
name: 'object-find-owner.fn',
|
||||
fn: objectFindOwnerFn,
|
||||
});
|
||||
function objectFindOwnerFn(
|
||||
root,
|
||||
path,
|
||||
prune = false
|
||||
) {
|
||||
let owner = root;
|
||||
let chain = path;
|
||||
for (;;) {
|
||||
@ -694,7 +737,7 @@ function objectPruneFn(
|
||||
const next = chain.slice(pos + 1);
|
||||
let found = false;
|
||||
for ( const key of Object.keys(owner) ) {
|
||||
found = objectPruneFn.findOwner(owner[key], next, prune) || found;
|
||||
found = objectFindOwnerFn(owner[key], next, prune) || found;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
@ -702,37 +745,7 @@ function objectPruneFn(
|
||||
owner = owner[prop];
|
||||
chain = chain.slice(pos + 1);
|
||||
}
|
||||
};
|
||||
objectPruneFn.mustProcess = (root, needlePaths) => {
|
||||
for ( const needlePath of needlePaths ) {
|
||||
if ( objectPruneFn.findOwner(root, needlePath) === false ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
objectPruneFn.logJson = (json, msg, reNeedle) => {
|
||||
if ( reNeedle.test(json) === false ) { return; }
|
||||
safeSelf().uboLog(`objectPrune()`, msg, location.hostname, json);
|
||||
};
|
||||
}
|
||||
const jsonBefore = logLevel ? safe.JSON_stringify(obj, null, 2) : '';
|
||||
if ( logLevel === true || logLevel === 'all' ) {
|
||||
objectPruneFn.logJson(jsonBefore, `prune:"${rawPrunePaths}" log:"${logLevel}"`, reLogNeedle);
|
||||
}
|
||||
if ( prunePaths.length === 0 ) { return; }
|
||||
let outcome = 'nomatch';
|
||||
if ( objectPruneFn.mustProcess(obj, needlePaths) ) {
|
||||
for ( const path of prunePaths ) {
|
||||
if ( objectPruneFn.findOwner(obj, path, true) ) {
|
||||
outcome = 'match';
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( logLevel === outcome ) {
|
||||
objectPruneFn.logJson(jsonBefore, `prune:"${rawPrunePaths}" log:"${logLevel}"`, reLogNeedle);
|
||||
}
|
||||
if ( outcome === 'match' ) { return obj; }
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
@ -4055,6 +4068,7 @@ builtinScriptlets.push({
|
||||
requiresTrust: true,
|
||||
fn: trustedPruneInboundObject,
|
||||
dependencies: [
|
||||
'object-find-owner.fn',
|
||||
'object-prune.fn',
|
||||
'safe-self.fn',
|
||||
],
|
||||
@ -4081,15 +4095,36 @@ function trustedPruneInboundObject(
|
||||
if ( argIndex < 1 ) { return; }
|
||||
const safe = safeSelf();
|
||||
const extraArgs = safe.getExtraArgs(Array.from(arguments), 4);
|
||||
const needlePaths = [];
|
||||
if ( rawPrunePaths !== '' ) {
|
||||
needlePaths.push(...rawPrunePaths.split(/ +/));
|
||||
}
|
||||
if ( rawNeedlePaths !== '' ) {
|
||||
needlePaths.push(...rawNeedlePaths.split(/ +/));
|
||||
}
|
||||
const mustProcess = root => {
|
||||
for ( const needlePath of needlePaths ) {
|
||||
if ( objectFindOwnerFn(root, needlePath) === false ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
context[prop] = new Proxy(context[prop], {
|
||||
apply: function(target, thisArg, args) {
|
||||
const targetArg = argIndex <= args.length
|
||||
? args[argIndex-1]
|
||||
: undefined;
|
||||
if ( targetArg instanceof Object ) {
|
||||
const objBefore = extraArgs.dontOverwrite
|
||||
? safe.JSON_parse(safe.JSON_stringify(targetArg))
|
||||
: targetArg;
|
||||
if ( targetArg instanceof Object && mustProcess(targetArg) ) {
|
||||
let objBefore = targetArg;
|
||||
if ( extraArgs.dontOverwrite ) {
|
||||
try {
|
||||
objBefore = safe.JSON_parse(safe.JSON_stringify(targetArg));
|
||||
} catch(_) {
|
||||
objBefore = undefined;
|
||||
}
|
||||
}
|
||||
if ( objBefore !== undefined ) {
|
||||
const objAfter = objectPruneFn(
|
||||
objBefore,
|
||||
rawPrunePaths,
|
||||
@ -4099,6 +4134,7 @@ function trustedPruneInboundObject(
|
||||
);
|
||||
args[argIndex-1] = objAfter || objBefore;
|
||||
}
|
||||
}
|
||||
return Reflect.apply(target, thisArg, args);
|
||||
},
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user