mirror of
https://github.com/kkapsner/CanvasBlocker
synced 2025-01-30 23:38:47 +01:00
parent
9711c67c3f
commit
26529a3653
228
lib/intercept.js
228
lib/intercept.js
@ -158,9 +158,107 @@
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
let extensionID = browser.extension.getURL("");
|
||||
scope.intercept = function intercept({subject: window}, {check, checkStack, ask, notify, prefs}){
|
||||
function getDataURL(object, prefs){
|
||||
return (
|
||||
this &&
|
||||
prefs("storeImageForInspection") &&
|
||||
prefs("showNotifications")?
|
||||
(
|
||||
this instanceof HTMLCanvasElement?
|
||||
this.toDataURL():
|
||||
(
|
||||
this.canvas instanceof HTMLCanvasElement?
|
||||
this.canvas.toDataURL():
|
||||
false
|
||||
)
|
||||
):
|
||||
false
|
||||
);
|
||||
}
|
||||
function generateChecker(name, changedFunction, siteStatus, original){
|
||||
return function checker(callingDepth = 2){
|
||||
var url = getURL(window);
|
||||
if (!url){
|
||||
return undef;
|
||||
}
|
||||
var error = new Error();
|
||||
try {
|
||||
// return original if the extension itself requested the function
|
||||
if (
|
||||
error.stack
|
||||
.split("\n", callingDepth + 2)[callingDepth + 1]
|
||||
.split("@", callingDepth + 1)[1]
|
||||
.startsWith(extensionID)
|
||||
){
|
||||
return {allow: true, original, window};
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
// stack had an unknown form
|
||||
}
|
||||
if (checkStack(error.stack)){
|
||||
return {allow: true, original, window};
|
||||
}
|
||||
var funcStatus = changedFunction.getStatus(this, siteStatus);
|
||||
|
||||
function notifyCallback(messageId){
|
||||
notify({
|
||||
url,
|
||||
errorStack: error.stack,
|
||||
messageId,
|
||||
timestamp: new Date(),
|
||||
functionName: name,
|
||||
api: changedFunction.api,
|
||||
dataURL: getDataURL(this, prefs)
|
||||
});
|
||||
}
|
||||
|
||||
if (funcStatus.active && !prefs("apiWhiteList")[name]){
|
||||
if (funcStatus.mode === "ask"){
|
||||
funcStatus.mode = ask({
|
||||
window: window,
|
||||
type: changedFunction.type,
|
||||
api: changedFunction.api,
|
||||
canvas: this instanceof HTMLCanvasElement?
|
||||
this:
|
||||
(
|
||||
this &&
|
||||
(this.canvas instanceof HTMLCanvasElement)?
|
||||
this.canvas:
|
||||
false
|
||||
),
|
||||
errorStack: error.stack
|
||||
});
|
||||
}
|
||||
switch (funcStatus.mode){
|
||||
case "allow":
|
||||
return {allow: true, original, window};
|
||||
case "fake":
|
||||
setRandomSupplyByType(prefs("rng"));
|
||||
return {
|
||||
allow: "fake",
|
||||
prefs,
|
||||
notify: notifyCallback,
|
||||
window,
|
||||
original
|
||||
};
|
||||
//case "block":
|
||||
default:
|
||||
return {
|
||||
allow: false,
|
||||
notify: notifyCallback
|
||||
};
|
||||
}
|
||||
}
|
||||
else {
|
||||
return {allow: true, original, window};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var siteStatus = check({url: getURL(window)});
|
||||
logging.verbose("status for page", window, siteStatus);
|
||||
if (siteStatus.mode !== "allow"){
|
||||
@ -177,117 +275,25 @@
|
||||
var constructor = getWrapped(window)[object];
|
||||
if (constructor){
|
||||
var original = constructor.prototype[name];
|
||||
|
||||
Object.defineProperty(
|
||||
constructor.prototype,
|
||||
name,
|
||||
{
|
||||
enumerable: true,
|
||||
configureable: true,
|
||||
get: exportFunction(function(){
|
||||
var url = getURL(window);
|
||||
if (!url){
|
||||
return undef;
|
||||
}
|
||||
var error = new Error();
|
||||
try {
|
||||
// return original if the extension itself requested the function
|
||||
if (error.stack.split("\n", 3)[1].split("@", 2)[1].startsWith(extensionID)){
|
||||
return original;
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
// stack had an unknown form
|
||||
}
|
||||
if (checkStack(error.stack)){
|
||||
return original;
|
||||
}
|
||||
var funcStatus = changedFunction.getStatus(this, siteStatus);
|
||||
|
||||
function notifyCallback(messageId){
|
||||
notify({
|
||||
url,
|
||||
errorStack: error.stack,
|
||||
messageId,
|
||||
timestamp: new Date(),
|
||||
functionName: name,
|
||||
api: changedFunction.api,
|
||||
dataURL:
|
||||
this &&
|
||||
prefs("storeImageForInspection") &&
|
||||
prefs("showNotifications")?
|
||||
(
|
||||
this instanceof HTMLCanvasElement?
|
||||
this.toDataURL():
|
||||
(
|
||||
this.canvas instanceof HTMLCanvasElement?
|
||||
this.canvas.toDataURL():
|
||||
false
|
||||
)
|
||||
):
|
||||
false
|
||||
});
|
||||
}
|
||||
|
||||
if (funcStatus.active && !prefs("apiWhiteList")[name]){
|
||||
if (funcStatus.mode === "ask"){
|
||||
funcStatus.mode = ask({
|
||||
window: window,
|
||||
type: changedFunction.type,
|
||||
api: changedFunction.api,
|
||||
canvas: this instanceof HTMLCanvasElement?
|
||||
this:
|
||||
(
|
||||
this &&
|
||||
(this.canvas instanceof HTMLCanvasElement)?
|
||||
this.canvas:
|
||||
false
|
||||
),
|
||||
errorStack: error.stack
|
||||
});
|
||||
}
|
||||
switch (funcStatus.mode){
|
||||
case "allow":
|
||||
return original;
|
||||
case "fake":
|
||||
setRandomSupplyByType(prefs("rng"));
|
||||
var fake = changedFunction.fakeGenerator(
|
||||
prefs,
|
||||
notifyCallback,
|
||||
window,
|
||||
original
|
||||
);
|
||||
switch (fake){
|
||||
case true:
|
||||
return original;
|
||||
case false:
|
||||
return undef;
|
||||
default:
|
||||
return exportFunction(fake, getWrapped(window));
|
||||
}
|
||||
//case "block":
|
||||
default:
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return original;
|
||||
}
|
||||
}, window),
|
||||
set: exportFunction(function(value){
|
||||
Object.defineProperty(
|
||||
constructor.prototype,
|
||||
name,
|
||||
{
|
||||
value,
|
||||
writable: true,
|
||||
configurable: true,
|
||||
enumerable: true
|
||||
}
|
||||
);
|
||||
}, window)
|
||||
const checker = generateChecker(name, changedFunction, siteStatus, original);
|
||||
var descriptor = Object.getOwnPropertyDescriptor(constructor.prototype, name);
|
||||
if (descriptor.hasOwnProperty("value")){
|
||||
if (changedFunction.fakeGenerator){
|
||||
descriptor.value = exportFunction(
|
||||
changedFunction.fakeGenerator(checker),
|
||||
window
|
||||
);
|
||||
}
|
||||
);
|
||||
else {
|
||||
descriptor.value = null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
descriptor.get = exportFunction(function(){
|
||||
return changedFunction.fakeGenerator(checker);
|
||||
}, window);
|
||||
}
|
||||
Object.defineProperty(constructor.prototype, name, descriptor);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
const logging = require("./logging");
|
||||
const {copyCanvasToWebgl} = require("./webgl");
|
||||
const getWrapped = require("sdk/getWrapped");
|
||||
const {hasType, checkerWrapper} = require("./modifiedAPIFunctions");
|
||||
const modifiedAudioAPI = require("./modifiedAudioAPI");
|
||||
|
||||
var randomSupply = null;
|
||||
@ -151,10 +152,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
function hasType(status, type){
|
||||
return status.type.indexOf(type) !== -1;
|
||||
}
|
||||
|
||||
scope.setRandomSupply = function(supply){
|
||||
randomSupply = supply;
|
||||
modifiedAudioAPI.setRandomSupply(supply);
|
||||
@ -186,10 +183,13 @@
|
||||
}
|
||||
},
|
||||
object: "HTMLCanvasElement",
|
||||
fakeGenerator: function(prefs, notify, window, original){
|
||||
fakeGenerator: function(checker){
|
||||
return function(context, contextAttributes){
|
||||
canvasContextType.set(this, context);
|
||||
return original.apply(this, window.Array.from(arguments));
|
||||
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||
var {prefs, notify, window, original} = check;
|
||||
canvasContextType.set(this, context);
|
||||
return original.apply(this, window.Array.from(args));
|
||||
});
|
||||
};
|
||||
}
|
||||
},
|
||||
@ -205,18 +205,21 @@
|
||||
return status;
|
||||
},
|
||||
object: "HTMLCanvasElement",
|
||||
fakeGenerator: function(prefs, notify, window, original){
|
||||
fakeGenerator: function(checker){
|
||||
return function toDataURL(){
|
||||
if (canvasSizeShouldBeFaked(this, prefs)){
|
||||
var fakeCanvas = getFakeCanvas(window, this, prefs);
|
||||
if (fakeCanvas !== this){
|
||||
notify.call(this, "fakedReadout");
|
||||
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||
var {prefs, notify, window, original} = check;
|
||||
if (canvasSizeShouldBeFaked(this, prefs)){
|
||||
var fakeCanvas = getFakeCanvas(window, this, prefs);
|
||||
if (fakeCanvas !== this){
|
||||
notify.call(this, "fakedReadout");
|
||||
}
|
||||
return original.apply(fakeCanvas, window.Array.from(args));
|
||||
}
|
||||
return original.apply(fakeCanvas, window.Array.from(arguments));
|
||||
}
|
||||
else {
|
||||
return original.apply(this, window.Array.from(arguments));
|
||||
}
|
||||
else {
|
||||
return original.apply(this, window.Array.from(args));
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
},
|
||||
@ -232,18 +235,21 @@
|
||||
return status;
|
||||
},
|
||||
object: "HTMLCanvasElement",
|
||||
fakeGenerator: function(prefs, notify, window, original){
|
||||
fakeGenerator: function(checker){
|
||||
return function toBlob(callback){
|
||||
if (canvasSizeShouldBeFaked(this, prefs)){
|
||||
var fakeCanvas = getFakeCanvas(window, this, prefs);
|
||||
if (fakeCanvas !== this){
|
||||
notify.call(this, "fakedReadout");
|
||||
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||
var {prefs, notify, window, original} = check;
|
||||
if (canvasSizeShouldBeFaked(this, prefs)){
|
||||
var fakeCanvas = getFakeCanvas(window, this, prefs);
|
||||
if (fakeCanvas !== this){
|
||||
notify.call(this, "fakedReadout");
|
||||
}
|
||||
return original.apply(fakeCanvas, window.Array.from(args));
|
||||
}
|
||||
return original.apply(fakeCanvas, window.Array.from(arguments));
|
||||
}
|
||||
else {
|
||||
return original.apply(this, window.Array.from(arguments));
|
||||
}
|
||||
else {
|
||||
return original.apply(this, window.Array.from(args));
|
||||
}
|
||||
});
|
||||
};
|
||||
},
|
||||
exportOptions: {allowCallbacks: true}
|
||||
@ -260,18 +266,21 @@
|
||||
return status;
|
||||
},
|
||||
object: "HTMLCanvasElement",
|
||||
fakeGenerator: function(prefs, notify, window, original){
|
||||
fakeGenerator: function(checker){
|
||||
return function mozGetAsFile(callback){
|
||||
if (canvasSizeShouldBeFaked(this, prefs)){
|
||||
var fakeCanvas = getFakeCanvas(window, this, prefs);
|
||||
if (fakeCanvas !== this){
|
||||
notify.call(this, "fakedReadout");
|
||||
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||
var {prefs, notify, window, original} = check;
|
||||
if (canvasSizeShouldBeFaked(this, prefs)){
|
||||
var fakeCanvas = getFakeCanvas(window, this, prefs);
|
||||
if (fakeCanvas !== this){
|
||||
notify.call(this, "fakedReadout");
|
||||
}
|
||||
return original.apply(fakeCanvas, window.Array.from(args));
|
||||
}
|
||||
return original.apply(fakeCanvas, window.Array.from(arguments));
|
||||
}
|
||||
else {
|
||||
return original.apply(this, window.Array.from(arguments));
|
||||
}
|
||||
else {
|
||||
return original.apply(this, window.Array.from(args));
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
},
|
||||
@ -283,26 +292,29 @@
|
||||
return status;
|
||||
},
|
||||
object: "CanvasRenderingContext2D",
|
||||
fakeGenerator: function(prefs, notify, window, original){
|
||||
fakeGenerator: function(checker){
|
||||
return function getImageData(sx, sy, sw, sh){
|
||||
if (!this || canvasSizeShouldBeFaked(this.canvas, prefs)){
|
||||
var fakeCanvas;
|
||||
var context = this;
|
||||
if (this && this.canvas) {
|
||||
fakeCanvas = getFakeCanvas(window, this.canvas, prefs);
|
||||
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||
var {prefs, notify, window, original} = check;
|
||||
if (!this || canvasSizeShouldBeFaked(this.canvas, prefs)){
|
||||
var fakeCanvas;
|
||||
var context = this;
|
||||
if (this && this.canvas) {
|
||||
fakeCanvas = getFakeCanvas(window, this.canvas, prefs);
|
||||
}
|
||||
if (fakeCanvas && fakeCanvas !== this.canvas){
|
||||
notify.call(this, "fakedReadout");
|
||||
context = window.HTMLCanvasElement.prototype.getContext.call(
|
||||
fakeCanvas,
|
||||
"2d"
|
||||
);
|
||||
}
|
||||
return original.apply(context, window.Array.from(args));
|
||||
}
|
||||
if (fakeCanvas && fakeCanvas !== this.canvas){
|
||||
notify.call(this, "fakedReadout");
|
||||
context = window.HTMLCanvasElement.prototype.getContext.call(
|
||||
fakeCanvas,
|
||||
"2d"
|
||||
);
|
||||
else {
|
||||
return original.apply(this, window.Array.from(args));
|
||||
}
|
||||
return original.apply(context, window.Array.from(arguments));
|
||||
}
|
||||
else {
|
||||
return original.apply(this, window.Array.from(arguments));
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
},
|
||||
@ -314,18 +326,21 @@
|
||||
return status;
|
||||
},
|
||||
object: "CanvasRenderingContext2D",
|
||||
fakeGenerator: function(prefs, notify, window, original){
|
||||
fakeGenerator: function(checker){
|
||||
return function isPointInPath(x, y){
|
||||
var rng = randomSupply.getValueRng(1, window);
|
||||
var originalValue = original.apply(this, window.Array.from(arguments));
|
||||
if ((typeof originalValue) === "boolean"){
|
||||
notify.call(this, "fakedReadout");
|
||||
var index = x + this.width * y;
|
||||
return original.call(this, rng(x, index), rng(y, index));
|
||||
}
|
||||
else {
|
||||
return originalValue;
|
||||
}
|
||||
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||
var {prefs, notify, window, original} = check;
|
||||
var rng = randomSupply.getValueRng(1, window);
|
||||
var originalValue = original.apply(this, window.Array.from(args));
|
||||
if ((typeof originalValue) === "boolean"){
|
||||
notify.call(this, "fakedReadout");
|
||||
var index = x + this.width * y;
|
||||
return original.call(this, rng(x, index), rng(y, index));
|
||||
}
|
||||
else {
|
||||
return originalValue;
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
},
|
||||
@ -337,18 +352,21 @@
|
||||
return status;
|
||||
},
|
||||
object: "CanvasRenderingContext2D",
|
||||
fakeGenerator: function(prefs, notify, window, original){
|
||||
fakeGenerator: function(checker){
|
||||
return function isPointInStroke(x, y){
|
||||
var rng = randomSupply.getValueRng(1, window);
|
||||
var originalValue = original.apply(this, window.Array.from(arguments));
|
||||
if ((typeof originalValue) === "boolean"){
|
||||
notify.call(this, "fakedReadout");
|
||||
var index = x + this.width * y;
|
||||
return original.call(this, rng(x, index), rng(y, index));
|
||||
}
|
||||
else {
|
||||
return originalValue;
|
||||
}
|
||||
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||
var {prefs, notify, window, original} = check;
|
||||
var rng = randomSupply.getValueRng(1, window);
|
||||
var originalValue = original.apply(this, window.Array.from(args));
|
||||
if ((typeof originalValue) === "boolean"){
|
||||
notify.call(this, "fakedReadout");
|
||||
var index = x + this.width * y;
|
||||
return original.call(this, rng(x, index), rng(y, index));
|
||||
}
|
||||
else {
|
||||
return originalValue;
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
},
|
||||
@ -360,27 +378,30 @@
|
||||
return status;
|
||||
},
|
||||
object: "CanvasRenderingContext2D",
|
||||
fakeGenerator: function(prefs, notify, window, original){
|
||||
fakeGenerator: function(checker){
|
||||
return function fillText(str, x, y){
|
||||
if (!this || canvasSizeShouldBeFaked(this.canvas, prefs)){
|
||||
notify.call(this, "fakedInput");
|
||||
var oldImageData;
|
||||
try {
|
||||
// "this" is not trustable - it may be not a context
|
||||
oldImageData = getImageData(window, this).imageData;
|
||||
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||
var {prefs, notify, window, original} = check;
|
||||
if (!this || canvasSizeShouldBeFaked(this.canvas, prefs)){
|
||||
notify.call(this, "fakedInput");
|
||||
var oldImageData;
|
||||
try {
|
||||
// "this" is not trustable - it may be not a context
|
||||
oldImageData = getImageData(window, this).imageData;
|
||||
}
|
||||
catch (e){
|
||||
// nothing to do here
|
||||
}
|
||||
// if "this" is not a correct context the next line will throw an error
|
||||
var ret = original.apply(this, window.Array.from(args));
|
||||
var newImageData = getImageData(window, this).imageData;
|
||||
this.putImageData(randomMixImageData(window, oldImageData, newImageData), 0, 0);
|
||||
return ret;
|
||||
}
|
||||
catch (e){
|
||||
// nothing to do here
|
||||
else {
|
||||
return original.apply(this, window.Array.from(args));
|
||||
}
|
||||
// if "this" is not a correct context the next line will throw an error
|
||||
var ret = original.apply(this, window.Array.from(arguments));
|
||||
var newImageData = getImageData(window, this).imageData;
|
||||
this.putImageData(randomMixImageData(window, oldImageData, newImageData), 0, 0);
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
return original.apply(this, window.Array.from(arguments));
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
},
|
||||
@ -392,27 +413,30 @@
|
||||
return status;
|
||||
},
|
||||
object: "CanvasRenderingContext2D",
|
||||
fakeGenerator: function(prefs, notify, window, original){
|
||||
fakeGenerator: function(checker){
|
||||
return function strokeText(str, x, y){
|
||||
if (!this || canvasSizeShouldBeFaked(this.canvas, prefs)){
|
||||
notify.call(this, "fakedInput");
|
||||
var oldImageData;
|
||||
try {
|
||||
// "this" is not trustable - it may be not a context
|
||||
oldImageData = getImageData(window, this).imageData;
|
||||
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||
var {prefs, notify, window, original} = check;
|
||||
if (!this || canvasSizeShouldBeFaked(this.canvas, prefs)){
|
||||
notify.call(this, "fakedInput");
|
||||
var oldImageData;
|
||||
try {
|
||||
// "this" is not trustable - it may be not a context
|
||||
oldImageData = getImageData(window, this).imageData;
|
||||
}
|
||||
catch (e){
|
||||
// nothing to do here
|
||||
}
|
||||
// if "this" is not a correct context the next line will throw an error
|
||||
var ret = original.apply(this, window.Array.from(args));
|
||||
var newImageData = getImageData(window, this).imageData;
|
||||
this.putImageData(randomMixImageData(window, oldImageData, newImageData), 0, 0);
|
||||
return ret;
|
||||
}
|
||||
catch (e){
|
||||
// nothing to do here
|
||||
else {
|
||||
return original.apply(this, window.Array.from(args));
|
||||
}
|
||||
// if "this" is not a correct context the next line will throw an error
|
||||
var ret = original.apply(this, window.Array.from(arguments));
|
||||
var newImageData = getImageData(window, this).imageData;
|
||||
this.putImageData(randomMixImageData(window, oldImageData, newImageData), 0, 0);
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
return original.apply(this, window.Array.from(arguments));
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
},
|
||||
@ -424,21 +448,24 @@
|
||||
return status;
|
||||
},
|
||||
object: ["WebGLRenderingContext", "WebGL2RenderingContext"],
|
||||
fakeGenerator: function(prefs, notify, window, original){
|
||||
fakeGenerator: function(checker){
|
||||
return function readPixels(x, y, width, height, format, type, pixels){ // eslint-disable-line max-params
|
||||
if (!this || canvasSizeShouldBeFaked(this.canvas, prefs)){
|
||||
notify.call(this, "fakedReadout");
|
||||
var fakeCanvas = getFakeCanvas(window, this.canvas, prefs);
|
||||
var {context} = copyCanvasToWebgl(
|
||||
window,
|
||||
fakeCanvas,
|
||||
this instanceof window.WebGLRenderingContext? "webgl": "webgl2"
|
||||
);
|
||||
return original.apply(context, window.Array.from(arguments));
|
||||
}
|
||||
else {
|
||||
return original.apply(this, window.Array.from(arguments));
|
||||
}
|
||||
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||
var {prefs, notify, window, original} = check;
|
||||
if (!this || canvasSizeShouldBeFaked(this.canvas, prefs)){
|
||||
notify.call(this, "fakedReadout");
|
||||
var fakeCanvas = getFakeCanvas(window, this.canvas, prefs);
|
||||
var {context} = copyCanvasToWebgl(
|
||||
window,
|
||||
fakeCanvas,
|
||||
this instanceof window.WebGLRenderingContext? "webgl": "webgl2"
|
||||
);
|
||||
return original.apply(context, window.Array.from(args));
|
||||
}
|
||||
else {
|
||||
return original.apply(this, window.Array.from(args));
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -446,7 +473,17 @@
|
||||
Object.keys(scope.changedFunctions).forEach(function(key){
|
||||
scope.changedFunctions[key].api = "canvas";
|
||||
});
|
||||
Object.keys(modifiedAudioAPI.changedFunctions).forEach(function(key){
|
||||
scope.changedFunctions[key] = modifiedAudioAPI.changedFunctions[key];
|
||||
});
|
||||
|
||||
scope.changedGetters = {};
|
||||
|
||||
function appendModified(collection){
|
||||
Object.keys(collection.changedFunctions || {}).forEach(function(key){
|
||||
scope.changedFunctions[key] = collection.changedFunctions[key];
|
||||
});
|
||||
|
||||
Object.keys(collection.changedGetters || {}).forEach(function(key){
|
||||
scope.changedGetters[key] = collection.changedGetters[key];
|
||||
});
|
||||
}
|
||||
appendModified(modifiedAudioAPI);
|
||||
}());
|
32
lib/modifiedAPIFunctions.js
Normal file
32
lib/modifiedAPIFunctions.js
Normal file
@ -0,0 +1,32 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
(function(){
|
||||
"use strict";
|
||||
|
||||
var scope;
|
||||
if ((typeof exports) !== "undefined"){
|
||||
scope = exports;
|
||||
}
|
||||
else {
|
||||
window.scope.modifiedAPIFunctions = {};
|
||||
scope = window.scope.modifiedAPIFunctions;
|
||||
}
|
||||
|
||||
|
||||
|
||||
scope.hasType = function hasType(status, type){
|
||||
return status.type.indexOf(type) !== -1;
|
||||
};
|
||||
|
||||
scope.checkerWrapper = function checkerWrapper(checker, object, args, callback){
|
||||
const check = checker();
|
||||
if (check.allow){
|
||||
if (check.allow === true){
|
||||
return check.original.apply(object, check.window.Array.from(args));
|
||||
}
|
||||
return callback.call(object, args, check);
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
}());
|
@ -16,6 +16,7 @@
|
||||
const logging = require("./logging");
|
||||
const {sha256String: hashing} = require("./hash");
|
||||
const getWrapped = require("sdk/getWrapped");
|
||||
const {hasType, checkerWrapper} = require("./modifiedAPIFunctions");
|
||||
|
||||
var randomSupply = null;
|
||||
|
||||
@ -143,10 +144,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
function hasType(status, type){
|
||||
return status.type.indexOf(type) !== -1;
|
||||
}
|
||||
|
||||
scope.setRandomSupply = function(supply){
|
||||
randomSupply = supply;
|
||||
};
|
||||
@ -168,79 +165,100 @@
|
||||
scope.changedFunctions = {
|
||||
getFloatFrequencyData: {
|
||||
object: ["AnalyserNode"],
|
||||
fakeGenerator: function(prefs, notify, window, original){
|
||||
fakeGenerator: function(checker){
|
||||
return function getFloatFrequencyData(array){
|
||||
notifyOnce("getFloatFrequencyData", notify);
|
||||
var ret = original.apply(this, window.Array.from(arguments));
|
||||
fakeFloat32Array(array, window, prefs);
|
||||
return ret;
|
||||
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||
var {prefs, notify, window, original} = check;
|
||||
notifyOnce("getFloatFrequencyData", notify);
|
||||
var ret = original.apply(this, window.Array.from(args));
|
||||
fakeFloat32Array(array, window, prefs);
|
||||
return ret;
|
||||
});
|
||||
};
|
||||
}
|
||||
},
|
||||
getByteFrequencyData: {
|
||||
object: ["AnalyserNode"],
|
||||
fakeGenerator: function(prefs, notify, window, original){
|
||||
fakeGenerator: function(checker){
|
||||
return function getByteFrequencyData(array){
|
||||
notifyOnce("getByteFrequencyData", notify);
|
||||
var ret = original.apply(this, window.Array.from(arguments));
|
||||
fakeUint8Array(array, window, prefs);
|
||||
return ret;
|
||||
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||
var {prefs, notify, window, original} = check;
|
||||
notifyOnce("getByteFrequencyData", notify);
|
||||
var ret = original.apply(this, window.Array.from(args));
|
||||
fakeUint8Array(array, window, prefs);
|
||||
return ret;
|
||||
});
|
||||
};
|
||||
}
|
||||
},
|
||||
getFloatTimeDomainData: {
|
||||
object: ["AnalyserNode"],
|
||||
fakeGenerator: function(prefs, notify, window, original){
|
||||
fakeGenerator: function(checker){
|
||||
return function getFloatTimeDomainData(array){
|
||||
notifyOnce("getFloatTimeDomainData", notify);
|
||||
var ret = original.apply(this, window.Array.from(arguments));
|
||||
fakeFloat32Array(array, window, prefs);
|
||||
return ret;
|
||||
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||
var {prefs, notify, window, original} = check;
|
||||
notifyOnce("getFloatTimeDomainData", notify);
|
||||
var ret = original.apply(this, window.Array.from(args));
|
||||
fakeFloat32Array(array, window, prefs);
|
||||
return ret;
|
||||
});
|
||||
};
|
||||
}
|
||||
},
|
||||
getByteTimeDomainData: {
|
||||
object: ["AnalyserNode"],
|
||||
fakeGenerator: function(prefs, notify, window, original){
|
||||
fakeGenerator: function(checker){
|
||||
return function getByteTimeDomainData(array){
|
||||
notifyOnce("getByteTimeDomainData", notify);
|
||||
var ret = original.apply(this, window.Array.from(arguments));
|
||||
fakeUint8Array(array, window, prefs);
|
||||
return ret;
|
||||
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||
var {prefs, notify, window, original} = check;
|
||||
notifyOnce("getByteTimeDomainData", notify);
|
||||
var ret = original.apply(this, window.Array.from(args));
|
||||
fakeUint8Array(array, window, prefs);
|
||||
return ret;
|
||||
});
|
||||
};
|
||||
}
|
||||
},
|
||||
getChannelData: {
|
||||
object: ["AudioBuffer"],
|
||||
fakeGenerator: function(prefs, notify, window, original){
|
||||
fakeGenerator: function(checker){
|
||||
return function getChannelData(channel){
|
||||
notifyOnce("getChannelData", notify);
|
||||
var ret = original.apply(this, window.Array.from(arguments));
|
||||
fakeFloat32Array(ret, window, prefs);
|
||||
return ret;
|
||||
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||
var {prefs, notify, window, original} = check;
|
||||
notifyOnce("getChannelData", notify);
|
||||
var ret = original.apply(this, window.Array.from(args));
|
||||
fakeFloat32Array(ret, window, prefs);
|
||||
return ret;
|
||||
});
|
||||
};
|
||||
}
|
||||
},
|
||||
copyFromChannel: {
|
||||
object: ["AudioBuffer"],
|
||||
fakeGenerator: function(prefs, notify, window, original){
|
||||
fakeGenerator: function(checker){
|
||||
return function copyFromChannel(destination, channelNumber, startInChannel){
|
||||
notifyOnce("copyFromChannel", notify);
|
||||
var ret = original.apply(this, window.Array.from(arguments));
|
||||
fakeFloat32Array(destination, window, prefs);
|
||||
return ret;
|
||||
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||
var {prefs, notify, window, original} = check;
|
||||
notifyOnce("copyFromChannel", notify);
|
||||
var ret = original.apply(this, window.Array.from(args));
|
||||
fakeFloat32Array(destination, window, prefs);
|
||||
return ret;
|
||||
});
|
||||
};
|
||||
}
|
||||
},
|
||||
getFrequencyResponse: {
|
||||
object: ["BiquadFilterNode", "IIRFilterNode"],
|
||||
fakeGenerator: function(prefs, notify, window, original){
|
||||
fakeGenerator: function(checker){
|
||||
return function getFrequencyResponse(frequencyArray, magResponseOutput, phaseResponseOutput){
|
||||
notifyOnce("getFrequencyResponse", notify);
|
||||
var ret = original.apply(this, window.Array.from(arguments));
|
||||
fakeFloat32Array(magResponseOutput, window, prefs);
|
||||
fakeFloat32Array(phaseResponseOutput, window, prefs);
|
||||
return ret;
|
||||
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||
var {prefs, notify, window, original} = check;
|
||||
notifyOnce("getFrequencyResponse", notify);
|
||||
var ret = original.apply(this, window.Array.from(args));
|
||||
fakeFloat32Array(magResponseOutput, window, prefs);
|
||||
fakeFloat32Array(phaseResponseOutput, window, prefs);
|
||||
return ret;
|
||||
});
|
||||
};
|
||||
}
|
||||
},
|
||||
|
@ -32,6 +32,7 @@
|
||||
"lib/colorStatistics.js",
|
||||
"lib/webgl.js",
|
||||
"lib/hash.js",
|
||||
"lib/modifiedAPIFunctions.js",
|
||||
"lib/modifiedAudioAPI.js",
|
||||
"lib/modifiedAPI.js",
|
||||
"lib/randomSupplies.js",
|
||||
|
@ -8,7 +8,7 @@ Version 0.4.6:
|
||||
- Settings can be hidden
|
||||
|
||||
fixes:
|
||||
-
|
||||
- make function replacements not detectable
|
||||
|
||||
Version 0.4.5c:
|
||||
new features:
|
||||
|
Loading…
x
Reference in New Issue
Block a user