diff --git a/_locales/de/messages.json b/_locales/de/messages.json index 33dbd9e..e72bac5 100644 --- a/_locales/de/messages.json +++ b/_locales/de/messages.json @@ -114,6 +114,15 @@ "description": "" }, + "minFakeSize_description": { + "message": "Canvas, die eine kleiner oder gleich große Fläche als die hier angegebene Zahl haben, werden nicht vorgetäuscht. Dies ist ein parameter, der die Detektion des Addons erschweren soll.\nACHTUNG: Dies verringert die Sicherheit des Addons. Deswegen wird stark empfohlen, diesen Wert nicht unter 100 zu setzen.", + "description": "" + }, + "minFakeSize_title": { + "message": "Minimale Vortäuschgröße", + "description": "" + }, + "maxFakeSize_description": { "message": "Canvas, die eine größere Fläche als die hier angegebene Zahl haben, werden nicht vorgetäuscht. (Null eingeben, um es zu deaktivieren.) Dies ist ein Leistungsparameter, der das Einfrieren des Browsers verringern kann und der an die Rechenleistung des Gerätes angepasst sein soll.\nACHTUNG: Dies verringert die Sicherheit des Addons. Deswegen wird stark empfohlen, diesen Wert nicht unter 100 000 zu setzen.", "description": "" diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 2dc45b1..eea8f2b 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -114,6 +114,15 @@ "description": "" }, + "minFakeSize_description": { + "message": "Canvas with a smaller or equal area than this number will not be faked. This is a parameter to prevent detection.\nCAUTION: This lowers the safety of the addon, therefore it is highly recommended not to set this value above 100.", + "description": "" + }, + "minFakeSize_title": { + "message": "Minimal fake size", + "description": "" + }, + "maxFakeSize_description": { "message": "Canvas with a bigger area than this number will not be faked. (Enter zero to disable.) This is a performance parameter that can prevent browser freezes and should be adjusted to the computing power of the device.\nCAUTION: This lowers the safety of the addon, therefore it is highly recommended not to set this value below 100 000.", "description": "" diff --git a/lib/defaultSettings.js b/lib/defaultSettings.js index 5b52e0b..c459d48 100644 --- a/lib/defaultSettings.js +++ b/lib/defaultSettings.js @@ -4,6 +4,7 @@ var settings = { whiteList: "", blackList: "", blockMode: "fakeReadout", + minFakeSize: 1, maxFakeSize: 0, rng: "nonPersistent", persistentRndStorage: "", diff --git a/lib/modifiedAPI.js b/lib/modifiedAPI.js index 5d9935d..ec246c8 100644 --- a/lib/modifiedAPI.js +++ b/lib/modifiedAPI.js @@ -92,6 +92,18 @@ return imageData2; } + function canvasSizeShouldBeFaked(canvas, prefs){ + if (canvas){ + var size = canvas.height * canvas.width; + var maxSize = prefs("maxFakeSize") || Number.POSITIVE_INFINITY; + var minSize = prefs("minFakeSize") || 0; + return size > minSize & size <= maxSize; + } + else { + return true + } + } + function hasType(status, type){ return status.type.indexOf(type) !== -1; } @@ -149,8 +161,13 @@ object: "HTMLCanvasElement", fakeGenerator: function(prefs, notify, window, original){ return function toDataURL(){ - notify.call(this, "fakedReadout"); - return original.apply(getFakeCanvas(window, this), window.Array.from(arguments)); + if (canvasSizeShouldBeFaked(this, prefs)){ + notify.call(this, "fakedReadout"); + return original.apply(getFakeCanvas(window, this), window.Array.from(arguments)); + } + else { + return original.apply(this, window.Array.from(arguments)); + } }; } }, @@ -170,8 +187,13 @@ object: "HTMLCanvasElement", fakeGenerator: function(prefs, notify, window, original){ return function toBlob(callback){ - notify.call(this, "fakedReadout"); - return original.apply(getFakeCanvas(window, this), window.Array.from(arguments)); + if (canvasSizeShouldBeFaked(this, prefs)){ + notify.call(this, "fakedReadout"); + return original.apply(getFakeCanvas(window, this), window.Array.from(arguments)); + } + else { + return original.apply(this, window.Array.from(arguments)); + } }; }, exportOptions: {allowCallbacks: true} @@ -192,8 +214,13 @@ object: "HTMLCanvasElement", fakeGenerator: function(prefs, notify, window, original){ return function mozGetAsFile(callback){ - notify.call(this, "fakedReadout"); - return original.apply(getFakeCanvas(window, this), window.Array.from(arguments)); + if (canvasSizeShouldBeFaked(this, prefs)){ + notify.call(this, "fakedReadout"); + return original.apply(getFakeCanvas(window, this), window.Array.from(arguments)); + } + else { + return original.apply(this, window.Array.from(arguments)); + } }; } }, @@ -212,12 +239,8 @@ }, object: "CanvasRenderingContext2D", fakeGenerator: function(prefs, notify, window, original){ - var maxSize = prefs("maxFakeSize") || Number.POSITIVE_INFINITY; return function getImageData(sx, sy, sw, sh){ - if (sw * sh > maxSize){ - return original.apply(this, window.Array.from(arguments)); - } - else { + if (!this || canvasSizeShouldBeFaked(this.canvas, prefs)){ notify.call(this, "fakedReadout"); var fakeCanvas; var context = this; @@ -232,6 +255,9 @@ } return original.apply(context, window.Array.from(arguments)); } + else { + return original.apply(this, window.Array.from(arguments)); + } }; } }, @@ -245,18 +271,23 @@ object: "CanvasRenderingContext2D", fakeGenerator: function(prefs, notify, window, original){ return function fillText(str, x, y){ - notify.call(this, "fakedInput"); - var oldImageData; - try { - // "this" is not trustable - it may be not a context - oldImageData = getImageData(window, this).imageData; + 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){} + // 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)); } - catch (e){} - // 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; }; } }, @@ -270,18 +301,23 @@ object: "CanvasRenderingContext2D", fakeGenerator: function(prefs, notify, window, original){ return function strokeText(str, x, y){ - notify.call(this, "fakedInput"); - var oldImageData; - try { - // "this" is not trustable - it may be not a context - oldImageData = getImageData(window, this).imageData; + 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){} + // 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)); } - catch (e){} - // 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; }; } }, @@ -295,18 +331,23 @@ object: ["WebGLRenderingContext", "WebGL2RenderingContext"], fakeGenerator: function(prefs, notify, window, original){ return function readPixels(x, y, width, height, format, type, pixels){ - // not able to use the getFakeCanvas function because the context type is wrong... - notify.call(this, "fakedReadout"); - var xPixels = pixels; - var ret = original.apply(this, window.Array.from(arguments)); - var l = xPixels.length; - var rng = randomSupply.getRng(l, window); - - for (var i = 0; i < l; i += 1){ - xPixels[i] = rng(xPixels[i], i); + if (!this || canvasSizeShouldBeFaked(this.canvas, prefs)){ + // not able to use the getFakeCanvas function because the context type is wrong... + notify.call(this, "fakedReadout"); + var xPixels = pixels; + var ret = original.apply(this, window.Array.from(arguments)); + var l = xPixels.length; + var rng = randomSupply.getRng(l, window); + + for (var i = 0; i < l; i += 1){ + xPixels[i] = rng(xPixels[i], i); + } + + return ret; + } + else { + return original.apply(this, window.Array.from(arguments)); } - - return ret; }; } } diff --git a/options/buildPrefInputs.js b/options/buildPrefInputs.js index 6104755..b26222d 100644 --- a/options/buildPrefInputs.js +++ b/options/buildPrefInputs.js @@ -69,6 +69,15 @@ document.body.appendChild(table); "blockMode": ["blockReadout", "fakeReadout", "fakeInput", "askReadout", "ask", "allow"] } }, + { + "name": "minFakeSize", + "title": "Minimal fake size", + "type": "integer", + "value": 1, + "displayDependencies": { + "blockMode": ["fakeReadout", "fakeInput"] + } + }, { "name": "maxFakeSize", "title": "Maximal fake size", diff --git a/releaseNotes.txt b/releaseNotes.txt index b647b1c..a78bad1 100644 --- a/releaseNotes.txt +++ b/releaseNotes.txt @@ -1,14 +1,18 @@ Version 0.4.0: todos: - import settings in content script (have to wait for the new API to register content scripts) + changes: - switched to webExtension - notifications are now done via page action + - minimal and maximal fake size are now respected in all fakeable functions new features: - information of all fake events in one tab are visible - - new setting to enable the inspection of the content of the faked canvas - settings page now only shows settings that are useful within the given settings set + - new preferences: + * minimal fake size + * setting to enable the inspection of the content of the faked canvas fixes: - ask mode did not work for input types