Loading toolkit/components/resistfingerprinting/tests/browser/browser_canvas_randomization_permission.js +100 −28 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ /** * Bug 1896175 - Testing canvas randomization with read canvas permission granted. * * Bug 1918690 - Extend canvas randomization permission test */ const emptyPage = Loading @@ -13,11 +13,11 @@ const emptyPage = "https://example.com" ) + "empty.html"; const TRUE_VALUE = "255,0,0,255,0,255,0,255,0,0,255,255"; function getImageData(tab) { const extractCanvas = function () { const canvas = document.createElement("canvas"); function getImageData(tab, isOffscreen, method) { const extractCanvas = function (isOffscreen, method) { const canvas = isOffscreen ? new OffscreenCanvas(3, 1) : document.createElement("canvas"); const ctx = canvas.getContext("2d"); ctx.fillStyle = "rgb(255, 0, 0)"; Loading @@ -27,10 +27,30 @@ function getImageData(tab) { ctx.fillStyle = "rgb(0, 0, 255)"; ctx.fillRect(2, 0, 1, 1); if (method === "getImageData") { return ctx.getImageData(0, 0, 3, 1).data.join(","); } else if (method === "toDataURL") { return canvas.toDataURL(); } else if (method === "toBlob") { return new Promise((resolve, reject) => { if (isOffscreen) { canvas.convertToBlob().then(resolve, reject); } else { canvas.toBlob(resolve, "image/png"); } }).then(blob => { const reader = new FileReader(); reader.readAsDataURL(blob); const { promise, resolve, reject } = Promise.withResolvers(); reader.onload = () => resolve(reader.result); reader.onerror = reject; return promise; }); } return null; }; const extractCanvasExpr = `(${extractCanvas.toString()})();`; const extractCanvasExpr = `(${extractCanvas.toString()})(${isOffscreen}, "${method}");`; return SpecialPowers.spawn( tab.linkedBrowser, Loading @@ -39,10 +59,21 @@ function getImageData(tab) { ); } add_task(async function test_no_permission() { // Test cases: [isOffscreen, method, true value] const TEST_CASES = [ // HTMLCanvasElement [false, "getImageData", null], [false, "toDataURL", null], [false, "toBlob", null], // OffscreenCanvas [true, "getImageData", null], [true, "toBlob", null], ]; add_setup(async function setup() { await SpecialPowers.pushPrefEnv({ set: [ ["privacy.resistFingerprinting", true], ["privacy.resistFingerprinting", false], ["privacy.fingerprintingProtection", false], ], }); Loading @@ -53,19 +84,26 @@ add_task(async function test_no_permission() { forceNewProcess: true, }); const imageData = await getImageData(tab); isnot(imageData, TRUE_VALUE, "Image data was randomized."); for (let i = 0; i < TEST_CASES.length; i++) { const test_case = TEST_CASES[i]; const [isOffscreen, method] = test_case; const imageData = await getImageData(tab, isOffscreen, method); test_case[2] = imageData; } BrowserTestUtils.removeTab(tab); await SpecialPowers.popPrefEnv(); }); add_task(async function test_permission() { async function runTest(permissionGranted, isRFP) { await SpecialPowers.pushPrefEnv({ set: [ ["privacy.resistFingerprinting", true], ["privacy.fingerprintingProtection", false], ["privacy.resistFingerprinting", isRFP], ["privacy.fingerprintingProtection", !isRFP], [ "privacy.fingerprintingProtection.overrides", "-AllTargets,+CanvasRandomization,+CanvasImageExtractionPrompt", ], ], }); Loading @@ -75,6 +113,7 @@ add_task(async function test_permission() { forceNewProcess: true, }); if (permissionGranted) { await SpecialPowers.pushPermissions([ { type: "canvas", Loading @@ -82,12 +121,45 @@ add_task(async function test_permission() { context: emptyPage, }, ]); } const imageData = await getImageData(tab); is(imageData, TRUE_VALUE, "Image data was not randomized."); for (let i = 0; i < TEST_CASES.length; i++) { const test_case = TEST_CASES[i]; const [isOffscreen, method, trueValue] = test_case; const imageData = await getImageData(tab, isOffscreen, method); const message = `Image data was ${ permissionGranted ? "not " : "" }randomized for ${method} on ${ isOffscreen ? "OffscreenCanvas" : "HTMLCanvasElement" }.`; if (isOffscreen) { // Offscreen canvas doesn't respect the permission. continue; } permissionGranted ? is(imageData, trueValue, message) : isnot(imageData, trueValue, message); } BrowserTestUtils.removeTab(tab); if (permissionGranted) { await SpecialPowers.popPermissions(); } BrowserTestUtils.removeTab(tab); await SpecialPowers.popPrefEnv(); } add_task(async function test_rfp_no_permission() { await runTest(false, true); }); add_task(async function test_rfp_permission() { await runTest(true, true); }); add_task(async function test_fpp_no_permission() { await runTest(false, false); }); add_task(async function test_fpp_permission() { await runTest(true, false); }); Loading
toolkit/components/resistfingerprinting/tests/browser/browser_canvas_randomization_permission.js +100 −28 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ /** * Bug 1896175 - Testing canvas randomization with read canvas permission granted. * * Bug 1918690 - Extend canvas randomization permission test */ const emptyPage = Loading @@ -13,11 +13,11 @@ const emptyPage = "https://example.com" ) + "empty.html"; const TRUE_VALUE = "255,0,0,255,0,255,0,255,0,0,255,255"; function getImageData(tab) { const extractCanvas = function () { const canvas = document.createElement("canvas"); function getImageData(tab, isOffscreen, method) { const extractCanvas = function (isOffscreen, method) { const canvas = isOffscreen ? new OffscreenCanvas(3, 1) : document.createElement("canvas"); const ctx = canvas.getContext("2d"); ctx.fillStyle = "rgb(255, 0, 0)"; Loading @@ -27,10 +27,30 @@ function getImageData(tab) { ctx.fillStyle = "rgb(0, 0, 255)"; ctx.fillRect(2, 0, 1, 1); if (method === "getImageData") { return ctx.getImageData(0, 0, 3, 1).data.join(","); } else if (method === "toDataURL") { return canvas.toDataURL(); } else if (method === "toBlob") { return new Promise((resolve, reject) => { if (isOffscreen) { canvas.convertToBlob().then(resolve, reject); } else { canvas.toBlob(resolve, "image/png"); } }).then(blob => { const reader = new FileReader(); reader.readAsDataURL(blob); const { promise, resolve, reject } = Promise.withResolvers(); reader.onload = () => resolve(reader.result); reader.onerror = reject; return promise; }); } return null; }; const extractCanvasExpr = `(${extractCanvas.toString()})();`; const extractCanvasExpr = `(${extractCanvas.toString()})(${isOffscreen}, "${method}");`; return SpecialPowers.spawn( tab.linkedBrowser, Loading @@ -39,10 +59,21 @@ function getImageData(tab) { ); } add_task(async function test_no_permission() { // Test cases: [isOffscreen, method, true value] const TEST_CASES = [ // HTMLCanvasElement [false, "getImageData", null], [false, "toDataURL", null], [false, "toBlob", null], // OffscreenCanvas [true, "getImageData", null], [true, "toBlob", null], ]; add_setup(async function setup() { await SpecialPowers.pushPrefEnv({ set: [ ["privacy.resistFingerprinting", true], ["privacy.resistFingerprinting", false], ["privacy.fingerprintingProtection", false], ], }); Loading @@ -53,19 +84,26 @@ add_task(async function test_no_permission() { forceNewProcess: true, }); const imageData = await getImageData(tab); isnot(imageData, TRUE_VALUE, "Image data was randomized."); for (let i = 0; i < TEST_CASES.length; i++) { const test_case = TEST_CASES[i]; const [isOffscreen, method] = test_case; const imageData = await getImageData(tab, isOffscreen, method); test_case[2] = imageData; } BrowserTestUtils.removeTab(tab); await SpecialPowers.popPrefEnv(); }); add_task(async function test_permission() { async function runTest(permissionGranted, isRFP) { await SpecialPowers.pushPrefEnv({ set: [ ["privacy.resistFingerprinting", true], ["privacy.fingerprintingProtection", false], ["privacy.resistFingerprinting", isRFP], ["privacy.fingerprintingProtection", !isRFP], [ "privacy.fingerprintingProtection.overrides", "-AllTargets,+CanvasRandomization,+CanvasImageExtractionPrompt", ], ], }); Loading @@ -75,6 +113,7 @@ add_task(async function test_permission() { forceNewProcess: true, }); if (permissionGranted) { await SpecialPowers.pushPermissions([ { type: "canvas", Loading @@ -82,12 +121,45 @@ add_task(async function test_permission() { context: emptyPage, }, ]); } const imageData = await getImageData(tab); is(imageData, TRUE_VALUE, "Image data was not randomized."); for (let i = 0; i < TEST_CASES.length; i++) { const test_case = TEST_CASES[i]; const [isOffscreen, method, trueValue] = test_case; const imageData = await getImageData(tab, isOffscreen, method); const message = `Image data was ${ permissionGranted ? "not " : "" }randomized for ${method} on ${ isOffscreen ? "OffscreenCanvas" : "HTMLCanvasElement" }.`; if (isOffscreen) { // Offscreen canvas doesn't respect the permission. continue; } permissionGranted ? is(imageData, trueValue, message) : isnot(imageData, trueValue, message); } BrowserTestUtils.removeTab(tab); if (permissionGranted) { await SpecialPowers.popPermissions(); } BrowserTestUtils.removeTab(tab); await SpecialPowers.popPrefEnv(); } add_task(async function test_rfp_no_permission() { await runTest(false, true); }); add_task(async function test_rfp_permission() { await runTest(true, true); }); add_task(async function test_fpp_no_permission() { await runTest(false, false); }); add_task(async function test_fpp_permission() { await runTest(true, false); });