mirror of
https://github.com/kkapsner/CanvasBlocker
synced 2025-04-18 08:08:28 +02:00
parent
9711c67c3f
commit
26529a3653
228
lib/intercept.js
228
lib/intercept.js
@ -158,9 +158,107 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let extensionID = browser.extension.getURL("");
|
let extensionID = browser.extension.getURL("");
|
||||||
scope.intercept = function intercept({subject: window}, {check, checkStack, ask, notify, prefs}){
|
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)});
|
var siteStatus = check({url: getURL(window)});
|
||||||
logging.verbose("status for page", window, siteStatus);
|
logging.verbose("status for page", window, siteStatus);
|
||||||
if (siteStatus.mode !== "allow"){
|
if (siteStatus.mode !== "allow"){
|
||||||
@ -177,117 +275,25 @@
|
|||||||
var constructor = getWrapped(window)[object];
|
var constructor = getWrapped(window)[object];
|
||||||
if (constructor){
|
if (constructor){
|
||||||
var original = constructor.prototype[name];
|
var original = constructor.prototype[name];
|
||||||
|
const checker = generateChecker(name, changedFunction, siteStatus, original);
|
||||||
Object.defineProperty(
|
var descriptor = Object.getOwnPropertyDescriptor(constructor.prototype, name);
|
||||||
constructor.prototype,
|
if (descriptor.hasOwnProperty("value")){
|
||||||
name,
|
if (changedFunction.fakeGenerator){
|
||||||
{
|
descriptor.value = exportFunction(
|
||||||
enumerable: true,
|
changedFunction.fakeGenerator(checker),
|
||||||
configureable: true,
|
window
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
);
|
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 logging = require("./logging");
|
||||||
const {copyCanvasToWebgl} = require("./webgl");
|
const {copyCanvasToWebgl} = require("./webgl");
|
||||||
const getWrapped = require("sdk/getWrapped");
|
const getWrapped = require("sdk/getWrapped");
|
||||||
|
const {hasType, checkerWrapper} = require("./modifiedAPIFunctions");
|
||||||
const modifiedAudioAPI = require("./modifiedAudioAPI");
|
const modifiedAudioAPI = require("./modifiedAudioAPI");
|
||||||
|
|
||||||
var randomSupply = null;
|
var randomSupply = null;
|
||||||
@ -151,10 +152,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasType(status, type){
|
|
||||||
return status.type.indexOf(type) !== -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
scope.setRandomSupply = function(supply){
|
scope.setRandomSupply = function(supply){
|
||||||
randomSupply = supply;
|
randomSupply = supply;
|
||||||
modifiedAudioAPI.setRandomSupply(supply);
|
modifiedAudioAPI.setRandomSupply(supply);
|
||||||
@ -186,10 +183,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
object: "HTMLCanvasElement",
|
object: "HTMLCanvasElement",
|
||||||
fakeGenerator: function(prefs, notify, window, original){
|
fakeGenerator: function(checker){
|
||||||
return function(context, contextAttributes){
|
return function(context, contextAttributes){
|
||||||
canvasContextType.set(this, context);
|
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||||
return original.apply(this, window.Array.from(arguments));
|
var {prefs, notify, window, original} = check;
|
||||||
|
canvasContextType.set(this, context);
|
||||||
|
return original.apply(this, window.Array.from(args));
|
||||||
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -205,18 +205,21 @@
|
|||||||
return status;
|
return status;
|
||||||
},
|
},
|
||||||
object: "HTMLCanvasElement",
|
object: "HTMLCanvasElement",
|
||||||
fakeGenerator: function(prefs, notify, window, original){
|
fakeGenerator: function(checker){
|
||||||
return function toDataURL(){
|
return function toDataURL(){
|
||||||
if (canvasSizeShouldBeFaked(this, prefs)){
|
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||||
var fakeCanvas = getFakeCanvas(window, this, prefs);
|
var {prefs, notify, window, original} = check;
|
||||||
if (fakeCanvas !== this){
|
if (canvasSizeShouldBeFaked(this, prefs)){
|
||||||
notify.call(this, "fakedReadout");
|
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(args));
|
||||||
else {
|
}
|
||||||
return original.apply(this, window.Array.from(arguments));
|
});
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -232,18 +235,21 @@
|
|||||||
return status;
|
return status;
|
||||||
},
|
},
|
||||||
object: "HTMLCanvasElement",
|
object: "HTMLCanvasElement",
|
||||||
fakeGenerator: function(prefs, notify, window, original){
|
fakeGenerator: function(checker){
|
||||||
return function toBlob(callback){
|
return function toBlob(callback){
|
||||||
if (canvasSizeShouldBeFaked(this, prefs)){
|
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||||
var fakeCanvas = getFakeCanvas(window, this, prefs);
|
var {prefs, notify, window, original} = check;
|
||||||
if (fakeCanvas !== this){
|
if (canvasSizeShouldBeFaked(this, prefs)){
|
||||||
notify.call(this, "fakedReadout");
|
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(args));
|
||||||
else {
|
}
|
||||||
return original.apply(this, window.Array.from(arguments));
|
});
|
||||||
}
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
exportOptions: {allowCallbacks: true}
|
exportOptions: {allowCallbacks: true}
|
||||||
@ -260,18 +266,21 @@
|
|||||||
return status;
|
return status;
|
||||||
},
|
},
|
||||||
object: "HTMLCanvasElement",
|
object: "HTMLCanvasElement",
|
||||||
fakeGenerator: function(prefs, notify, window, original){
|
fakeGenerator: function(checker){
|
||||||
return function mozGetAsFile(callback){
|
return function mozGetAsFile(callback){
|
||||||
if (canvasSizeShouldBeFaked(this, prefs)){
|
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||||
var fakeCanvas = getFakeCanvas(window, this, prefs);
|
var {prefs, notify, window, original} = check;
|
||||||
if (fakeCanvas !== this){
|
if (canvasSizeShouldBeFaked(this, prefs)){
|
||||||
notify.call(this, "fakedReadout");
|
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(args));
|
||||||
else {
|
}
|
||||||
return original.apply(this, window.Array.from(arguments));
|
});
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -283,26 +292,29 @@
|
|||||||
return status;
|
return status;
|
||||||
},
|
},
|
||||||
object: "CanvasRenderingContext2D",
|
object: "CanvasRenderingContext2D",
|
||||||
fakeGenerator: function(prefs, notify, window, original){
|
fakeGenerator: function(checker){
|
||||||
return function getImageData(sx, sy, sw, sh){
|
return function getImageData(sx, sy, sw, sh){
|
||||||
if (!this || canvasSizeShouldBeFaked(this.canvas, prefs)){
|
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||||
var fakeCanvas;
|
var {prefs, notify, window, original} = check;
|
||||||
var context = this;
|
if (!this || canvasSizeShouldBeFaked(this.canvas, prefs)){
|
||||||
if (this && this.canvas) {
|
var fakeCanvas;
|
||||||
fakeCanvas = getFakeCanvas(window, this.canvas, prefs);
|
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){
|
else {
|
||||||
notify.call(this, "fakedReadout");
|
return original.apply(this, window.Array.from(args));
|
||||||
context = window.HTMLCanvasElement.prototype.getContext.call(
|
|
||||||
fakeCanvas,
|
|
||||||
"2d"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return original.apply(context, window.Array.from(arguments));
|
});
|
||||||
}
|
|
||||||
else {
|
|
||||||
return original.apply(this, window.Array.from(arguments));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -314,18 +326,21 @@
|
|||||||
return status;
|
return status;
|
||||||
},
|
},
|
||||||
object: "CanvasRenderingContext2D",
|
object: "CanvasRenderingContext2D",
|
||||||
fakeGenerator: function(prefs, notify, window, original){
|
fakeGenerator: function(checker){
|
||||||
return function isPointInPath(x, y){
|
return function isPointInPath(x, y){
|
||||||
var rng = randomSupply.getValueRng(1, window);
|
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||||
var originalValue = original.apply(this, window.Array.from(arguments));
|
var {prefs, notify, window, original} = check;
|
||||||
if ((typeof originalValue) === "boolean"){
|
var rng = randomSupply.getValueRng(1, window);
|
||||||
notify.call(this, "fakedReadout");
|
var originalValue = original.apply(this, window.Array.from(args));
|
||||||
var index = x + this.width * y;
|
if ((typeof originalValue) === "boolean"){
|
||||||
return original.call(this, rng(x, index), rng(y, index));
|
notify.call(this, "fakedReadout");
|
||||||
}
|
var index = x + this.width * y;
|
||||||
else {
|
return original.call(this, rng(x, index), rng(y, index));
|
||||||
return originalValue;
|
}
|
||||||
}
|
else {
|
||||||
|
return originalValue;
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -337,18 +352,21 @@
|
|||||||
return status;
|
return status;
|
||||||
},
|
},
|
||||||
object: "CanvasRenderingContext2D",
|
object: "CanvasRenderingContext2D",
|
||||||
fakeGenerator: function(prefs, notify, window, original){
|
fakeGenerator: function(checker){
|
||||||
return function isPointInStroke(x, y){
|
return function isPointInStroke(x, y){
|
||||||
var rng = randomSupply.getValueRng(1, window);
|
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||||
var originalValue = original.apply(this, window.Array.from(arguments));
|
var {prefs, notify, window, original} = check;
|
||||||
if ((typeof originalValue) === "boolean"){
|
var rng = randomSupply.getValueRng(1, window);
|
||||||
notify.call(this, "fakedReadout");
|
var originalValue = original.apply(this, window.Array.from(args));
|
||||||
var index = x + this.width * y;
|
if ((typeof originalValue) === "boolean"){
|
||||||
return original.call(this, rng(x, index), rng(y, index));
|
notify.call(this, "fakedReadout");
|
||||||
}
|
var index = x + this.width * y;
|
||||||
else {
|
return original.call(this, rng(x, index), rng(y, index));
|
||||||
return originalValue;
|
}
|
||||||
}
|
else {
|
||||||
|
return originalValue;
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -360,27 +378,30 @@
|
|||||||
return status;
|
return status;
|
||||||
},
|
},
|
||||||
object: "CanvasRenderingContext2D",
|
object: "CanvasRenderingContext2D",
|
||||||
fakeGenerator: function(prefs, notify, window, original){
|
fakeGenerator: function(checker){
|
||||||
return function fillText(str, x, y){
|
return function fillText(str, x, y){
|
||||||
if (!this || canvasSizeShouldBeFaked(this.canvas, prefs)){
|
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||||
notify.call(this, "fakedInput");
|
var {prefs, notify, window, original} = check;
|
||||||
var oldImageData;
|
if (!this || canvasSizeShouldBeFaked(this.canvas, prefs)){
|
||||||
try {
|
notify.call(this, "fakedInput");
|
||||||
// "this" is not trustable - it may be not a context
|
var oldImageData;
|
||||||
oldImageData = getImageData(window, this).imageData;
|
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){
|
else {
|
||||||
// nothing to do here
|
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;
|
return status;
|
||||||
},
|
},
|
||||||
object: "CanvasRenderingContext2D",
|
object: "CanvasRenderingContext2D",
|
||||||
fakeGenerator: function(prefs, notify, window, original){
|
fakeGenerator: function(checker){
|
||||||
return function strokeText(str, x, y){
|
return function strokeText(str, x, y){
|
||||||
if (!this || canvasSizeShouldBeFaked(this.canvas, prefs)){
|
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||||
notify.call(this, "fakedInput");
|
var {prefs, notify, window, original} = check;
|
||||||
var oldImageData;
|
if (!this || canvasSizeShouldBeFaked(this.canvas, prefs)){
|
||||||
try {
|
notify.call(this, "fakedInput");
|
||||||
// "this" is not trustable - it may be not a context
|
var oldImageData;
|
||||||
oldImageData = getImageData(window, this).imageData;
|
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){
|
else {
|
||||||
// nothing to do here
|
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;
|
return status;
|
||||||
},
|
},
|
||||||
object: ["WebGLRenderingContext", "WebGL2RenderingContext"],
|
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
|
return function readPixels(x, y, width, height, format, type, pixels){ // eslint-disable-line max-params
|
||||||
if (!this || canvasSizeShouldBeFaked(this.canvas, prefs)){
|
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||||
notify.call(this, "fakedReadout");
|
var {prefs, notify, window, original} = check;
|
||||||
var fakeCanvas = getFakeCanvas(window, this.canvas, prefs);
|
if (!this || canvasSizeShouldBeFaked(this.canvas, prefs)){
|
||||||
var {context} = copyCanvasToWebgl(
|
notify.call(this, "fakedReadout");
|
||||||
window,
|
var fakeCanvas = getFakeCanvas(window, this.canvas, prefs);
|
||||||
fakeCanvas,
|
var {context} = copyCanvasToWebgl(
|
||||||
this instanceof window.WebGLRenderingContext? "webgl": "webgl2"
|
window,
|
||||||
);
|
fakeCanvas,
|
||||||
return original.apply(context, window.Array.from(arguments));
|
this instanceof window.WebGLRenderingContext? "webgl": "webgl2"
|
||||||
}
|
);
|
||||||
else {
|
return original.apply(context, window.Array.from(args));
|
||||||
return original.apply(this, window.Array.from(arguments));
|
}
|
||||||
}
|
else {
|
||||||
|
return original.apply(this, window.Array.from(args));
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -446,7 +473,17 @@
|
|||||||
Object.keys(scope.changedFunctions).forEach(function(key){
|
Object.keys(scope.changedFunctions).forEach(function(key){
|
||||||
scope.changedFunctions[key].api = "canvas";
|
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 logging = require("./logging");
|
||||||
const {sha256String: hashing} = require("./hash");
|
const {sha256String: hashing} = require("./hash");
|
||||||
const getWrapped = require("sdk/getWrapped");
|
const getWrapped = require("sdk/getWrapped");
|
||||||
|
const {hasType, checkerWrapper} = require("./modifiedAPIFunctions");
|
||||||
|
|
||||||
var randomSupply = null;
|
var randomSupply = null;
|
||||||
|
|
||||||
@ -143,10 +144,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasType(status, type){
|
|
||||||
return status.type.indexOf(type) !== -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
scope.setRandomSupply = function(supply){
|
scope.setRandomSupply = function(supply){
|
||||||
randomSupply = supply;
|
randomSupply = supply;
|
||||||
};
|
};
|
||||||
@ -168,79 +165,100 @@
|
|||||||
scope.changedFunctions = {
|
scope.changedFunctions = {
|
||||||
getFloatFrequencyData: {
|
getFloatFrequencyData: {
|
||||||
object: ["AnalyserNode"],
|
object: ["AnalyserNode"],
|
||||||
fakeGenerator: function(prefs, notify, window, original){
|
fakeGenerator: function(checker){
|
||||||
return function getFloatFrequencyData(array){
|
return function getFloatFrequencyData(array){
|
||||||
notifyOnce("getFloatFrequencyData", notify);
|
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||||
var ret = original.apply(this, window.Array.from(arguments));
|
var {prefs, notify, window, original} = check;
|
||||||
fakeFloat32Array(array, window, prefs);
|
notifyOnce("getFloatFrequencyData", notify);
|
||||||
return ret;
|
var ret = original.apply(this, window.Array.from(args));
|
||||||
|
fakeFloat32Array(array, window, prefs);
|
||||||
|
return ret;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getByteFrequencyData: {
|
getByteFrequencyData: {
|
||||||
object: ["AnalyserNode"],
|
object: ["AnalyserNode"],
|
||||||
fakeGenerator: function(prefs, notify, window, original){
|
fakeGenerator: function(checker){
|
||||||
return function getByteFrequencyData(array){
|
return function getByteFrequencyData(array){
|
||||||
notifyOnce("getByteFrequencyData", notify);
|
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||||
var ret = original.apply(this, window.Array.from(arguments));
|
var {prefs, notify, window, original} = check;
|
||||||
fakeUint8Array(array, window, prefs);
|
notifyOnce("getByteFrequencyData", notify);
|
||||||
return ret;
|
var ret = original.apply(this, window.Array.from(args));
|
||||||
|
fakeUint8Array(array, window, prefs);
|
||||||
|
return ret;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getFloatTimeDomainData: {
|
getFloatTimeDomainData: {
|
||||||
object: ["AnalyserNode"],
|
object: ["AnalyserNode"],
|
||||||
fakeGenerator: function(prefs, notify, window, original){
|
fakeGenerator: function(checker){
|
||||||
return function getFloatTimeDomainData(array){
|
return function getFloatTimeDomainData(array){
|
||||||
notifyOnce("getFloatTimeDomainData", notify);
|
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||||
var ret = original.apply(this, window.Array.from(arguments));
|
var {prefs, notify, window, original} = check;
|
||||||
fakeFloat32Array(array, window, prefs);
|
notifyOnce("getFloatTimeDomainData", notify);
|
||||||
return ret;
|
var ret = original.apply(this, window.Array.from(args));
|
||||||
|
fakeFloat32Array(array, window, prefs);
|
||||||
|
return ret;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getByteTimeDomainData: {
|
getByteTimeDomainData: {
|
||||||
object: ["AnalyserNode"],
|
object: ["AnalyserNode"],
|
||||||
fakeGenerator: function(prefs, notify, window, original){
|
fakeGenerator: function(checker){
|
||||||
return function getByteTimeDomainData(array){
|
return function getByteTimeDomainData(array){
|
||||||
notifyOnce("getByteTimeDomainData", notify);
|
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||||
var ret = original.apply(this, window.Array.from(arguments));
|
var {prefs, notify, window, original} = check;
|
||||||
fakeUint8Array(array, window, prefs);
|
notifyOnce("getByteTimeDomainData", notify);
|
||||||
return ret;
|
var ret = original.apply(this, window.Array.from(args));
|
||||||
|
fakeUint8Array(array, window, prefs);
|
||||||
|
return ret;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getChannelData: {
|
getChannelData: {
|
||||||
object: ["AudioBuffer"],
|
object: ["AudioBuffer"],
|
||||||
fakeGenerator: function(prefs, notify, window, original){
|
fakeGenerator: function(checker){
|
||||||
return function getChannelData(channel){
|
return function getChannelData(channel){
|
||||||
notifyOnce("getChannelData", notify);
|
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||||
var ret = original.apply(this, window.Array.from(arguments));
|
var {prefs, notify, window, original} = check;
|
||||||
fakeFloat32Array(ret, window, prefs);
|
notifyOnce("getChannelData", notify);
|
||||||
return ret;
|
var ret = original.apply(this, window.Array.from(args));
|
||||||
|
fakeFloat32Array(ret, window, prefs);
|
||||||
|
return ret;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
copyFromChannel: {
|
copyFromChannel: {
|
||||||
object: ["AudioBuffer"],
|
object: ["AudioBuffer"],
|
||||||
fakeGenerator: function(prefs, notify, window, original){
|
fakeGenerator: function(checker){
|
||||||
return function copyFromChannel(destination, channelNumber, startInChannel){
|
return function copyFromChannel(destination, channelNumber, startInChannel){
|
||||||
notifyOnce("copyFromChannel", notify);
|
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||||
var ret = original.apply(this, window.Array.from(arguments));
|
var {prefs, notify, window, original} = check;
|
||||||
fakeFloat32Array(destination, window, prefs);
|
notifyOnce("copyFromChannel", notify);
|
||||||
return ret;
|
var ret = original.apply(this, window.Array.from(args));
|
||||||
|
fakeFloat32Array(destination, window, prefs);
|
||||||
|
return ret;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getFrequencyResponse: {
|
getFrequencyResponse: {
|
||||||
object: ["BiquadFilterNode", "IIRFilterNode"],
|
object: ["BiquadFilterNode", "IIRFilterNode"],
|
||||||
fakeGenerator: function(prefs, notify, window, original){
|
fakeGenerator: function(checker){
|
||||||
return function getFrequencyResponse(frequencyArray, magResponseOutput, phaseResponseOutput){
|
return function getFrequencyResponse(frequencyArray, magResponseOutput, phaseResponseOutput){
|
||||||
notifyOnce("getFrequencyResponse", notify);
|
return checkerWrapper(checker, this, arguments, function(args, check){
|
||||||
var ret = original.apply(this, window.Array.from(arguments));
|
var {prefs, notify, window, original} = check;
|
||||||
fakeFloat32Array(magResponseOutput, window, prefs);
|
notifyOnce("getFrequencyResponse", notify);
|
||||||
fakeFloat32Array(phaseResponseOutput, window, prefs);
|
var ret = original.apply(this, window.Array.from(args));
|
||||||
return ret;
|
fakeFloat32Array(magResponseOutput, window, prefs);
|
||||||
|
fakeFloat32Array(phaseResponseOutput, window, prefs);
|
||||||
|
return ret;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
"lib/colorStatistics.js",
|
"lib/colorStatistics.js",
|
||||||
"lib/webgl.js",
|
"lib/webgl.js",
|
||||||
"lib/hash.js",
|
"lib/hash.js",
|
||||||
|
"lib/modifiedAPIFunctions.js",
|
||||||
"lib/modifiedAudioAPI.js",
|
"lib/modifiedAudioAPI.js",
|
||||||
"lib/modifiedAPI.js",
|
"lib/modifiedAPI.js",
|
||||||
"lib/randomSupplies.js",
|
"lib/randomSupplies.js",
|
||||||
|
@ -8,7 +8,7 @@ Version 0.4.6:
|
|||||||
- Settings can be hidden
|
- Settings can be hidden
|
||||||
|
|
||||||
fixes:
|
fixes:
|
||||||
-
|
- make function replacements not detectable
|
||||||
|
|
||||||
Version 0.4.5c:
|
Version 0.4.5c:
|
||||||
new features:
|
new features:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user