Skip to content

Commit

Permalink
Add trusted-prune-outbound-object.js scriptlet
Browse files Browse the repository at this point in the history
Essentially a complement of `trusted-prune-inbound-object.js` added in
1c9da22

To perform object pruning on any object returned synchronously by
any given call.

The arguments for `trusted-prune-outbound-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 properties to prune (as with `json-prune`)

- The properties which must all be present for pruning to occur
  (as with `json-prune`)

The scriptlets `json-prune.js` and `evaldata-prune.js` essentially
perform the same function, and will eventually be rewritten to
internally delegate to generic `trusted-prune-outbound-object.js`.
  • Loading branch information
gorhill committed Oct 22, 2023
1 parent 0b9b5a4 commit 86f0d6d
Showing 1 changed file with 45 additions and 0 deletions.
45 changes: 45 additions & 0 deletions assets/resources/scriptlets.js
Original file line number Diff line number Diff line change
Expand Up @@ -4091,3 +4091,48 @@ function trustedPruneInboundObject(
}

/******************************************************************************/

builtinScriptlets.push({
name: 'trusted-prune-outbound-object.js',
requiresTrust: true,
fn: trustedPruneOutboundObject,
dependencies: [
'object-prune.fn',
'safe-self.fn',
],
});
function trustedPruneOutboundObject(
entryPoint = '',
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 safe = safeSelf();
const extraArgs = safe.getExtraArgs(Array.from(arguments), 3);
context[prop] = new Proxy(context[prop], {
apply: function(target, thisArg, args) {
const objBefore = Reflect.apply(target, thisArg, args);
if ( objBefore instanceof Object === false ) { return objBefore; }
const objAfter = objectPruneFn(
objBefore,
rawPrunePaths,
rawNeedlePaths,
{ matchAll: true },
extraArgs
);
return objAfter || objBefore;
},
});
}

/******************************************************************************/

0 comments on commit 86f0d6d

Please sign in to comment.