mirror of
https://github.com/kkapsner/CanvasBlocker
synced 2024-12-22 12:50:36 +01:00
Added test for blob, offscreen canvas and offscreen canvas in workers
This commit is contained in:
parent
7c2a4edde0
commit
a79c4ec8c5
@ -2,8 +2,8 @@ const canvasAPI = {
|
|||||||
draw: function draw(canvas){
|
draw: function draw(canvas){
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
canvas.setAttribute("width", 220);
|
canvas.width = 220;
|
||||||
canvas.setAttribute("height", 30);
|
canvas.height = 30;
|
||||||
|
|
||||||
const fingerprintText = "BrowserLeaks,com <canvas> 10";
|
const fingerprintText = "BrowserLeaks,com <canvas> 10";
|
||||||
|
|
||||||
|
@ -71,6 +71,24 @@
|
|||||||
Hash: <span class="hash"><i>click anywhere to populate</i></span> (isPointInPath: <span class="isPointInPath"></span>)
|
Hash: <span class="hash"><i>click anywhere to populate</i></span> (isPointInPath: <span class="isPointInPath"></span>)
|
||||||
<button>refresh</button>
|
<button>refresh</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="blob">
|
||||||
|
<h3>blob Test</h3>
|
||||||
|
<img class="display"><br>
|
||||||
|
Hash: <span class="hash"></span>
|
||||||
|
<button>refresh</button>
|
||||||
|
</div>
|
||||||
|
<div id="offscreen">
|
||||||
|
<h3>offscreen Test</h3>
|
||||||
|
<img class="display"><br>
|
||||||
|
Hash: <span class="hash"></span>
|
||||||
|
<button>refresh</button>
|
||||||
|
</div>
|
||||||
|
<div id="offscreenWorker">
|
||||||
|
<h3>offscreen Worker Test</h3>
|
||||||
|
<img class="display"><br>
|
||||||
|
Hash: <span class="hash"></span>
|
||||||
|
<button>refresh</button>
|
||||||
|
</div>
|
||||||
<script src="testAPI.js"></script>
|
<script src="testAPI.js"></script>
|
||||||
<script src="canvasAPI.js"></script>
|
<script src="canvasAPI.js"></script>
|
||||||
<script src="test.js"></script>
|
<script src="test.js"></script>
|
||||||
|
52
test/test.js
52
test/test.js
@ -8,13 +8,15 @@
|
|||||||
display.title = url;
|
display.title = url;
|
||||||
const hashes = await Promise.all([
|
const hashes = await Promise.all([
|
||||||
testAPI.hash(url),
|
testAPI.hash(url),
|
||||||
testAPI.hash(imageData.data)
|
imageData? testAPI.hash(imageData.data): ""
|
||||||
]);
|
]);
|
||||||
container.querySelector(".hash").textContent =
|
container.querySelector(".hash").textContent =
|
||||||
hashes[0] + " / " +
|
hashes[0] + " / " +
|
||||||
hashes[1];
|
hashes[1];
|
||||||
|
if (typeof isPointInPath === "boolean"){
|
||||||
container.querySelector(".isPointInPath").textContent = isPointInPath;
|
container.querySelector(".isPointInPath").textContent = isPointInPath;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function iframeTest(testNode){
|
function iframeTest(testNode){
|
||||||
const iframe = testNode.querySelector("iframe");
|
const iframe = testNode.querySelector("iframe");
|
||||||
@ -51,15 +53,47 @@
|
|||||||
newWindow.close();
|
newWindow.close();
|
||||||
return fingerprint;
|
return fingerprint;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
blob: async function(testNode){
|
||||||
|
const canvas = document.createElement("canvas");
|
||||||
|
canvasAPI.draw(canvas);
|
||||||
|
return new Promise(function(resolve, reject){
|
||||||
|
canvas.toBlob(async function(blob){
|
||||||
|
resolve({url: await testAPI.readBlob(blob)});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
offscreen: async function(testNode){
|
||||||
|
if (typeof OffscreenCanvas === "undefined"){
|
||||||
|
throw "not supported";
|
||||||
}
|
}
|
||||||
|
return offscreenTest();
|
||||||
|
},
|
||||||
|
offscreenWorker: async function(testNode){
|
||||||
|
if (
|
||||||
|
typeof OffscreenCanvas === "undefined" ||
|
||||||
|
typeof Worker === "undefined"
|
||||||
|
){
|
||||||
|
throw "not supported";
|
||||||
|
}
|
||||||
|
const canvasAPIUrl = new URL("./canvasAPI.js", location);
|
||||||
|
const testAPIUrl = new URL("./testAPI.js", location);
|
||||||
|
return testAPI.runInWorker(offscreenTest, [], [canvasAPIUrl, testAPIUrl]);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.keys(tests).forEach(async function(testName){
|
Object.keys(tests).forEach(async function(testName){
|
||||||
const testNode = document.getElementById(testName);
|
const testNode = document.getElementById(testName);
|
||||||
const callback = tests[testName];
|
const callback = tests[testName];
|
||||||
if (location.search !== "?notInitial"){
|
if (location.search !== "?notInitial"){
|
||||||
try {show(testNode, await callback(testNode, true));}
|
try {
|
||||||
catch (error){console.error(testName, error);}
|
show(testNode, await callback(testNode, true));
|
||||||
|
}
|
||||||
|
catch (error){
|
||||||
|
testNode.querySelector(".hash").innerHTML =
|
||||||
|
"<i>Error while computing: " + (error.message || error) + "</i>";
|
||||||
|
console.error(testName, error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
testNode.querySelector("button").addEventListener("click", async function(){
|
testNode.querySelector("button").addEventListener("click", async function(){
|
||||||
show(testNode, await callback(testNode));
|
show(testNode, await callback(testNode));
|
||||||
@ -100,3 +134,15 @@ function dynamicIframeTest3(){
|
|||||||
document.body.removeChild(div);
|
document.body.removeChild(div);
|
||||||
return canvasAPI.fingerprint(iframeWindow);
|
return canvasAPI.fingerprint(iframeWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function offscreenTest(){
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const offscreenCanvas = new OffscreenCanvas(220, 30);
|
||||||
|
canvasAPI.draw(offscreenCanvas);
|
||||||
|
const blob = offscreenCanvas.convertToBlob?
|
||||||
|
await offscreenCanvas.convertToBlob():
|
||||||
|
await offscreenCanvas.toBlob();
|
||||||
|
|
||||||
|
return {url: await testAPI.readBlob(blob)};
|
||||||
|
}
|
@ -18,6 +18,54 @@ const testAPI = function(){
|
|||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
runInWorker: async function(func, args = [], scripts = []){
|
||||||
|
return new Promise(function(resolve, reject){
|
||||||
|
const apis = scripts.map(function(script){
|
||||||
|
switch (typeof script){
|
||||||
|
case "function":
|
||||||
|
return script.toString();
|
||||||
|
case "string":
|
||||||
|
case "object":
|
||||||
|
return "self.importScripts(" + JSON.stringify(script.toString()) + ")";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}).join(";\n");
|
||||||
|
const code = `${apis};
|
||||||
|
${func.toString()}
|
||||||
|
async function run(){
|
||||||
|
return ${func.name}(${args.map(JSON.stringify).join(", ")});
|
||||||
|
}
|
||||||
|
run().then(function(result){
|
||||||
|
self.postMessage({result});
|
||||||
|
}).catch(function(error){
|
||||||
|
console.log(error);
|
||||||
|
self.postMessage({error: error.message || error.toString()});
|
||||||
|
});`;
|
||||||
|
const blob = new Blob([code], {type: "text/javascript"});
|
||||||
|
|
||||||
|
const blobWorker = new Worker(URL.createObjectURL(blob), {name: "BlobWorker"});
|
||||||
|
blobWorker.addEventListener("message", function(event){
|
||||||
|
if (event.data.error){
|
||||||
|
reject(event.data.error);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
resolve(event.data.result);
|
||||||
|
}
|
||||||
|
blobWorker.terminate();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
readBlob: async function(blob){
|
||||||
|
const reader = new FileReader();
|
||||||
|
return new Promise(function(resolve, reject){
|
||||||
|
reader.addEventListener("error", reject);
|
||||||
|
reader.addEventListener("load", function(){
|
||||||
|
resolve(reader.result);
|
||||||
|
});
|
||||||
|
reader.readAsDataURL(blob);
|
||||||
|
});
|
||||||
|
},
|
||||||
hash: async function(input){
|
hash: async function(input){
|
||||||
const buffer = ((typeof input) === "string")?
|
const buffer = ((typeof input) === "string")?
|
||||||
new TextEncoder("utf-8").encode(input):
|
new TextEncoder("utf-8").encode(input):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user