mirror of https://github.com/gorhill/uBlock.git
Add `trusted-prune-inbound-object` scriptlet
As per discussion with filter list maintainers. To perform object pruning for any given call which has an object as argument (hence "inbound"). Since `json-prune-stringify` scriptlet is a specific form of pruning inbound objects, it has been removed. The arguments for `trusted-prune-inbound-object` in order are: - The name of the property to trap. Must be a function, and must exist when the scriptlet tries to install the trap. - The position of the object to prune in the argument list when the trapped function is called. The position is 1-based and must be an integer greater than 0. - The properties to prune (as with `json-prune`) - The properties which must all be present for pruning to occur (as with `json-prune`) - Varargs: - `, dontOverwrite, 1`: do not modify the target inbound object Examples: Remove `title` and `name` properties before passing the object to `JSON.stringify` call: example.org##+js(trusted-prune-inbound-object, JSON.stringify, 1, title name) Remove `status` property before passing the object to `Object.keys` call but do not modify caller's instance of the object: example.org##+js(trusted-prune-inbound-object, Object.keys, 1, status, , dontOverwrite, 1)
This commit is contained in:
parent
287f7711aa
commit
1c9da227d7
|
@ -1429,42 +1429,6 @@ function jsonPrune(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
builtinScriptlets.push({
|
|
||||||
name: 'json-prune-stringify.js',
|
|
||||||
fn: jsonPruneStringify,
|
|
||||||
dependencies: [
|
|
||||||
'object-prune.fn',
|
|
||||||
'safe-self.fn',
|
|
||||||
],
|
|
||||||
});
|
|
||||||
function jsonPruneStringify(
|
|
||||||
rawPrunePaths = '',
|
|
||||||
rawNeedlePaths = '',
|
|
||||||
stackNeedle = ''
|
|
||||||
) {
|
|
||||||
const safe = safeSelf();
|
|
||||||
const stackNeedleDetails = safe.initPattern(stackNeedle, { canNegate: true });
|
|
||||||
const extraArgs = safe.getExtraArgs(Array.from(arguments), 3);
|
|
||||||
JSON.stringify = new Proxy(JSON.stringify, {
|
|
||||||
apply: function(target, thisArg, args) {
|
|
||||||
const objBefore = args[0];
|
|
||||||
if ( objBefore instanceof Object ) {
|
|
||||||
const objAfter = objectPruneFn(
|
|
||||||
objBefore,
|
|
||||||
rawPrunePaths,
|
|
||||||
rawNeedlePaths,
|
|
||||||
stackNeedleDetails,
|
|
||||||
extraArgs
|
|
||||||
);
|
|
||||||
args[0] = objAfter || objBefore;
|
|
||||||
}
|
|
||||||
return Reflect.apply(target, thisArg, args);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* json-prune-fetch-response.js
|
* json-prune-fetch-response.js
|
||||||
|
@ -4071,3 +4035,59 @@ function trustedClickElement(
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
builtinScriptlets.push({
|
||||||
|
name: 'trusted-prune-inbound-object.js',
|
||||||
|
requiresTrust: true,
|
||||||
|
fn: trustedPruneInboundObject,
|
||||||
|
dependencies: [
|
||||||
|
'object-prune.fn',
|
||||||
|
'safe-self.fn',
|
||||||
|
],
|
||||||
|
});
|
||||||
|
function trustedPruneInboundObject(
|
||||||
|
entryPoint = '',
|
||||||
|
argPos = '',
|
||||||
|
rawPrunePaths = '',
|
||||||
|
rawNeedlePaths = ''
|
||||||
|
) {
|
||||||
|
if ( entryPoint === '' ) { return; }
|
||||||
|
let context = globalThis;
|
||||||
|
let prop = entryPoint;
|
||||||
|
for (;;) {
|
||||||
|
const pos = prop.indexOf('.');
|
||||||
|
if ( pos === -1 ) { break; }
|
||||||
|
context = context[prop.slice(0, pos)];
|
||||||
|
if ( context instanceof Object === false ) { return; }
|
||||||
|
prop = prop.slice(pos+1);
|
||||||
|
}
|
||||||
|
if ( typeof context[prop] !== 'function' ) { return; }
|
||||||
|
const argIndex = parseInt(argPos);
|
||||||
|
if ( isNaN(argIndex) ) { return; }
|
||||||
|
if ( argIndex < 1 ) { return; }
|
||||||
|
const safe = safeSelf();
|
||||||
|
const extraArgs = safe.getExtraArgs(Array.from(arguments), 4);
|
||||||
|
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;
|
||||||
|
const objAfter = objectPruneFn(
|
||||||
|
objBefore,
|
||||||
|
rawPrunePaths,
|
||||||
|
rawNeedlePaths,
|
||||||
|
{ matchAll: true },
|
||||||
|
extraArgs
|
||||||
|
);
|
||||||
|
args[argIndex-1] = objAfter || objBefore;
|
||||||
|
}
|
||||||
|
return Reflect.apply(target, thisArg, args);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
Loading…
Reference in New Issue