Skip to content

Commit 97d11c0

Browse files
committed
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.
1 parent a3576ea commit 97d11c0

File tree

1 file changed

+95
-5
lines changed

1 file changed

+95
-5
lines changed

assets/resources/scriptlets.js

Lines changed: 95 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4756,24 +4756,29 @@ builtinScriptlets.push({
47564756
});
47574757
function trustedReplaceArgument(
47584758
propChain = '',
4759-
argpos = '',
4759+
argposRaw = '',
47604760
argraw = ''
47614761
) {
47624762
if ( propChain === '' ) { return; }
4763-
if ( argpos === '' ) { return; }
4764-
if ( argraw === '' ) { return; }
47654763
const safe = safeSelf();
4766-
const logPrefix = safe.makeLogPrefix('trusted-replace-argument', propChain, argpos, argraw);
4764+
const logPrefix = safe.makeLogPrefix('trusted-replace-argument', propChain, argposRaw, argraw);
4765+
const argpos = parseInt(argposRaw, 10) || 0;
47674766
const extraArgs = safe.getExtraArgs(Array.from(arguments), 3);
47684767
const normalValue = validateConstantFn(true, argraw);
47694768
const reCondition = extraArgs.condition
47704769
? safe.patternToRegex(extraArgs.condition)
47714770
: /^/;
47724771
const reflector = proxyApplyFn(propChain, function(...args) {
4772+
if ( argposRaw === '' ) {
4773+
safe.uboLog(logPrefix, `Arguments:\n${args.join('\n')}`);
4774+
return reflector(...args);
4775+
}
47734776
const arglist = args[args.length-1];
47744777
if ( Array.isArray(arglist) === false ) { return reflector(...args); }
47754778
const argBefore = arglist[argpos];
4776-
if ( reCondition.test(argBefore) === false ) { return reflector(...args); }
4779+
if ( safe.RegExp_test.call(reCondition, argBefore) === false ) {
4780+
return reflector(...args);
4781+
}
47774782
arglist[argpos] = normalValue;
47784783
safe.uboLog(logPrefix, `Replaced argument:\nBefore: ${JSON.stringify(argBefore)}\nAfter: ${normalValue}`);
47794784
return reflector(...args);
@@ -4830,4 +4835,89 @@ function trustedReplaceOutboundText(
48304835
});
48314836
}
48324837

4838+
/*******************************************************************************
4839+
*
4840+
* Reference:
4841+
* https://github.com/AdguardTeam/Scriptlets/blob/5a92d79489/wiki/about-trusted-scriptlets.md#trusted-suppress-native-method
4842+
*
4843+
* This is a first version with current limitations:
4844+
* - Does not support matching arguments which are object or array
4845+
* - Does not support `stack` parameter
4846+
*
4847+
* If `signatureStr` parameter is not declared, the scriptlet will log all calls
4848+
* to `methodPath` along with the arguments passed and will not prevent the
4849+
* trapped method.
4850+
*
4851+
* */
4852+
4853+
builtinScriptlets.push({
4854+
name: 'trusted-suppress-native-method.js',
4855+
requiresTrust: true,
4856+
fn: trustedSuppressNativeMethod,
4857+
dependencies: [
4858+
'proxy-apply.fn',
4859+
'safe-self.fn',
4860+
],
4861+
});
4862+
function trustedSuppressNativeMethod(
4863+
methodPath = '',
4864+
signature = '',
4865+
how = '',
4866+
stack = ''
4867+
) {
4868+
if ( methodPath === '' ) { return; }
4869+
if ( stack !== '' ) { return; }
4870+
const safe = safeSelf();
4871+
const logPrefix = safe.makeLogPrefix('trusted-suppress-native-method', methodPath, signature, how);
4872+
const signatureArgs = signature.split(/\s*\|\s*/).map(v => {
4873+
if ( /^".*"$/.test(v) ) {
4874+
return { type: 'pattern', re: safe.patternToRegex(v.slice(1, -1)) };
4875+
}
4876+
if ( v === 'false' ) {
4877+
return { type: 'exact', value: false };
4878+
}
4879+
if ( v === 'true' ) {
4880+
return { type: 'exact', value: true };
4881+
}
4882+
if ( v === 'null' ) {
4883+
return { type: 'exact', value: null };
4884+
}
4885+
if ( v === 'undefined' ) {
4886+
return { type: 'exact', value: undefined };
4887+
}
4888+
});
4889+
const reflector = proxyApplyFn(methodPath, function(...args) {
4890+
if ( signature === '' ) {
4891+
safe.uboLog(logPrefix, `Arguments:\n${args.join('\n')}`);
4892+
return reflector(...args);
4893+
}
4894+
const arglist = args[args.length-1];
4895+
if ( Array.isArray(arglist) === false ) {
4896+
return reflector(...args);
4897+
}
4898+
if ( arglist.length < signatureArgs.length ) {
4899+
return reflector(...args);
4900+
}
4901+
for ( let i = 0; i < signatureArgs.length; i++ ) {
4902+
const signatureArg = signatureArgs[i];
4903+
if ( signatureArg === undefined ) { continue; }
4904+
const targetArg = arglist[i];
4905+
if ( signatureArg.type === 'exact' ) {
4906+
if ( targetArg !== signatureArg.value ) {
4907+
return reflector(...args);
4908+
}
4909+
}
4910+
if ( signatureArg.type === 'pattern' ) {
4911+
if ( safe.RegExp_test.call(signatureArg.re, targetArg) === false ) {
4912+
return reflector(...args);
4913+
}
4914+
}
4915+
}
4916+
safe.uboLog(logPrefix, `Suppressed:\n${args.join('\n')}`);
4917+
if ( how === 'abort' ) {
4918+
throw new ReferenceError();
4919+
}
4920+
});
4921+
}
4922+
48334923
/******************************************************************************/

0 commit comments

Comments
 (0)