Skip to content

Commit 2695b9f

Browse files
committed
Add edit-this-object/trusted-edit-this-object scriptlets
Related issue: uBlockOrigin/uBlock-issues#4019 * @Scriptlet edit-this-object.js * * @description * Prune properties from an object through one of the object's own method. * Properties can only be removed. * * @param propChain * Property chain of the method to trap. * * @param jsonq * A uBO-flavored JSONPath query. * * @param order * If set to `after`, the `this` object will be edited after the trapped * method is called. By default the `this` object is edited before calling * the trapped method. The trusted version works the same as the non-trusted version, except that it allows to assign new values to targeted properties instead of just removing them.
1 parent 09e46b7 commit 2695b9f

1 file changed

Lines changed: 112 additions & 0 deletions

File tree

src/js/resources/json-edit.js

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,118 @@ registerScriptlet(trustedEditInboundObject, {
301301
/******************************************************************************/
302302
/******************************************************************************/
303303

304+
function editThisObjectFn(
305+
trusted = false,
306+
propChain = '',
307+
jsonq = '',
308+
order = ''
309+
) {
310+
if ( propChain === '' ) { return; }
311+
const safe = safeSelf();
312+
const logPrefix = safe.makeLogPrefix(
313+
`${trusted ? 'trusted-' : ''}edit-this-object`,
314+
propChain,
315+
jsonq
316+
);
317+
const jsonp = JSONPath.create(jsonq);
318+
if ( jsonp.valid === false || jsonp.value !== undefined && trusted !== true ) {
319+
return safe.uboLog(logPrefix, 'Bad JSONPath query');
320+
}
321+
const editObj = objBefore => {
322+
const objAfter = jsonp.apply(objBefore);
323+
if ( objAfter === undefined ) { return; }
324+
safe.uboLog(logPrefix, 'Edited');
325+
if ( safe.logLevel <= 1 ) { return; }
326+
safe.uboLog(logPrefix, `After edit:\n${safe.JSON_stringify(objAfter, null, 2)}`);
327+
};
328+
proxyApplyFn(propChain, function(context) {
329+
const { thisArg } = context;
330+
let r;
331+
if ( order === 'after' ) {
332+
r = context.reflect();
333+
}
334+
editObj(thisArg);
335+
if ( order !== 'after' ) {
336+
r = context.reflect();
337+
}
338+
return r;
339+
});
340+
}
341+
registerScriptlet(editThisObjectFn, {
342+
name: 'edit-this-object.fn',
343+
dependencies: [
344+
JSONPath,
345+
proxyApplyFn,
346+
safeSelf,
347+
],
348+
});
349+
350+
/******************************************************************************/
351+
/**
352+
* @scriptlet edit-this-object.js
353+
*
354+
* @description
355+
* Prune properties from an object through one of the object's own method.
356+
* Properties can only be removed.
357+
*
358+
* @param propChain
359+
* Property chain of the method to trap.
360+
*
361+
* @param jsonq
362+
* A uBO-flavored JSONPath query.
363+
*
364+
* @param order
365+
* If set to `after`, the `this` object will be edited after the trapped method
366+
* is called. By default the `this` object is edited before calling the trapped
367+
* method.
368+
*
369+
* */
370+
371+
function editThisObject(...args) {
372+
editThisObjectFn(false, ...args);
373+
}
374+
registerScriptlet(editThisObject, {
375+
name: 'edit-this-object.js',
376+
dependencies: [
377+
editThisObjectFn,
378+
],
379+
});
380+
381+
/******************************************************************************/
382+
/**
383+
* @scriptlet trusted-edit-this-object.js
384+
*
385+
* @description
386+
* Edit properties of an object through one of the object's own method.
387+
* Properties can be assigned new values.
388+
*
389+
* @param propChain
390+
* Property chain of the method to trap.
391+
*
392+
* @param jsonq
393+
* A uBO-flavored JSONPath query.
394+
*
395+
* @param order
396+
* If set to `after`, the `this` object will be edited after the trapped method
397+
* is called. By default the `this` object is edited before calling the trapped
398+
* method.
399+
*
400+
* */
401+
402+
function trustedEditThisObject(...args) {
403+
editThisObjectFn(true, ...args);
404+
}
405+
registerScriptlet(trustedEditThisObject, {
406+
name: 'trusted-edit-this-object.js',
407+
requiresTrust: true,
408+
dependencies: [
409+
editThisObjectFn,
410+
],
411+
});
412+
413+
/******************************************************************************/
414+
/******************************************************************************/
415+
304416
function jsonEditXhrResponseFn(trusted, jsonq = '') {
305417
const safe = safeSelf();
306418
const logPrefix = safe.makeLogPrefix(

0 commit comments

Comments
 (0)