mirror of https://github.com/gorhill/uBlock.git
Add `trusted-suppress-native-method` scriptlet
Reference: https://github.com/AdguardTeam/Scriptlets/blob/5a92d79489/wiki/about-trusted-scriptlets.md#trusted-suppress-native-method This is a first draft version, see code comments for details.
This commit is contained in:
parent
a3576ea651
commit
97d11c03c2
|
@ -4756,24 +4756,29 @@ builtinScriptlets.push({
|
||||||
});
|
});
|
||||||
function trustedReplaceArgument(
|
function trustedReplaceArgument(
|
||||||
propChain = '',
|
propChain = '',
|
||||||
argpos = '',
|
argposRaw = '',
|
||||||
argraw = ''
|
argraw = ''
|
||||||
) {
|
) {
|
||||||
if ( propChain === '' ) { return; }
|
if ( propChain === '' ) { return; }
|
||||||
if ( argpos === '' ) { return; }
|
|
||||||
if ( argraw === '' ) { return; }
|
|
||||||
const safe = safeSelf();
|
const safe = safeSelf();
|
||||||
const logPrefix = safe.makeLogPrefix('trusted-replace-argument', propChain, argpos, argraw);
|
const logPrefix = safe.makeLogPrefix('trusted-replace-argument', propChain, argposRaw, argraw);
|
||||||
|
const argpos = parseInt(argposRaw, 10) || 0;
|
||||||
const extraArgs = safe.getExtraArgs(Array.from(arguments), 3);
|
const extraArgs = safe.getExtraArgs(Array.from(arguments), 3);
|
||||||
const normalValue = validateConstantFn(true, argraw);
|
const normalValue = validateConstantFn(true, argraw);
|
||||||
const reCondition = extraArgs.condition
|
const reCondition = extraArgs.condition
|
||||||
? safe.patternToRegex(extraArgs.condition)
|
? safe.patternToRegex(extraArgs.condition)
|
||||||
: /^/;
|
: /^/;
|
||||||
const reflector = proxyApplyFn(propChain, function(...args) {
|
const reflector = proxyApplyFn(propChain, function(...args) {
|
||||||
|
if ( argposRaw === '' ) {
|
||||||
|
safe.uboLog(logPrefix, `Arguments:\n${args.join('\n')}`);
|
||||||
|
return reflector(...args);
|
||||||
|
}
|
||||||
const arglist = args[args.length-1];
|
const arglist = args[args.length-1];
|
||||||
if ( Array.isArray(arglist) === false ) { return reflector(...args); }
|
if ( Array.isArray(arglist) === false ) { return reflector(...args); }
|
||||||
const argBefore = arglist[argpos];
|
const argBefore = arglist[argpos];
|
||||||
if ( reCondition.test(argBefore) === false ) { return reflector(...args); }
|
if ( safe.RegExp_test.call(reCondition, argBefore) === false ) {
|
||||||
|
return reflector(...args);
|
||||||
|
}
|
||||||
arglist[argpos] = normalValue;
|
arglist[argpos] = normalValue;
|
||||||
safe.uboLog(logPrefix, `Replaced argument:\nBefore: ${JSON.stringify(argBefore)}\nAfter: ${normalValue}`);
|
safe.uboLog(logPrefix, `Replaced argument:\nBefore: ${JSON.stringify(argBefore)}\nAfter: ${normalValue}`);
|
||||||
return reflector(...args);
|
return reflector(...args);
|
||||||
|
@ -4830,4 +4835,89 @@ function trustedReplaceOutboundText(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* Reference:
|
||||||
|
* https://github.com/AdguardTeam/Scriptlets/blob/5a92d79489/wiki/about-trusted-scriptlets.md#trusted-suppress-native-method
|
||||||
|
*
|
||||||
|
* This is a first version with current limitations:
|
||||||
|
* - Does not support matching arguments which are object or array
|
||||||
|
* - Does not support `stack` parameter
|
||||||
|
*
|
||||||
|
* If `signatureStr` parameter is not declared, the scriptlet will log all calls
|
||||||
|
* to `methodPath` along with the arguments passed and will not prevent the
|
||||||
|
* trapped method.
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
|
||||||
|
builtinScriptlets.push({
|
||||||
|
name: 'trusted-suppress-native-method.js',
|
||||||
|
requiresTrust: true,
|
||||||
|
fn: trustedSuppressNativeMethod,
|
||||||
|
dependencies: [
|
||||||
|
'proxy-apply.fn',
|
||||||
|
'safe-self.fn',
|
||||||
|
],
|
||||||
|
});
|
||||||
|
function trustedSuppressNativeMethod(
|
||||||
|
methodPath = '',
|
||||||
|
signature = '',
|
||||||
|
how = '',
|
||||||
|
stack = ''
|
||||||
|
) {
|
||||||
|
if ( methodPath === '' ) { return; }
|
||||||
|
if ( stack !== '' ) { return; }
|
||||||
|
const safe = safeSelf();
|
||||||
|
const logPrefix = safe.makeLogPrefix('trusted-suppress-native-method', methodPath, signature, how);
|
||||||
|
const signatureArgs = signature.split(/\s*\|\s*/).map(v => {
|
||||||
|
if ( /^".*"$/.test(v) ) {
|
||||||
|
return { type: 'pattern', re: safe.patternToRegex(v.slice(1, -1)) };
|
||||||
|
}
|
||||||
|
if ( v === 'false' ) {
|
||||||
|
return { type: 'exact', value: false };
|
||||||
|
}
|
||||||
|
if ( v === 'true' ) {
|
||||||
|
return { type: 'exact', value: true };
|
||||||
|
}
|
||||||
|
if ( v === 'null' ) {
|
||||||
|
return { type: 'exact', value: null };
|
||||||
|
}
|
||||||
|
if ( v === 'undefined' ) {
|
||||||
|
return { type: 'exact', value: undefined };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const reflector = proxyApplyFn(methodPath, function(...args) {
|
||||||
|
if ( signature === '' ) {
|
||||||
|
safe.uboLog(logPrefix, `Arguments:\n${args.join('\n')}`);
|
||||||
|
return reflector(...args);
|
||||||
|
}
|
||||||
|
const arglist = args[args.length-1];
|
||||||
|
if ( Array.isArray(arglist) === false ) {
|
||||||
|
return reflector(...args);
|
||||||
|
}
|
||||||
|
if ( arglist.length < signatureArgs.length ) {
|
||||||
|
return reflector(...args);
|
||||||
|
}
|
||||||
|
for ( let i = 0; i < signatureArgs.length; i++ ) {
|
||||||
|
const signatureArg = signatureArgs[i];
|
||||||
|
if ( signatureArg === undefined ) { continue; }
|
||||||
|
const targetArg = arglist[i];
|
||||||
|
if ( signatureArg.type === 'exact' ) {
|
||||||
|
if ( targetArg !== signatureArg.value ) {
|
||||||
|
return reflector(...args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( signatureArg.type === 'pattern' ) {
|
||||||
|
if ( safe.RegExp_test.call(signatureArg.re, targetArg) === false ) {
|
||||||
|
return reflector(...args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
safe.uboLog(logPrefix, `Suppressed:\n${args.join('\n')}`);
|
||||||
|
if ( how === 'abort' ) {
|
||||||
|
throw new ReferenceError();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
Loading…
Reference in New Issue