1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-10-04 08:37:11 +02:00

Fix/improve logging in json-prune scriptlet

This commit is contained in:
Raymond Hill 2023-08-09 08:02:45 -04:00
parent 2c04b5a982
commit b4ffd16db6
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2

View File

@ -640,86 +640,78 @@ function objectPrune(
extraArgs = {} extraArgs = {}
) { ) {
if ( typeof rawPrunePaths !== 'string' ) { return obj; } if ( typeof rawPrunePaths !== 'string' ) { return obj; }
const safe = safeSelf();
const prunePaths = rawPrunePaths !== '' const prunePaths = rawPrunePaths !== ''
? rawPrunePaths.split(/ +/) ? rawPrunePaths.split(/ +/)
: []; : [];
const safe = safeSelf(); const needlePaths = prunePaths.length !== 0 && rawNeedlePaths !== ''
let needlePaths; ? rawNeedlePaths.split(/ +/)
let log, reLogNeedle; : [];
if ( prunePaths.length !== 0 ) { const logLevel = shouldLog({ log: rawPrunePaths === '' || extraArgs.log });
needlePaths = prunePaths.length !== 0 && rawNeedlePaths !== '' const log = logLevel ? ((...args) => { safe.uboLog(...args); }) : (( ) => { });
? rawNeedlePaths.split(/ +/) const reLogNeedle = safe.patternToRegex(logLevel === true ? rawNeedlePaths : '');
: [];
if ( extraArgs.log !== undefined ) {
log = console.log.bind(console);
reLogNeedle = safe.patternToRegex(extraArgs.log);
}
} else {
log = console.log.bind(console);
reLogNeedle = safe.patternToRegex(rawNeedlePaths);
}
if ( stackNeedleDetails.matchAll !== true ) { if ( stackNeedleDetails.matchAll !== true ) {
if ( matchesStackTrace(stackNeedleDetails, extraArgs.logstack) === false ) { if ( matchesStackTrace(stackNeedleDetails, extraArgs.logstack) === false ) {
return obj; return obj;
} }
} }
const findOwner = function(root, path, prune = false) { if ( objectPrune.findOwner === undefined ) {
let owner = root; objectPrune.findOwner = (root, path, prune = false) => {
let chain = path; let owner = root;
for (;;) { let chain = path;
if ( typeof owner !== 'object' || owner === null ) { for (;;) {
return false; if ( typeof owner !== 'object' || owner === null ) { return false; }
} const pos = chain.indexOf('.');
const pos = chain.indexOf('.'); if ( pos === -1 ) {
if ( pos === -1 ) { if ( prune === false ) {
if ( prune === false ) { return owner.hasOwnProperty(chain);
return owner.hasOwnProperty(chain);
}
if ( chain === '*' ) {
for ( const key in owner ) {
if ( owner.hasOwnProperty(key) === false ) { continue; }
delete owner[key];
} }
} else if ( owner.hasOwnProperty(chain) ) { if ( chain === '*' ) {
delete owner[chain]; for ( const key in owner ) {
if ( owner.hasOwnProperty(key) === false ) { continue; }
delete owner[key];
}
} else if ( owner.hasOwnProperty(chain) ) {
delete owner[chain];
}
return true;
} }
return true; const prop = chain.slice(0, pos);
} if (
const prop = chain.slice(0, pos); prop === '[]' && Array.isArray(owner) ||
if ( prop === '*' && owner instanceof Object
prop === '[]' && Array.isArray(owner) || ) {
prop === '*' && owner instanceof Object const next = chain.slice(pos + 1);
) { let found = false;
const next = chain.slice(pos + 1); for ( const key of Object.keys(owner) ) {
let found = false; found = objectPrune.findOwner(owner[key], next, prune) || found;
for ( const key of Object.keys(owner) ) { }
found = findOwner(owner[key], next, prune) || found; return found;
} }
return found; if ( owner.hasOwnProperty(prop) === false ) { return false; }
owner = owner[prop];
chain = chain.slice(pos + 1);
} }
if ( owner.hasOwnProperty(prop) === false ) { return false; } };
owner = owner[prop]; objectPrune.mustProcess = (root, needlePaths) => {
chain = chain.slice(pos + 1); for ( const needlePath of needlePaths ) {
} if ( objectPrune.findOwner(root, needlePath) === false ) {
}; return false;
const mustProcess = function(root) { }
for ( const needlePath of needlePaths ) {
if ( findOwner(root, needlePath) === false ) {
return false;
} }
} return true;
return true; };
}; }
if ( log !== undefined ) { if ( logLevel === true || logLevel === 'all' ) {
const json = JSON.stringify(obj, null, 2); const json = JSON.stringify(obj, null, 2);
if ( reLogNeedle.test(json) ) { if ( reLogNeedle.test(json) ) {
log('uBO:', location.hostname, json); log(location.hostname, json);
} }
return obj;
} }
if ( mustProcess(obj) === false ) { return obj; } if ( prunePaths.length === 0 ) { return obj; }
if ( objectPrune.mustProcess(obj, needlePaths) === false ) { return obj; }
for ( const path of prunePaths ) { for ( const path of prunePaths ) {
findOwner(obj, path, true); objectPrune.findOwner(obj, path, true);
} }
return obj; return obj;
} }
@ -1222,6 +1214,9 @@ function jsonPrune(
) { ) {
JSON.parse = new Proxy(JSON.parse, { JSON.parse = new Proxy(JSON.parse, {
apply: function(target, thisArg, args) { apply: function(target, thisArg, args) {
if ( logLevel ) {
safe.uboLog('json-prune / JSON.parse()');
}
return objectPrune( return objectPrune(
Reflect.apply(target, thisArg, args), Reflect.apply(target, thisArg, args),
rawPrunePaths, rawPrunePaths,
@ -1235,19 +1230,20 @@ function jsonPrune(
Response.prototype.json = new Proxy(Response.prototype.json, { Response.prototype.json = new Proxy(Response.prototype.json, {
apply: function(target, thisArg, args) { apply: function(target, thisArg, args) {
const dataPromise = Reflect.apply(target, thisArg, args); const dataPromise = Reflect.apply(target, thisArg, args);
let outcome = 'match';
if ( fetchPropNeedles.size !== 0 ) { if ( fetchPropNeedles.size !== 0 ) {
const outcome = matchObjectProperties(fetchPropNeedles, thisArg) if ( matchObjectProperties(fetchPropNeedles, thisArg) === false ) {
? 'match' outcome = 'nomatch';
: 'nomatch';
if ( outcome === logLevel || logLevel === 'all' ) {
safe.uboLog(
`json-prune (${outcome})`,
`\n\tpropsToMatch: ${JSON.stringify(Array.from(fetchPropNeedles)).slice(1,-1)}`,
'\n\tprops:', thisArg,
);
} }
if ( outcome === 'nomatch' ) { return dataPromise; }
} }
if ( outcome === logLevel || logLevel === 'all' ) {
safe.uboLog(
`json-prune / Response.json() (${outcome})`,
`\n\tfetchPropsToMatch: ${JSON.stringify(Array.from(fetchPropNeedles)).slice(1,-1)}`,
'\n\tprops:', thisArg,
);
}
if ( outcome === 'nomatch' ) { return dataPromise; }
return dataPromise.then(data => objectPrune( return dataPromise.then(data => objectPrune(
data, data,
rawPrunePaths, rawPrunePaths,