mirror of
https://github.com/gorhill/uBlock.git
synced 2024-10-06 09:37:12 +02:00
Ensure scriptlet logging information make it to destination
Avoid race conditions between isolated world-side broadcast channel and main-side broadcast channel, so as to not lose logging information if the isolated world-side is not yet ready to receive through its broadcast channel. Additionally, added new scriptlet: `trusted-replace-argument`. [...]##+js(trusted-replace-argument, fn, argpos, argval [,condition, pattern]) Where: - `fn` is the function we want to proxy through an `apply` handler. This can also be a class, in which case the scriptlet will proxy through `construct` handler. At the moment, `fn` must exist at the time the scriptlet executes. - `argpos` is the 0-based position of the argument we want to change - `argval` is the value we want to have for the argument -- the value is interpreted the same way the value for `set-constant` is interpreted. - `condition, pattern` is a vararg which tells the scriptlet to act only if `pattern` is found in the argument to overwrite. Example of usage: alliptvlinks.com##+js(trusted-replace-argument, MutationObserver, 0, noopFunc)
This commit is contained in:
parent
55e4cee6e8
commit
34da372d7a
@ -156,25 +156,39 @@ function safeSelf() {
|
|||||||
return this.Object_fromEntries(entries);
|
return this.Object_fromEntries(entries);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
if ( scriptletGlobals.bcSecret !== undefined ) {
|
|
||||||
const bc = new self.BroadcastChannel(scriptletGlobals.bcSecret);
|
|
||||||
safe.logLevel = scriptletGlobals.logLevel || 1;
|
|
||||||
safe.sendToLogger = (type, ...args) => {
|
|
||||||
if ( args.length === 0 ) { return; }
|
|
||||||
const text = `[${document.location.hostname || document.location.href}]${args.join(' ')}`;
|
|
||||||
bc.postMessage({ what: 'messageToLogger', type, text });
|
|
||||||
};
|
|
||||||
bc.onmessage = ev => {
|
|
||||||
const msg = ev.data;
|
|
||||||
if ( msg instanceof Object === false ) { return; }
|
|
||||||
switch ( msg.what ) {
|
|
||||||
case 'setScriptletLogLevel':
|
|
||||||
safe.logLevel = msg.level;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
scriptletGlobals.safeSelf = safe;
|
scriptletGlobals.safeSelf = safe;
|
||||||
|
if ( scriptletGlobals.bcSecret === undefined ) { return safe; }
|
||||||
|
// This is executed only when the logger is opened
|
||||||
|
const bc = new self.BroadcastChannel(scriptletGlobals.bcSecret);
|
||||||
|
let bcBuffer = [];
|
||||||
|
safe.logLevel = scriptletGlobals.logLevel || 1;
|
||||||
|
safe.sendToLogger = (type, ...args) => {
|
||||||
|
if ( args.length === 0 ) { return; }
|
||||||
|
const text = `[${document.location.hostname || document.location.href}]${args.join(' ')}`;
|
||||||
|
if ( bcBuffer === undefined ) {
|
||||||
|
return bc.postMessage({ what: 'messageToLogger', type, text });
|
||||||
|
}
|
||||||
|
bcBuffer.push({ type, text });
|
||||||
|
};
|
||||||
|
bc.onmessage = ev => {
|
||||||
|
const msg = ev.data;
|
||||||
|
switch ( msg ) {
|
||||||
|
case 'iamready!':
|
||||||
|
if ( bcBuffer === undefined ) { break; }
|
||||||
|
bcBuffer.forEach(({ type, text }) =>
|
||||||
|
bc.postMessage({ what: 'messageToLogger', type, text })
|
||||||
|
);
|
||||||
|
bcBuffer = undefined;
|
||||||
|
break;
|
||||||
|
case 'setScriptletLogLevelToOne':
|
||||||
|
safe.logLevel = 1;
|
||||||
|
break;
|
||||||
|
case 'setScriptletLogLevelToTwo':
|
||||||
|
safe.logLevel = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
bc.postMessage('areyouready?');
|
||||||
return safe;
|
return safe;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,34 +468,90 @@ function abortCurrentScriptCore(
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
builtinScriptlets.push({
|
builtinScriptlets.push({
|
||||||
name: 'set-constant-core.fn',
|
name: 'validate-constant.fn',
|
||||||
fn: setConstantCore,
|
fn: validateConstantFn,
|
||||||
dependencies: [
|
dependencies: [
|
||||||
'run-at.fn',
|
|
||||||
'safe-self.fn',
|
'safe-self.fn',
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
function validateConstantFn(trusted, raw) {
|
||||||
|
const safe = safeSelf();
|
||||||
|
const extraArgs = safe.getExtraArgs(Array.from(arguments), 2);
|
||||||
|
let value;
|
||||||
|
if ( raw === 'undefined' ) {
|
||||||
|
value = undefined;
|
||||||
|
} else if ( raw === 'false' ) {
|
||||||
|
value = false;
|
||||||
|
} else if ( raw === 'true' ) {
|
||||||
|
value = true;
|
||||||
|
} else if ( raw === 'null' ) {
|
||||||
|
value = null;
|
||||||
|
} else if ( raw === "''" || raw === '' ) {
|
||||||
|
value = '';
|
||||||
|
} else if ( raw === '[]' || raw === 'emptyArr' ) {
|
||||||
|
value = [];
|
||||||
|
} else if ( raw === '{}' || raw === 'emptyObj' ) {
|
||||||
|
value = {};
|
||||||
|
} else if ( raw === 'noopFunc' ) {
|
||||||
|
value = function(){};
|
||||||
|
} else if ( raw === 'trueFunc' ) {
|
||||||
|
value = function(){ return true; };
|
||||||
|
} else if ( raw === 'falseFunc' ) {
|
||||||
|
value = function(){ return false; };
|
||||||
|
} else if ( /^-?\d+$/.test(raw) ) {
|
||||||
|
value = parseInt(raw);
|
||||||
|
if ( isNaN(raw) ) { return; }
|
||||||
|
if ( Math.abs(raw) > 0x7FFF ) { return; }
|
||||||
|
} else if ( trusted ) {
|
||||||
|
if ( raw.startsWith('{') && raw.endsWith('}') ) {
|
||||||
|
try { value = safe.JSON_parse(raw).value; } catch(ex) { return; }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( extraArgs.as !== undefined ) {
|
||||||
|
if ( extraArgs.as === 'function' ) {
|
||||||
|
return ( ) => value;
|
||||||
|
} else if ( extraArgs.as === 'callback' ) {
|
||||||
|
return ( ) => (( ) => value);
|
||||||
|
} else if ( extraArgs.as === 'resolved' ) {
|
||||||
|
return Promise.resolve(value);
|
||||||
|
} else if ( extraArgs.as === 'rejected' ) {
|
||||||
|
return Promise.reject(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
function setConstantCore(
|
/******************************************************************************/
|
||||||
|
|
||||||
|
builtinScriptlets.push({
|
||||||
|
name: 'set-constant.fn',
|
||||||
|
fn: setConstantFn,
|
||||||
|
dependencies: [
|
||||||
|
'run-at.fn',
|
||||||
|
'safe-self.fn',
|
||||||
|
'validate-constant.fn',
|
||||||
|
],
|
||||||
|
});
|
||||||
|
function setConstantFn(
|
||||||
trusted = false,
|
trusted = false,
|
||||||
chain = '',
|
chain = '',
|
||||||
cValue = ''
|
rawValue = ''
|
||||||
) {
|
) {
|
||||||
if ( chain === '' ) { return; }
|
if ( chain === '' ) { return; }
|
||||||
const safe = safeSelf();
|
const safe = safeSelf();
|
||||||
const logPrefix = safe.makeLogPrefix('set-constant', chain, cValue);
|
const logPrefix = safe.makeLogPrefix('set-constant', chain, rawValue);
|
||||||
const extraArgs = safe.getExtraArgs(Array.from(arguments), 3);
|
const extraArgs = safe.getExtraArgs(Array.from(arguments), 3);
|
||||||
function setConstant(chain, cValue) {
|
function setConstant(chain, rawValue) {
|
||||||
const trappedProp = (( ) => {
|
const trappedProp = (( ) => {
|
||||||
const pos = chain.lastIndexOf('.');
|
const pos = chain.lastIndexOf('.');
|
||||||
if ( pos === -1 ) { return chain; }
|
if ( pos === -1 ) { return chain; }
|
||||||
return chain.slice(pos+1);
|
return chain.slice(pos+1);
|
||||||
})();
|
})();
|
||||||
if ( trappedProp === '' ) { return; }
|
|
||||||
const thisScript = document.currentScript;
|
|
||||||
const cloakFunc = fn => {
|
const cloakFunc = fn => {
|
||||||
safe.Object_defineProperty(fn, 'name', { value: trappedProp });
|
safe.Object_defineProperty(fn, 'name', { value: trappedProp });
|
||||||
const proxy = new Proxy(fn, {
|
return new Proxy(fn, {
|
||||||
defineProperty(target, prop) {
|
defineProperty(target, prop) {
|
||||||
if ( prop !== 'toString' ) {
|
if ( prop !== 'toString' ) {
|
||||||
return Reflect.defineProperty(...arguments);
|
return Reflect.defineProperty(...arguments);
|
||||||
@ -503,50 +573,12 @@ function setConstantCore(
|
|||||||
return Reflect.get(...arguments);
|
return Reflect.get(...arguments);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return proxy;
|
|
||||||
};
|
};
|
||||||
if ( cValue === 'undefined' ) {
|
if ( trappedProp === '' ) { return; }
|
||||||
cValue = undefined;
|
const thisScript = document.currentScript;
|
||||||
} else if ( cValue === 'false' ) {
|
let normalValue = validateConstantFn(trusted, rawValue);
|
||||||
cValue = false;
|
if ( rawValue === 'noopFunc' || rawValue === 'trueFunc' || rawValue === 'falseFunc' ) {
|
||||||
} else if ( cValue === 'true' ) {
|
normalValue = cloakFunc(normalValue);
|
||||||
cValue = true;
|
|
||||||
} else if ( cValue === 'null' ) {
|
|
||||||
cValue = null;
|
|
||||||
} else if ( cValue === "''" || cValue === '' ) {
|
|
||||||
cValue = '';
|
|
||||||
} else if ( cValue === '[]' || cValue === 'emptyArr' ) {
|
|
||||||
cValue = [];
|
|
||||||
} else if ( cValue === '{}' || cValue === 'emptyObj' ) {
|
|
||||||
cValue = {};
|
|
||||||
} else if ( cValue === 'noopFunc' ) {
|
|
||||||
cValue = cloakFunc(function(){});
|
|
||||||
} else if ( cValue === 'trueFunc' ) {
|
|
||||||
cValue = cloakFunc(function(){ return true; });
|
|
||||||
} else if ( cValue === 'falseFunc' ) {
|
|
||||||
cValue = cloakFunc(function(){ return false; });
|
|
||||||
} else if ( /^-?\d+$/.test(cValue) ) {
|
|
||||||
cValue = parseInt(cValue);
|
|
||||||
if ( isNaN(cValue) ) { return; }
|
|
||||||
if ( Math.abs(cValue) > 0x7FFF ) { return; }
|
|
||||||
} else if ( trusted ) {
|
|
||||||
if ( cValue.startsWith('{') && cValue.endsWith('}') ) {
|
|
||||||
try { cValue = safe.JSON_parse(cValue).value; } catch(ex) { return; }
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ( extraArgs.as !== undefined ) {
|
|
||||||
const value = cValue;
|
|
||||||
if ( extraArgs.as === 'function' ) {
|
|
||||||
cValue = ( ) => value;
|
|
||||||
} else if ( extraArgs.as === 'callback' ) {
|
|
||||||
cValue = ( ) => (( ) => value);
|
|
||||||
} else if ( extraArgs.as === 'resolved' ) {
|
|
||||||
cValue = Promise.resolve(value);
|
|
||||||
} else if ( extraArgs.as === 'rejected' ) {
|
|
||||||
cValue = Promise.reject(value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
let aborted = false;
|
let aborted = false;
|
||||||
const mustAbort = function(v) {
|
const mustAbort = function(v) {
|
||||||
@ -554,8 +586,8 @@ function setConstantCore(
|
|||||||
if ( aborted ) { return true; }
|
if ( aborted ) { return true; }
|
||||||
aborted =
|
aborted =
|
||||||
(v !== undefined && v !== null) &&
|
(v !== undefined && v !== null) &&
|
||||||
(cValue !== undefined && cValue !== null) &&
|
(normalValue !== undefined && normalValue !== null) &&
|
||||||
(typeof v !== typeof cValue);
|
(typeof v !== typeof normalValue);
|
||||||
if ( aborted ) {
|
if ( aborted ) {
|
||||||
safe.uboLog(logPrefix, `Aborted because value set to ${v}`);
|
safe.uboLog(logPrefix, `Aborted because value set to ${v}`);
|
||||||
}
|
}
|
||||||
@ -564,11 +596,11 @@ function setConstantCore(
|
|||||||
// https://github.com/uBlockOrigin/uBlock-issues/issues/156
|
// https://github.com/uBlockOrigin/uBlock-issues/issues/156
|
||||||
// Support multiple trappers for the same property.
|
// Support multiple trappers for the same property.
|
||||||
const trapProp = function(owner, prop, configurable, handler) {
|
const trapProp = function(owner, prop, configurable, handler) {
|
||||||
if ( handler.init(configurable ? owner[prop] : cValue) === false ) { return; }
|
if ( handler.init(configurable ? owner[prop] : normalValue) === false ) { return; }
|
||||||
const odesc = safe.Object_getOwnPropertyDescriptor(owner, prop);
|
const odesc = safe.Object_getOwnPropertyDescriptor(owner, prop);
|
||||||
let prevGetter, prevSetter;
|
let prevGetter, prevSetter;
|
||||||
if ( odesc instanceof safe.Object ) {
|
if ( odesc instanceof safe.Object ) {
|
||||||
owner[prop] = cValue;
|
owner[prop] = normalValue;
|
||||||
if ( odesc.get instanceof Function ) {
|
if ( odesc.get instanceof Function ) {
|
||||||
prevGetter = odesc.get;
|
prevGetter = odesc.get;
|
||||||
}
|
}
|
||||||
@ -583,7 +615,7 @@ function setConstantCore(
|
|||||||
if ( prevGetter !== undefined ) {
|
if ( prevGetter !== undefined ) {
|
||||||
prevGetter();
|
prevGetter();
|
||||||
}
|
}
|
||||||
return handler.getter(); // cValue
|
return handler.getter();
|
||||||
},
|
},
|
||||||
set(a) {
|
set(a) {
|
||||||
if ( prevSetter !== undefined ) {
|
if ( prevSetter !== undefined ) {
|
||||||
@ -592,7 +624,9 @@ function setConstantCore(
|
|||||||
handler.setter(a);
|
handler.setter(a);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
safe.uboLog(logPrefix, 'Trap installed');
|
||||||
} catch(ex) {
|
} catch(ex) {
|
||||||
|
safe.uboErr(logPrefix, ex);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const trapChain = function(owner, chain) {
|
const trapChain = function(owner, chain) {
|
||||||
@ -610,11 +644,11 @@ function setConstantCore(
|
|||||||
return this.v;
|
return this.v;
|
||||||
}
|
}
|
||||||
safe.uboLog(logPrefix, 'Property read');
|
safe.uboLog(logPrefix, 'Property read');
|
||||||
return cValue;
|
return normalValue;
|
||||||
},
|
},
|
||||||
setter: function(a) {
|
setter: function(a) {
|
||||||
if ( mustAbort(a) === false ) { return; }
|
if ( mustAbort(a) === false ) { return; }
|
||||||
cValue = a;
|
normalValue = a;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@ -646,7 +680,7 @@ function setConstantCore(
|
|||||||
trapChain(window, chain);
|
trapChain(window, chain);
|
||||||
}
|
}
|
||||||
runAt(( ) => {
|
runAt(( ) => {
|
||||||
setConstant(chain, cValue);
|
setConstant(chain, rawValue);
|
||||||
}, extraArgs.runAt);
|
}, extraArgs.runAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1307,6 +1341,37 @@ function replaceFetchResponseFn(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
builtinScriptlets.push({
|
||||||
|
name: 'proxy-apply.fn',
|
||||||
|
fn: proxyApplyFn,
|
||||||
|
dependencies: [
|
||||||
|
'safe-self.fn',
|
||||||
|
],
|
||||||
|
});
|
||||||
|
function proxyApplyFn(
|
||||||
|
target = '',
|
||||||
|
handler = ''
|
||||||
|
) {
|
||||||
|
let context = globalThis;
|
||||||
|
let prop = target;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
const fn = context[prop];
|
||||||
|
if ( typeof fn !== 'function' ) { return; }
|
||||||
|
if ( fn.prototype && fn.prototype.constructor === fn ) {
|
||||||
|
context[prop] = new Proxy(fn, { construct: handler });
|
||||||
|
return (...args) => { return Reflect.construct(...args); };
|
||||||
|
}
|
||||||
|
context[prop] = new Proxy(fn, { apply: handler });
|
||||||
|
return (...args) => { return Reflect.apply(...args); };
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
@ -2208,13 +2273,13 @@ builtinScriptlets.push({
|
|||||||
],
|
],
|
||||||
fn: setConstant,
|
fn: setConstant,
|
||||||
dependencies: [
|
dependencies: [
|
||||||
'set-constant-core.fn'
|
'set-constant.fn'
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
function setConstant(
|
function setConstant(
|
||||||
...args
|
...args
|
||||||
) {
|
) {
|
||||||
setConstantCore(false, ...args);
|
setConstantFn(false, ...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -2517,7 +2582,7 @@ function noXhrIf(
|
|||||||
details.xhr.dispatchEvent(new Event('readystatechange'));
|
details.xhr.dispatchEvent(new Event('readystatechange'));
|
||||||
details.xhr.dispatchEvent(new Event('load'));
|
details.xhr.dispatchEvent(new Event('load'));
|
||||||
details.xhr.dispatchEvent(new Event('loadend'));
|
details.xhr.dispatchEvent(new Event('loadend'));
|
||||||
safe.uboLog(logPrefix, `Prevented with:\n${details.xhr.response}`);
|
safe.uboLog(logPrefix, `Prevented with response:\n${details.xhr.response}`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
getResponseHeader(headerName) {
|
getResponseHeader(headerName) {
|
||||||
@ -3944,13 +4009,13 @@ builtinScriptlets.push({
|
|||||||
],
|
],
|
||||||
fn: trustedSetConstant,
|
fn: trustedSetConstant,
|
||||||
dependencies: [
|
dependencies: [
|
||||||
'set-constant-core.fn'
|
'set-constant.fn'
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
function trustedSetConstant(
|
function trustedSetConstant(
|
||||||
...args
|
...args
|
||||||
) {
|
) {
|
||||||
setConstantCore(true, ...args);
|
setConstantFn(true, ...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -4437,40 +4502,67 @@ builtinScriptlets.push({
|
|||||||
fn: trustedPruneOutboundObject,
|
fn: trustedPruneOutboundObject,
|
||||||
dependencies: [
|
dependencies: [
|
||||||
'object-prune.fn',
|
'object-prune.fn',
|
||||||
|
'proxy-apply.fn',
|
||||||
'safe-self.fn',
|
'safe-self.fn',
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
function trustedPruneOutboundObject(
|
function trustedPruneOutboundObject(
|
||||||
entryPoint = '',
|
propChain = '',
|
||||||
rawPrunePaths = '',
|
rawPrunePaths = '',
|
||||||
rawNeedlePaths = ''
|
rawNeedlePaths = ''
|
||||||
) {
|
) {
|
||||||
if ( entryPoint === '' ) { return; }
|
if ( propChain === '' ) { 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 safe = safeSelf();
|
||||||
const extraArgs = safe.getExtraArgs(Array.from(arguments), 3);
|
const extraArgs = safe.getExtraArgs(Array.from(arguments), 3);
|
||||||
context[prop] = new Proxy(context[prop], {
|
const reflector = proxyApplyFn(propChain, function(...args) {
|
||||||
apply: function(target, thisArg, args) {
|
const objBefore = reflector(...args);
|
||||||
const objBefore = Reflect.apply(target, thisArg, args);
|
if ( objBefore instanceof Object === false ) { return objBefore; }
|
||||||
if ( objBefore instanceof Object === false ) { return objBefore; }
|
const objAfter = objectPruneFn(
|
||||||
const objAfter = objectPruneFn(
|
objBefore,
|
||||||
objBefore,
|
rawPrunePaths,
|
||||||
rawPrunePaths,
|
rawNeedlePaths,
|
||||||
rawNeedlePaths,
|
{ matchAll: true },
|
||||||
{ matchAll: true },
|
extraArgs
|
||||||
extraArgs
|
);
|
||||||
);
|
return objAfter || objBefore;
|
||||||
return objAfter || objBefore;
|
});
|
||||||
},
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
builtinScriptlets.push({
|
||||||
|
name: 'trusted-replace-argument.js',
|
||||||
|
requiresTrust: true,
|
||||||
|
fn: trustedReplaceArgument,
|
||||||
|
dependencies: [
|
||||||
|
'proxy-apply.fn',
|
||||||
|
'safe-self.fn',
|
||||||
|
'validate-constant.fn',
|
||||||
|
],
|
||||||
|
});
|
||||||
|
function trustedReplaceArgument(
|
||||||
|
propChain = '',
|
||||||
|
argpos = '',
|
||||||
|
argraw = ''
|
||||||
|
) {
|
||||||
|
if ( propChain === '' ) { return; }
|
||||||
|
if ( argpos === '' ) { return; }
|
||||||
|
if ( argraw === '' ) { return; }
|
||||||
|
const safe = safeSelf();
|
||||||
|
const logPrefix = safe.makeLogPrefix('trusted-replace-argument', propChain, argpos, argraw);
|
||||||
|
const extraArgs = safe.getExtraArgs(Array.from(arguments), 3);
|
||||||
|
const normalValue = validateConstantFn(true, argraw);
|
||||||
|
const reCondition = extraArgs.condition
|
||||||
|
? safe.patternToRegex(extraArgs.condition)
|
||||||
|
: /^/;
|
||||||
|
const reflector = proxyApplyFn(propChain, function(...args) {
|
||||||
|
const arglist = args.length >= 2 && args[1];
|
||||||
|
if ( Array.isArray(arglist) === false ) { return reflector(...args); }
|
||||||
|
const argBefore = arglist[argpos];
|
||||||
|
if ( reCondition.test(argBefore) === false ) { return reflector(...args); }
|
||||||
|
arglist[argpos] = normalValue;
|
||||||
|
safe.uboLog(logPrefix, `Replaced argument:\nBefore: ${argBefore.trim()}\nAfter: ${normalValue}`);
|
||||||
|
return reflector(...args);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,12 +180,22 @@ const onScriptletMessageInjector = (( ) => {
|
|||||||
if ( vAPI.bcSecret ) { return; }
|
if ( vAPI.bcSecret ) { return; }
|
||||||
const bcSecret = new self.BroadcastChannel(name);
|
const bcSecret = new self.BroadcastChannel(name);
|
||||||
bcSecret.onmessage = ev => {
|
bcSecret.onmessage = ev => {
|
||||||
if ( self.vAPI && self.vAPI.messaging ) {
|
const msg = ev.data;
|
||||||
self.vAPI.messaging.send('contentscript', ev.data);
|
switch ( typeof msg ) {
|
||||||
} else {
|
case 'string':
|
||||||
bcSecret.onmessage = null;
|
if ( msg !== 'areyouready?' ) { break; }
|
||||||
|
bcSecret.postMessage('iamready!');
|
||||||
|
break;
|
||||||
|
case 'object':
|
||||||
|
if ( self.vAPI && self.vAPI.messaging ) {
|
||||||
|
self.vAPI.messaging.send('contentscript', msg);
|
||||||
|
} else {
|
||||||
|
bcSecret.onmessage = null;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
bcSecret.postMessage('iamready!');
|
||||||
vAPI.bcSecret = bcSecret;
|
vAPI.bcSecret = bcSecret;
|
||||||
}.toString(),
|
}.toString(),
|
||||||
')(',
|
')(',
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
(( ) => {
|
(( ) => {
|
||||||
if ( typeof vAPI !== 'object' || vAPI === null ) { return; }
|
if ( typeof vAPI !== 'object' || vAPI === null ) { return; }
|
||||||
if ( vAPI.bcSecret instanceof self.BroadcastChannel === false ) { return; }
|
if ( vAPI.bcSecret instanceof self.BroadcastChannel === false ) { return; }
|
||||||
vAPI.bcSecret.postMessage({ what: 'setScriptletLogLevel', level: 1 });
|
vAPI.bcSecret.postMessage('setScriptletLogLevelOne');
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
(( ) => {
|
(( ) => {
|
||||||
if ( typeof vAPI !== 'object' || vAPI === null ) { return; }
|
if ( typeof vAPI !== 'object' || vAPI === null ) { return; }
|
||||||
if ( vAPI.bcSecret instanceof self.BroadcastChannel === false ) { return; }
|
if ( vAPI.bcSecret instanceof self.BroadcastChannel === false ) { return; }
|
||||||
vAPI.bcSecret.postMessage({ what: 'setScriptletLogLevel', level: 2 });
|
vAPI.bcSecret.postMessage('setScriptletLogLevelToTwo');
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user