Added test for blob, offscreen canvas and offscreen canvas in workers

This commit is contained in:
kkapsner 2020-05-19 10:48:08 +02:00
parent 7c2a4edde0
commit a79c4ec8c5
4 changed files with 119 additions and 7 deletions

View File

@ -2,8 +2,8 @@ const canvasAPI = {
draw: function draw(canvas){
"use strict";
canvas.setAttribute("width", 220);
canvas.setAttribute("height", 30);
canvas.width = 220;
canvas.height = 30;
const fingerprintText = "BrowserLeaks,com <canvas> 10";

View File

@ -71,6 +71,24 @@
Hash: <span class="hash"><i>click anywhere to populate</i></span> (isPointInPath: <span class="isPointInPath"></span>)
<button>refresh</button>
</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="canvasAPI.js"></script>
<script src="test.js"></script>

View File

@ -8,12 +8,14 @@
display.title = url;
const hashes = await Promise.all([
testAPI.hash(url),
testAPI.hash(imageData.data)
imageData? testAPI.hash(imageData.data): ""
]);
container.querySelector(".hash").textContent =
hashes[0] + " / " +
hashes[1];
container.querySelector(".isPointInPath").textContent = isPointInPath;
if (typeof isPointInPath === "boolean"){
container.querySelector(".isPointInPath").textContent = isPointInPath;
}
}
function iframeTest(testNode){
@ -51,15 +53,47 @@
newWindow.close();
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){
const testNode = document.getElementById(testName);
const callback = tests[testName];
if (location.search !== "?notInitial"){
try {show(testNode, await callback(testNode, true));}
catch (error){console.error(testName, error);}
try {
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(){
show(testNode, await callback(testNode));
@ -99,4 +133,16 @@ function dynamicIframeTest3(){
const iframeWindow = window[length];
document.body.removeChild(div);
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)};
}

View File

@ -18,6 +18,54 @@ const testAPI = function(){
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){
const buffer = ((typeof input) === "string")?
new TextEncoder("utf-8").encode(input):