tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit d749d6e28edf452e9bdba8a5da98f02bee8a6fb3
parent 1b6130dd320f2a1651b44e0b7d85582f633a4bc9
Author: Cristina Horotan <chorotan@mozilla.com>
Date:   Fri,  3 Oct 2025 22:28:06 +0300

Revert "Bug 1980264: Add a test r=timhuang" for causing xpcshell failures on test_encoder_png.js

This reverts commit d4cf73ac9411060a035affe325c5761057bba570.

Revert "Bug 1980264: Test Infra Fixes r=timhuang"

This reverts commit 992c24e4cf666613a8853213d2a36dcf1feaf35d.

Revert "Bug 1980264: Implement a streaming randomization approach for PNG images r=tnikkel"

This reverts commit 5910c78f6181b12315ae4a359a5afc7b071171c7.

Revert "Bug 1980264: Wire up an alternate efficient randomization layer r=timhuang"

This reverts commit a8a220b58adf1638f6deb05c3bc145510f70548f.

Revert "Bug 1980264: Plumb metatadata down to the Image Encoders r=tnikkel"

This reverts commit 348790428488cfc1000fa58c3c3f854cb4b19a58.

Revert "Bug 1980264: Rename a variable to be more generic r=timhuang"

This reverts commit b6b02cefea71e23351057fe45ea31fcacf091b93.

Revert "Bug 1980264: Clang Formatting and a missing Permission Check r=timhuang"

This reverts commit f3c68965b8f712efc829bf440525f0173d76a530.

Diffstat:
Mbrowser/components/resistfingerprinting/test/browser/browser.toml | 4----
Dbrowser/components/resistfingerprinting/test/browser/browser_efficientcanvascompare_iframes.js | 247-------------------------------------------------------------------------------
Dbrowser/components/resistfingerprinting/test/browser/file_efficientcanvascompare_iframee.html | 41-----------------------------------------
Dbrowser/components/resistfingerprinting/test/browser/file_efficientcanvascompare_iframer.html | 75---------------------------------------------------------------------------
Mbrowser/components/resistfingerprinting/test/browser/head.js | 9++++++---
Mdom/base/ImageEncoder.cpp | 65+++++++++++++++++++++++++++--------------------------------------
Mdom/base/ImageEncoder.h | 7+------
Mdom/canvas/CanvasRenderingContext2D.cpp | 26+++++++++++++-------------
Mdom/canvas/CanvasRenderingContext2D.h | 2+-
Mdom/canvas/CanvasRenderingContextHelper.cpp | 16+---------------
Mdom/canvas/CanvasRenderingContextHelper.h | 3---
Mdom/canvas/CanvasUtils.cpp | 36+++++++++++++-----------------------
Mdom/canvas/CanvasUtils.h | 1-
Mdom/canvas/ClientWebGLContext.cpp | 4++--
Mdom/canvas/ClientWebGLContext.h | 8++++----
Mdom/canvas/ImageBitmapRenderingContext.cpp | 8++++----
Mdom/canvas/ImageBitmapRenderingContext.h | 2+-
Mdom/canvas/OffscreenCanvas.cpp | 20+++++++++-----------
Mdom/canvas/nsICanvasRenderingContextInternal.h | 8++++----
Mdom/html/HTMLCanvasElement.cpp | 23++++++++---------------
Mdom/media/imagecapture/CaptureTask.cpp | 2+-
Mdom/webgpu/CanvasContext.cpp | 2+-
Mdom/webgpu/CanvasContext.h | 2+-
Mgfx/thebes/gfxUtils.cpp | 6+++---
Mimage/encoders/bmp/nsBMPEncoder.cpp | 3+--
Mimage/encoders/ico/nsICOEncoder.cpp | 9+++------
Mimage/encoders/jpeg/nsJPEGEncoder.cpp | 3+--
Mimage/encoders/png/nsPNGEncoder.cpp | 51+--------------------------------------------------
Mimage/encoders/png/nsPNGEncoder.h | 3---
Mimage/encoders/webp/nsWebPEncoder.cpp | 3+--
Mimage/imgIEncoder.idl | 3+--
Mimage/imgTools.cpp | 2+-
Mmedia/libpng/pnglibconf.h | 3---
Mmfbt/HashFunctions.cpp | 5++---
Mmfbt/HashFunctions.h | 3+--
Mtoolkit/components/resistfingerprinting/RFPTargets.inc | 2--
Mtoolkit/components/resistfingerprinting/nsRFPService.cpp | 68++------------------------------------------------------------------
Mtoolkit/components/resistfingerprinting/nsRFPService.h | 8--------
38 files changed, 114 insertions(+), 669 deletions(-)

diff --git a/browser/components/resistfingerprinting/test/browser/browser.toml b/browser/components/resistfingerprinting/test/browser/browser.toml @@ -11,8 +11,6 @@ support-files = [ "file_workerNetInfo.js", "file_workerPerformance.js", "head.js", - "file_efficientcanvascompare_iframer.html", - "file_efficientcanvascompare_iframee.html", "file_canvascompare_aboutblank_iframee.html", "file_canvascompare_aboutblank_iframer.html", "file_canvascompare_aboutblank_popupmaker.html", @@ -99,8 +97,6 @@ skip-if = [ "os == 'mac' && os_version == '15.30' && arch == 'aarch64' && opt", # Bug 1775698 ] -["browser_efficientcanvascompare_iframes.js"] - ["browser_exslt_time_precision.js"] ["browser_exslt_timezone_load.js"] diff --git a/browser/components/resistfingerprinting/test/browser/browser_efficientcanvascompare_iframes.js b/browser/components/resistfingerprinting/test/browser/browser_efficientcanvascompare_iframes.js @@ -1,247 +0,0 @@ -/** - * This test compares canvas randomization on a parent and an iframe, and ensures that the canvas randomization key - * is inherited correctly. (e.g. that the canvases have the same random value) - * - * It runs all the tests twice - once for when the iframe is cross-domain, and once when it is same-domain - * - * Covers the following cases: - * - RFP/FPP is disabled entirely - * - RFP is enabled entirely, and only in PBM - * - FPP is enabled entirely, and only in PBM - * - A normal window when FPP is enabled globally and RFP is enabled in PBM, Protections Enabled and Disabled - * - */ - -"use strict"; - -// ============================================================================================= - -async function testCanvasRandomization(result, expectedResults, extraData) { - let testDesc = extraData.testDesc; - - let parent = result.mine; - let child = result.theirs; - let unmodified = UNMODIFIED_CANVAS_DATA; - - if (expectedResults.shouldBeRandom) { - if (expectedResults.shouldRFPApply) { - Assert.notEqual( - parent, - child, - `Checking ${testDesc} for RFP canvas randomization parent != child` + - ` is ${parent != child}` - ); - Assert.notEqual( - parent, - unmodified, - `Checking ${testDesc} for RFP canvas randomization, parent != unmodified` + - ` is ${parent != unmodified}` - ); - } else { - Assert.equal( - parent, - child, - `Checking ${testDesc} for canvas randomization parent == child` + - ` is ${parent == child}` - ); - Assert.notEqual( - parent, - unmodified, - `Checking ${testDesc} for canvas randomization, parent != unmodified` + - ` is ${parent != unmodified}` - ); - } - } else { - Assert.equal( - parent, - child, - `Checking ${testDesc} for no canvas randomization, parent == child` + - ` is ${parent == child}` - ); - Assert.equal( - parent, - unmodified, - `Checking ${testDesc} for no canvas randomization, parent == unmodified` + - ` is ${parent == unmodified}` - ); - } -} - -requestLongerTimeout(2); - -var UNMODIFIED_CANVAS_DATA = undefined; - -add_setup(async function () { - // Disable the fingerprinting randomization. - await SpecialPowers.pushPrefEnv({ - set: [ - [ - "privacy.fingerprintingProtection.overrides", - "+EfficientCanvasRandomization,-CanvasRandomization", - ], - ], - }); - - await SpecialPowers.pushPrefEnv({ - set: [ - ["privacy.fingerprintingProtection", false], - ["privacy.fingerprintingProtection.pbmode", false], - ["privacy.resistFingerprinting", false], - ], - }); - - function runExtractCanvasData(tab) { - return SpecialPowers.spawn(tab.linkedBrowser, [], async () => { - const canvas = content.document.createElement("canvas"); - canvas.width = 100; - canvas.height = 100; - - const context = canvas.getContext("2d"); - - context.fillStyle = "#EE2222"; - context.fillRect(0, 0, 100, 100); - context.fillStyle = "#2222EE"; - context.fillRect(20, 20, 100, 100); - - // Add the canvas element to the document - content.document.body.appendChild(canvas); - - let url = canvas.toDataURL(); - return url; - }); - } - - const emptyPage = - getRootDirectory(gTestPath).replace( - "chrome://mochitests/content", - "https://example.com" - ) + "empty.html"; - - // Open a tab for extracting the canvas data. - const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, emptyPage); - - let data = await runExtractCanvasData(tab); - UNMODIFIED_CANVAS_DATA = data; - - BrowserTestUtils.removeTab(tab); - await SpecialPowers.popPrefEnv(); -}); - -// Keep the test simpler, we do pixel tests in other tests. - -// Note that we are inheriting the randomization key ACROSS top-level domains that are cross-domain, because the iframe is a 3rd party domain -let uri = `https://${FRAMER_DOMAIN}/browser/browser/components/resistfingerprinting/test/browser/file_efficientcanvascompare_iframer.html?mode=iframe`; - -let shouldBeRandom = { - shouldBeRandom: true, -}; -let noRandom = { - shouldBeRandom: false, -}; -let expectedResults = undefined; - -expectedResults = structuredClone(noRandom); -add_task( - defaultsTest.bind(null, uri, testCanvasRandomization, expectedResults) -); - -expectedResults = structuredClone(shouldBeRandom); -add_task( - defaultsPBMTest.bind(null, uri, testCanvasRandomization, expectedResults) -); - -expectedResults = structuredClone(shouldBeRandom); -add_task( - simpleRFPTest.bind(null, uri, testCanvasRandomization, expectedResults) -); - -// Test a private window with RFP enabled in PBMode -expectedResults = structuredClone(shouldBeRandom); -add_task( - simplePBMRFPTest.bind(null, uri, testCanvasRandomization, expectedResults) -); - -expectedResults = structuredClone(shouldBeRandom); -add_task( - simpleFPPTest.bind(null, uri, testCanvasRandomization, expectedResults) -); - -// Test a Private Window with FPP Enabled in PBM -expectedResults = structuredClone(shouldBeRandom); -add_task( - simplePBMFPPTest.bind(null, uri, testCanvasRandomization, expectedResults) -); - -// Test RFP Enabled in PBM and FPP enabled in Normal Browsing Mode, No Protections -expectedResults = structuredClone(noRandom); -add_task( - RFPPBMFPP_NormalMode_NoProtectionsTest.bind( - null, - uri, - testCanvasRandomization, - expectedResults - ) -); - -// Test RFP Enabled in PBM and FPP enabled in Normal Browsing Mode, Protections Enabled -expectedResults = structuredClone(shouldBeRandom); -add_task( - RFPPBMFPP_NormalMode_ProtectionsTest.bind( - null, - uri, - testCanvasRandomization, - expectedResults - ) -); - -// And here the we are inheriting the randomization key into an iframe that is same-domain to the parent -uri = `https://${IFRAME_DOMAIN}/browser/browser/components/resistfingerprinting/test/browser/file_efficientcanvascompare_iframer.html?mode=iframe`; - -expectedResults = structuredClone(noRandom); -add_task( - defaultsTest.bind(null, uri, testCanvasRandomization, expectedResults) -); - -expectedResults = structuredClone(shouldBeRandom); -add_task( - simpleRFPTest.bind(null, uri, testCanvasRandomization, expectedResults) -); - -// Test a private window with RFP enabled in PBMode -expectedResults = structuredClone(shouldBeRandom); -add_task( - simplePBMRFPTest.bind(null, uri, testCanvasRandomization, expectedResults) -); - -expectedResults = structuredClone(shouldBeRandom); -add_task( - simpleFPPTest.bind(null, uri, testCanvasRandomization, expectedResults) -); - -// Test a Private Window with FPP Enabled in PBM -expectedResults = structuredClone(shouldBeRandom); -add_task( - simplePBMFPPTest.bind(null, uri, testCanvasRandomization, expectedResults) -); - -// Test RFP Enabled in PBM and FPP enabled in Normal Browsing Mode, No Protections -expectedResults = structuredClone(noRandom); -add_task( - RFPPBMFPP_NormalMode_NoProtectionsTest.bind( - null, - uri, - testCanvasRandomization, - expectedResults - ) -); - -// Test RFP Enabled in PBM and FPP enabled in Normal Browsing Mode, Protections Enabled -expectedResults = structuredClone(shouldBeRandom); -add_task( - RFPPBMFPP_NormalMode_ProtectionsTest.bind( - null, - uri, - testCanvasRandomization, - expectedResults - ) -); diff --git a/browser/components/resistfingerprinting/test/browser/file_efficientcanvascompare_iframee.html b/browser/components/resistfingerprinting/test/browser/file_efficientcanvascompare_iframee.html @@ -1,41 +0,0 @@ -<!DOCTYPE html> -<meta charset="utf8"> -<script> -var parent_window; -let params = new URLSearchParams(document.location.search); -if (params.get("mode") == "popup") { - parent_window = window.opener; -} else { - parent_window = window.parent; -} - -window.onload = async () => { - parent_window.postMessage("ready", "*"); -} - -window.addEventListener("message", async function listener(event) { - if (event.data[0] == "gimme") { - let result = give_result(); - parent_window.postMessage(result, "*") - } -}); - -function give_result() { - const canvas = document.createElement("canvas"); - canvas.width = 100; - canvas.height = 100; - - const context = canvas.getContext("2d"); - - context.fillStyle = "#EE2222"; - context.fillRect(0, 0, 100, 100); - context.fillStyle = "#2222EE"; - context.fillRect(20, 20, 100, 100); - - // Add the canvas element to the document - document.body.appendChild(canvas); - - return canvas.toDataURL(); -} -</script> -<output id="result"></output> diff --git a/browser/components/resistfingerprinting/test/browser/file_efficientcanvascompare_iframer.html b/browser/components/resistfingerprinting/test/browser/file_efficientcanvascompare_iframer.html @@ -1,75 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<meta charset="utf-8"> -<title></title> -<script src="shared_test_funcs.js"></script> -<script> -async function runTheTest(iframe_domain, cross_origin_domain) { - var child_reference; - let url = `https://${iframe_domain}/browser/browser/components/resistfingerprinting/test/browser/file_efficientcanvascompare_iframee.html?mode=` - let params = new URLSearchParams(document.location.search); - - if (params.get("mode") == 'iframe') { - const iframes = document.querySelectorAll("iframe"); - iframes[0].src = url + 'iframe'; - child_reference = iframes[0].contentWindow; - } else if (params.get("mode") == "popup") { - let options = ""; - if (params.get("submode") == "noopener") { - options = "noopener"; - } - const popup = window.open(url + 'popup', '', options); - if (params.get("submode") == "noopener") { - return {}; - } - child_reference = popup; - } else { - throw new Error("Unknown page mode specified"); - } - - function give_result() { - const canvas = document.createElement("canvas"); - canvas.width = 100; - canvas.height = 100; - - const context = canvas.getContext("2d"); - - context.fillStyle = "#EE2222"; - context.fillRect(0, 0, 100, 100); - context.fillStyle = "#2222EE"; - context.fillRect(20, 20, 100, 100); - - // Add the canvas element to the document - document.body.appendChild(canvas); - - return canvas.toDataURL(); - } - let myResult = give_result(); - - await waitForMessage("ready", `https://${iframe_domain}`); - - const promiseForRFPTest = new Promise(resolve => { - window.addEventListener("message", event => { - if(event.origin != `https://${iframe_domain}`) { - throw new Error(`origin should be ${iframe_domain}`); - } - - resolve({mine: myResult, theirs: event.data}); - }, { once: true }); - }); - child_reference.postMessage(["gimme", cross_origin_domain], "*"); - var result = await promiseForRFPTest; - - if (params.get("mode") == "popup") { - child_reference.close(); - } - - return result; -} -</script> -</head> -<body> -<iframe width=100></iframe> -</body> -</html> diff --git a/browser/components/resistfingerprinting/test/browser/head.js b/browser/components/resistfingerprinting/test/browser/head.js @@ -843,7 +843,7 @@ async function simpleFPPTest( extraData = {}; } extraData.testDesc = extraData.testDesc || "simple FPP enabled"; - expectedResults.shouldRFPApply = false; + expectedResults.shouldRFPApply = true; await SpecialPowers.pushPrefEnv({ set: [ ["privacy.fingerprintingProtection", true], @@ -871,7 +871,7 @@ async function simplePBMFPPTest( } extraData.private_window = true; extraData.testDesc = extraData.testDesc || "simple FPP in PBM enabled"; - expectedResults.shouldRFPApply = false; + expectedResults.shouldRFPApply = true; await SpecialPowers.pushPrefEnv({ set: [ ["privacy.fingerprintingProtection.pbmode", true], @@ -907,7 +907,10 @@ async function RFPPBMFPP_NormalMode_NoProtectionsTest( ["privacy.resistFingerprinting", false], ["privacy.resistFingerprinting.pbmode", true], ["privacy.fingerprintingProtection", true], - ["privacy.fingerprintingProtection.overrides", "-AllTargets"], + [ + "privacy.fingerprintingProtection.overrides", + "-NavigatorHWConcurrency,-NavigatorHWConcurrencyTiered,-CanvasRandomization", + ], ].concat(extraPrefs || []), }); diff --git a/dom/base/ImageEncoder.cpp b/dom/base/ImageEncoder.cpp @@ -152,7 +152,7 @@ class EncodingRunnable : public Runnable { EncodingCompleteEvent* aEncodingCompleteEvent, int32_t aFormat, const CSSIntSize aSize, CanvasUtils::ImageExtraction aExtractionBehavior, - const nsCString& aRandomizationKey, bool aUsingCustomOptions) + bool aUsingCustomOptions) : Runnable("EncodingRunnable"), mType(aType), mOptions(aOptions), @@ -163,23 +163,22 @@ class EncodingRunnable : public Runnable { mFormat(aFormat), mSize(aSize), mExtractionBehavior(aExtractionBehavior), - mRandomizationKey(aRandomizationKey), mUsingCustomOptions(aUsingCustomOptions) {} nsresult ProcessImageData(uint64_t* aImgSize, void** aImgData) { nsCOMPtr<nsIInputStream> stream; nsresult rv = ImageEncoder::ExtractDataInternal( mType, mOptions, mImageBuffer.get(), mFormat, mSize, - mExtractionBehavior, mRandomizationKey, mImage, nullptr, nullptr, - getter_AddRefs(stream), mEncoder); + mExtractionBehavior, mImage, nullptr, nullptr, getter_AddRefs(stream), + mEncoder); // If there are unrecognized custom parse options, we should fall back to // the default values for the encoder without any options at all. if (rv == NS_ERROR_INVALID_ARG && mUsingCustomOptions) { rv = ImageEncoder::ExtractDataInternal( mType, u""_ns, mImageBuffer.get(), mFormat, mSize, - mExtractionBehavior, mRandomizationKey, mImage, nullptr, nullptr, - getter_AddRefs(stream), mEncoder); + mExtractionBehavior, mImage, nullptr, nullptr, getter_AddRefs(stream), + mEncoder); } NS_ENSURE_SUCCESS(rv, rv); @@ -222,7 +221,6 @@ class EncodingRunnable : public Runnable { int32_t mFormat; const CSSIntSize mSize; CanvasUtils::ImageExtraction mExtractionBehavior; - nsCString mRandomizationKey; bool mUsingCustomOptions; }; @@ -230,7 +228,6 @@ class EncodingRunnable : public Runnable { nsresult ImageEncoder::ExtractData( nsAString& aType, const nsAString& aOptions, const CSSIntSize aSize, CanvasUtils::ImageExtraction aExtractionBehavior, - const nsCString& aRandomizationKey, nsICanvasRenderingContextInternal* aContext, OffscreenCanvasDisplayHelper* aOffscreenDisplay, nsIInputStream** aStream) { nsCOMPtr<imgIEncoder> encoder = ImageEncoder::GetImageEncoder(aType); @@ -239,15 +236,14 @@ nsresult ImageEncoder::ExtractData( } return ExtractDataInternal(aType, aOptions, nullptr, 0, aSize, - aExtractionBehavior, aRandomizationKey, nullptr, - aContext, aOffscreenDisplay, aStream, encoder); + aExtractionBehavior, nullptr, aContext, + aOffscreenDisplay, aStream, encoder); } /* static */ nsresult ImageEncoder::ExtractDataFromLayersImageAsync( nsAString& aType, const nsAString& aOptions, bool aUsingCustomOptions, layers::Image* aImage, CanvasUtils::ImageExtraction aExtractionBehavior, - const nsCString& aRandomizationKey, EncodeCompleteCallback* aEncodeCallback) { nsCOMPtr<imgIEncoder> encoder = ImageEncoder::GetImageEncoder(aType); if (!encoder) { @@ -258,10 +254,10 @@ nsresult ImageEncoder::ExtractDataFromLayersImageAsync( new EncodingCompleteEvent(aEncodeCallback); CSSIntSize size = CSSIntSize::FromUnknownSize(aImage->GetSize()); - nsCOMPtr<nsIRunnable> event = new EncodingRunnable( - aType, aOptions, nullptr, aImage, encoder, completeEvent, - imgIEncoder::INPUT_FORMAT_HOSTARGB, size, aExtractionBehavior, - VoidCString(), aUsingCustomOptions); + nsCOMPtr<nsIRunnable> event = + new EncodingRunnable(aType, aOptions, nullptr, aImage, encoder, + completeEvent, imgIEncoder::INPUT_FORMAT_HOSTARGB, + size, aExtractionBehavior, aUsingCustomOptions); return NS_DispatchBackgroundTask(event.forget()); } @@ -270,7 +266,6 @@ nsresult ImageEncoder::ExtractDataAsync( nsAString& aType, const nsAString& aOptions, bool aUsingCustomOptions, UniquePtr<uint8_t[]> aImageBuffer, int32_t aFormat, const CSSIntSize aSize, CanvasUtils::ImageExtraction aExtractionBehavior, - const nsCString& aRandomizationKey, EncodeCompleteCallback* aEncodeCallback) { nsCOMPtr<imgIEncoder> encoder = ImageEncoder::GetImageEncoder(aType); if (!encoder) { @@ -282,8 +277,7 @@ nsresult ImageEncoder::ExtractDataAsync( nsCOMPtr<nsIRunnable> event = new EncodingRunnable( aType, aOptions, std::move(aImageBuffer), nullptr, encoder, completeEvent, - aFormat, aSize, aExtractionBehavior, aRandomizationKey, - aUsingCustomOptions); + aFormat, aSize, aExtractionBehavior, aUsingCustomOptions); return NS_DispatchBackgroundTask(event.forget()); } @@ -292,11 +286,10 @@ nsresult ImageEncoder::GetInputStream(int32_t aWidth, int32_t aHeight, uint8_t* aImageBuffer, int32_t aFormat, imgIEncoder* aEncoder, const nsAString& aEncoderOptions, - const nsACString& aRandomizationKey, nsIInputStream** aStream) { - nsresult rv = aEncoder->InitFromData(aImageBuffer, aWidth * aHeight * 4, - aWidth, aHeight, aWidth * 4, aFormat, - aEncoderOptions, aRandomizationKey); + nsresult rv = + aEncoder->InitFromData(aImageBuffer, aWidth * aHeight * 4, aWidth, + aHeight, aWidth * 4, aFormat, aEncoderOptions); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<imgIEncoder> encoder(aEncoder); @@ -308,8 +301,7 @@ nsresult ImageEncoder::GetInputStream(int32_t aWidth, int32_t aHeight, nsresult ImageEncoder::ExtractDataInternal( const nsAString& aType, const nsAString& aOptions, uint8_t* aImageBuffer, int32_t aFormat, const CSSIntSize aSize, - CanvasUtils::ImageExtraction aExtractionBehavior, - const nsCString& aRandomizationKey, layers::Image* aImage, + CanvasUtils::ImageExtraction aExtractionBehavior, layers::Image* aImage, nsICanvasRenderingContextInternal* aContext, OffscreenCanvasDisplayHelper* aOffscreenDisplay, nsIInputStream** aStream, imgIEncoder* aEncoder) { @@ -352,8 +344,7 @@ nsresult ImageEncoder::ExtractDataInternal( } rv = aEncoder->InitFromData(map.mData, aSize.width * aSize.height * 4, aSize.width, aSize.height, aSize.width * 4, - imgIEncoder::INPUT_FORMAT_HOSTARGB, aOptions, - VoidCString()); + imgIEncoder::INPUT_FORMAT_HOSTARGB, aOptions); emptyCanvas->Unmap(); if (NS_SUCCEEDED(rv)) { imgStream = aEncoder; @@ -363,13 +354,13 @@ nsresult ImageEncoder::ExtractDataInternal( return NS_ERROR_INVALID_ARG; } - rv = ImageEncoder::GetInputStream( - aSize.width, aSize.height, aImageBuffer, aFormat, aEncoder, aOptions, - aRandomizationKey, getter_AddRefs(imgStream)); + rv = ImageEncoder::GetInputStream(aSize.width, aSize.height, aImageBuffer, + aFormat, aEncoder, aOptions, + getter_AddRefs(imgStream)); } else if (aContext) { NS_ConvertUTF16toUTF8 encoderType(aType); rv = aContext->GetInputStream(encoderType.get(), aOptions, - aExtractionBehavior, aRandomizationKey, + aExtractionBehavior, getter_AddRefs(imgStream)); } else if (aOffscreenDisplay) { const NS_ConvertUTF16toUTF8 encoderType(aType); @@ -396,8 +387,7 @@ nsresult ImageEncoder::ExtractDataInternal( auto size = data->GetSize(); rv = aEncoder->InitFromData(map.mData, size.width * size.height * 4, size.width, size.height, size.width * 4, - imgIEncoder::INPUT_FORMAT_HOSTARGB, aOptions, - VoidCString()); + imgIEncoder::INPUT_FORMAT_HOSTARGB, aOptions); data->Unmap(); } if (NS_SUCCEEDED(rv)) { @@ -427,10 +417,10 @@ nsresult ImageEncoder::ExtractDataInternal( return rv; } - rv = aEncoder->InitFromData( - data.Elements(), aSize.width * aSize.height * 4, aSize.width, - aSize.height, aSize.width * 4, imgIEncoder::INPUT_FORMAT_HOSTARGB, - aOptions, VoidCString()); + rv = aEncoder->InitFromData(data.Elements(), + aSize.width * aSize.height * 4, aSize.width, + aSize.height, aSize.width * 4, + imgIEncoder::INPUT_FORMAT_HOSTARGB, aOptions); } else { if (BufferSizeFromDimensions(aSize.width, aSize.height, 4) == 0) { return NS_ERROR_INVALID_ARG; @@ -447,8 +437,7 @@ nsresult ImageEncoder::ExtractDataInternal( auto size = dataSurface->GetSize(); rv = aEncoder->InitFromData(map.mData, size.width * size.height * 4, size.width, size.height, size.width * 4, - imgIEncoder::INPUT_FORMAT_HOSTARGB, aOptions, - VoidCString()); + imgIEncoder::INPUT_FORMAT_HOSTARGB, aOptions); dataSurface->Unmap(); } diff --git a/dom/base/ImageEncoder.h b/dom/base/ImageEncoder.h @@ -40,7 +40,6 @@ class ImageEncoder { static nsresult ExtractData(nsAString& aType, const nsAString& aOptions, const CSSIntSize aSize, CanvasUtils::ImageExtraction aExtractionBehavior, - const nsCString& aRandomizationKey, nsICanvasRenderingContextInternal* aContext, OffscreenCanvasDisplayHelper* aOffscreenDisplay, nsIInputStream** aStream); @@ -60,7 +59,6 @@ class ImageEncoder { nsAString& aType, const nsAString& aOptions, bool aUsingCustomOptions, UniquePtr<uint8_t[]> aImageBuffer, int32_t aFormat, const CSSIntSize aSize, CanvasUtils::ImageExtraction aExtractionBehavior, - const nsCString& aRandomizationKey, EncodeCompleteCallback* aEncodeCallback); // Extract an Image asynchronously. Its function is same as ExtractDataAsync @@ -71,7 +69,6 @@ class ImageEncoder { static nsresult ExtractDataFromLayersImageAsync( nsAString& aType, const nsAString& aOptions, bool aUsingCustomOptions, layers::Image* aImage, CanvasUtils::ImageExtraction aExtractionBehavior, - const nsCString& aRandomizationKey, EncodeCompleteCallback* aEncodeCallback); // Gives you a stream containing the image represented by aImageBuffer. @@ -81,7 +78,6 @@ class ImageEncoder { uint8_t* aImageBuffer, int32_t aFormat, imgIEncoder* aEncoder, const nsAString& aEncoderOptions, - const nsACString& aRandomizationKey, nsIInputStream** aStream); private: @@ -89,8 +85,7 @@ class ImageEncoder { static nsresult ExtractDataInternal( const nsAString& aType, const nsAString& aOptions, uint8_t* aImageBuffer, int32_t aFormat, const CSSIntSize aSize, - CanvasUtils::ImageExtraction aExtractionBehavior, - const nsCString& aRandomizationKey, layers::Image* aImage, + CanvasUtils::ImageExtraction aExtractionBehavior, layers::Image* aImage, nsICanvasRenderingContextInternal* aContext, OffscreenCanvasDisplayHelper* aOffscreenDisplay, nsIInputStream** aStream, imgIEncoder* aEncoder); diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp @@ -2293,7 +2293,7 @@ NS_IMETHODIMP CanvasRenderingContext2D::GetInputStream( const char* aMimeType, const nsAString& aEncoderOptions, mozilla::CanvasUtils::ImageExtraction aExtractionBehavior, - const nsACString& aRandomizationKey, nsIInputStream** aStream) { + nsIInputStream** aStream) { nsCString enccid("@mozilla.org/image/encoder;2?type="); enccid += aMimeType; nsCOMPtr<imgIEncoder> encoder = do_CreateInstance(enccid.get()); @@ -2309,9 +2309,9 @@ CanvasRenderingContext2D::GetInputStream( return NS_ERROR_FAILURE; } - return ImageEncoder::GetInputStream( - imageSize.width, imageSize.height, imageBuffer.get(), format, encoder, - aEncoderOptions, aRandomizationKey, aStream); + return ImageEncoder::GetInputStream(imageSize.width, imageSize.height, + imageBuffer.get(), format, encoder, + aEncoderOptions, aStream); } already_AddRefed<mozilla::gfx::SourceSurface> @@ -6531,14 +6531,14 @@ nsresult CanvasRenderingContext2D::GetImageDataArray( mBufferProvider->ReturnSnapshot(snapshot.forget()); // Check for site-specific permission. - CanvasUtils::ImageExtraction extractionBehavior = + CanvasUtils::ImageExtraction permission = CanvasUtils::ImageExtraction::Unrestricted; if (mCanvasElement) { - extractionBehavior = CanvasUtils::ImageExtractionResult(mCanvasElement, aCx, - &aSubjectPrincipal); + permission = CanvasUtils::ImageExtractionResult(mCanvasElement, aCx, + &aSubjectPrincipal); } else if (mOffscreenCanvas) { - extractionBehavior = CanvasUtils::ImageExtractionResult( - mOffscreenCanvas, aCx, &aSubjectPrincipal); + permission = CanvasUtils::ImageExtractionResult(mOffscreenCanvas, aCx, + &aSubjectPrincipal); } // Clone the data source surface if canvas randomization is enabled. We need @@ -6547,7 +6547,7 @@ nsresult CanvasRenderingContext2D::GetImageDataArray( // // Note that we don't need to clone if we will use the place holder because // the place holder doesn't use actual image data. - if (extractionBehavior == CanvasUtils::ImageExtraction::Randomize) { + if (permission == CanvasUtils::ImageExtraction::Randomize) { if (readback) { readback = CreateDataSourceSurfaceByCloning(readback); } @@ -6560,12 +6560,12 @@ nsresult CanvasRenderingContext2D::GetImageDataArray( do { uint8_t* randomData; - if (extractionBehavior == CanvasUtils::ImageExtraction::Placeholder) { + if (permission == CanvasUtils::ImageExtraction::Placeholder) { // Since we cannot call any GC-able functions (like requesting the RNG // service) after we call JS_GetUint8ClampedArrayData, we will // pre-generate the randomness required for GeneratePlaceholderCanvasData. randomData = TryToGenerateRandomDataForPlaceholderCanvasData(); - } else if (extractionBehavior == CanvasUtils::ImageExtraction::Randomize) { + } else if (permission == CanvasUtils::ImageExtraction::Randomize) { // Apply the random noises if canvan randomization is enabled. We don't // need to calculate random noises if we are going to use the place // holder. @@ -6582,7 +6582,7 @@ nsresult CanvasRenderingContext2D::GetImageDataArray( uint8_t* data = JS_GetUint8ClampedArrayData(darray, &isShared, nogc); MOZ_ASSERT(!isShared); // Should not happen, data was created above - if (extractionBehavior == CanvasUtils::ImageExtraction::Placeholder) { + if (permission == CanvasUtils::ImageExtraction::Placeholder) { FillPlaceholderCanvas(randomData, len.value(), data); break; } diff --git a/dom/canvas/CanvasRenderingContext2D.h b/dom/canvas/CanvasRenderingContext2D.h @@ -502,7 +502,7 @@ class CanvasRenderingContext2D : public nsICanvasRenderingContextInternal, NS_IMETHOD GetInputStream( const char* aMimeType, const nsAString& aEncoderOptions, mozilla::CanvasUtils::ImageExtraction aExtractionBehavior, - const nsACString& aRandomizationKey, nsIInputStream** aStream) override; + nsIInputStream** aStream) override; already_AddRefed<mozilla::gfx::SourceSurface> GetOptimizedSnapshot( mozilla::gfx::DrawTarget* aTarget, gfxAlphaType* aOutAlphaType) override; diff --git a/dom/canvas/CanvasRenderingContextHelper.cpp b/dom/canvas/CanvasRenderingContextHelper.cpp @@ -62,12 +62,6 @@ void CanvasRenderingContextHelper::ToBlob( } } - nsCString randomizationKeyStr = VoidCString(); - if (aExtractionBehavior == CanvasUtils::ImageExtraction::EfficientRandomize) { - nsRFPService::GetFingerprintingRandomizationKeyAsString( - GetCookieJarSettings(), randomizationKeyStr); - } - int32_t format = 0; auto imageSize = gfx::IntSize{elementSize.width, elementSize.height}; UniquePtr<uint8_t[]> imageBuffer = @@ -77,7 +71,7 @@ void CanvasRenderingContextHelper::ToBlob( aRv = ImageEncoder::ExtractDataAsync( aType, aEncodeOptions, aUsingCustomOptions, std::move(imageBuffer), format, CSSIntSize::FromUnknownSize(imageSize), aExtractionBehavior, - randomizationKeyStr, callback); + callback); } UniquePtr<uint8_t[]> CanvasRenderingContextHelper::GetImageBuffer( @@ -90,14 +84,6 @@ UniquePtr<uint8_t[]> CanvasRenderingContextHelper::GetImageBuffer( return nullptr; } -nsICookieJarSettings* CanvasRenderingContextHelper::GetCookieJarSettings() - const { - if (mCurrentContext) { - return mCurrentContext->GetCookieJarSettings(); - } - return nullptr; -} - already_AddRefed<nsICanvasRenderingContextInternal> CanvasRenderingContextHelper::CreateContext(CanvasContextType aContextType) { return CreateContextHelper(aContextType, layers::LayersBackend::LAYERS_NONE); diff --git a/dom/canvas/CanvasRenderingContextHelper.h b/dom/canvas/CanvasRenderingContextHelper.h @@ -13,7 +13,6 @@ #include "nsSize.h" class nsICanvasRenderingContextInternal; -class nsICookieJarSettings; class nsIGlobalObject; namespace mozilla { @@ -76,8 +75,6 @@ class CanvasRenderingContextHelper { CanvasUtils::ImageExtraction aExtractionBehavior, int32_t* aOutFormat, gfx::IntSize* aOutImageSize); - nsICookieJarSettings* GetCookieJarSettings() const; - already_AddRefed<nsISupports> GetOrCreateContext( JSContext* aCx, const nsAString& aContextId, JS::Handle<JS::Value> aContextOptions, ErrorResult& aRv); diff --git a/dom/canvas/CanvasUtils.cpp b/dom/canvas/CanvasUtils.cpp @@ -383,17 +383,8 @@ ImageExtraction ImageExtractionResult(dom::HTMLCanvasElement* aCanvasElement, return ImageExtraction::Placeholder; } - if (ownerDoc->ShouldResistFingerprinting( - RFPTarget::EfficientCanvasRandomization) && - GetCanvasExtractDataPermission(aPrincipal) != - nsIPermissionManager::ALLOW_ACTION) { - return ImageExtraction::EfficientRandomize; - } - - if ((ownerDoc->ShouldResistFingerprinting(RFPTarget::CanvasRandomization) || - ownerDoc->ShouldResistFingerprinting(RFPTarget::WebGLRandomization)) && - GetCanvasExtractDataPermission(aPrincipal) != - nsIPermissionManager::ALLOW_ACTION) { + if (ownerDoc->ShouldResistFingerprinting(RFPTarget::CanvasRandomization) || + ownerDoc->ShouldResistFingerprinting(RFPTarget::WebGLRandomization)) { return ImageExtraction::Randomize; } @@ -469,8 +460,7 @@ bool IsImageExtractionAllowed(dom::OffscreenCanvas* aOffscreenCanvas, if (!XRE_IsContentProcess()) { MOZ_ASSERT_UNREACHABLE( - "Who's calling this from the parent process without a chrome " - "window " + "Who's calling this from the parent process without a chrome window " "(it would have been exempt from the RFP targets)?"); return; } @@ -596,11 +586,11 @@ bool GetCanvasContextType(const nsAString& str, } /** - * This security check utility might be called from an source that never - * taints others. For example, while painting a CanvasPattern, which is - * created from an ImageBitmap, onto a canvas. In this case, the caller could - * set the CORSUsed true in order to pass this check and leave the aPrincipal - * to be a nullptr since the aPrincipal is not going to be used. + * This security check utility might be called from an source that never taints + * others. For example, while painting a CanvasPattern, which is created from an + * ImageBitmap, onto a canvas. In this case, the caller could set the CORSUsed + * true in order to pass this check and leave the aPrincipal to be a nullptr + * since the aPrincipal is not going to be used. */ void DoDrawImageSecurityCheck(dom::HTMLCanvasElement* aCanvasElement, nsIPrincipal* aPrincipal, bool forceWriteOnly, @@ -658,11 +648,11 @@ void DoDrawImageSecurityCheck(dom::HTMLCanvasElement* aCanvasElement, } /** - * This security check utility might be called from an source that never - * taints others. For example, while painting a CanvasPattern, which is - * created from an ImageBitmap, onto a canvas. In this case, the caller could - * set the aCORSUsed true in order to pass this check and leave the aPrincipal - * to be a nullptr since the aPrincipal is not going to be used. + * This security check utility might be called from an source that never taints + * others. For example, while painting a CanvasPattern, which is created from an + * ImageBitmap, onto a canvas. In this case, the caller could set the aCORSUsed + * true in order to pass this check and leave the aPrincipal to be a nullptr + * since the aPrincipal is not going to be used. */ void DoDrawImageSecurityCheck(dom::OffscreenCanvas* aOffscreenCanvas, nsIPrincipal* aPrincipal, bool aForceWriteOnly, diff --git a/dom/canvas/CanvasUtils.h b/dom/canvas/CanvasUtils.h @@ -75,7 +75,6 @@ enum class ImageExtraction { Unrestricted, Placeholder, Randomize, - EfficientRandomize, }; // Returns whether the result of an image extraction should be replaced diff --git a/dom/canvas/ClientWebGLContext.cpp b/dom/canvas/ClientWebGLContext.cpp @@ -1358,8 +1358,8 @@ UniquePtr<uint8_t[]> ClientWebGLContext::GetImageBuffer( NS_IMETHODIMP ClientWebGLContext::GetInputStream( const char* mimeType, const nsAString& encoderOptions, - mozilla::CanvasUtils::ImageExtraction extractionBehavior, - const nsACString& randomizationKey, nsIInputStream** out_stream) { + mozilla::CanvasUtils::ImageExtraction spoofing, + nsIInputStream** out_stream) { // Use GetSurfaceSnapshot() to make sure that appropriate y-flip gets applied gfxAlphaType any; RefPtr<gfx::SourceSurface> snapshot = GetSurfaceSnapshot(&any); diff --git a/dom/canvas/ClientWebGLContext.h b/dom/canvas/ClientWebGLContext.h @@ -1009,10 +1009,10 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal, UniquePtr<uint8_t[]> GetImageBuffer( mozilla::CanvasUtils::ImageExtraction aExtractionBehavior, int32_t* out_format, gfx::IntSize* out_imageSize) override; - NS_IMETHOD GetInputStream( - const char* mimeType, const nsAString& encoderOptions, - mozilla::CanvasUtils::ImageExtraction extractionBehavior, - const nsACString& randomizationKey, nsIInputStream** out_stream) override; + NS_IMETHOD GetInputStream(const char* mimeType, + const nsAString& encoderOptions, + mozilla::CanvasUtils::ImageExtraction spoofing, + nsIInputStream** out_stream) override; already_AddRefed<mozilla::gfx::SourceSurface> GetSurfaceSnapshot( gfxAlphaType* out_alphaType) override; diff --git a/dom/canvas/ImageBitmapRenderingContext.cpp b/dom/canvas/ImageBitmapRenderingContext.cpp @@ -209,7 +209,7 @@ NS_IMETHODIMP ImageBitmapRenderingContext::GetInputStream( const char* aMimeType, const nsAString& aEncoderOptions, mozilla::CanvasUtils::ImageExtraction aExtractionBehavior, - const nsACString& aRandomizationKey, nsIInputStream** aStream) { + nsIInputStream** aStream) { nsCString enccid("@mozilla.org/image/encoder;2?type="); enccid += aMimeType; nsCOMPtr<imgIEncoder> encoder = do_CreateInstance(enccid.get()); @@ -225,9 +225,9 @@ ImageBitmapRenderingContext::GetInputStream( return NS_ERROR_FAILURE; } - return ImageEncoder::GetInputStream( - imageSize.width, imageSize.height, imageBuffer.get(), format, encoder, - aEncoderOptions, aRandomizationKey, aStream); + return ImageEncoder::GetInputStream(imageSize.width, imageSize.height, + imageBuffer.get(), format, encoder, + aEncoderOptions, aStream); } already_AddRefed<mozilla::gfx::SourceSurface> diff --git a/dom/canvas/ImageBitmapRenderingContext.h b/dom/canvas/ImageBitmapRenderingContext.h @@ -75,7 +75,7 @@ class ImageBitmapRenderingContext final NS_IMETHOD GetInputStream( const char* aMimeType, const nsAString& aEncoderOptions, mozilla::CanvasUtils::ImageExtraction aExtractionBehavior, - const nsACString& aRandomizationKey, nsIInputStream** aStream) override; + nsIInputStream** aStream) override; virtual already_AddRefed<mozilla::gfx::SourceSurface> GetSurfaceSnapshot( gfxAlphaType* aOutAlphaType) override; diff --git a/dom/canvas/OffscreenCanvas.cpp b/dom/canvas/OffscreenCanvas.cpp @@ -510,14 +510,13 @@ already_AddRefed<Promise> OffscreenCanvas::ConvertToBlob( RefPtr<EncodeCompleteCallback> callback = CreateEncodeCompleteCallback(promise); - CanvasUtils::ImageExtraction extractionBehaviour = - CanvasUtils::ImageExtractionResult( - this, nsContentUtils::GetCurrentJSContext(), - mCurrentContext ? mCurrentContext->PrincipalOrNull() : nullptr); + CanvasUtils::ImageExtraction spoofing = CanvasUtils::ImageExtractionResult( + this, nsContentUtils::GetCurrentJSContext(), + mCurrentContext ? mCurrentContext->PrincipalOrNull() : nullptr); CanvasRenderingContextHelper::ToBlob(callback, type, encodeOptions, /* aUsingCustomOptions */ false, - extractionBehaviour, aRv); + spoofing, aRv); if (aRv.Failed()) { promise->MaybeReject(std::move(aRv)); } @@ -555,12 +554,11 @@ already_AddRefed<Promise> OffscreenCanvas::ToBlob(JSContext* aCx, RefPtr<EncodeCompleteCallback> callback = CreateEncodeCompleteCallback(promise); - CanvasUtils::ImageExtraction extractionBehaviour = - CanvasUtils::ImageExtractionResult( - this, aCx, - mCurrentContext ? mCurrentContext->PrincipalOrNull() : nullptr); - CanvasRenderingContextHelper::ToBlob(aCx, callback, aType, aParams, - extractionBehaviour, aRv); + CanvasUtils::ImageExtraction spoofing = CanvasUtils::ImageExtractionResult( + this, aCx, + mCurrentContext ? mCurrentContext->PrincipalOrNull() : nullptr); + CanvasRenderingContextHelper::ToBlob(aCx, callback, aType, aParams, spoofing, + aRv); return promise.forget(); } diff --git a/dom/canvas/nsICanvasRenderingContextInternal.h b/dom/canvas/nsICanvasRenderingContextInternal.h @@ -122,10 +122,10 @@ class nsICanvasRenderingContextInternal : public nsISupports, // If the image format does not support transparency or includeTransparency // is false, alpha will be discarded and the result will be the image // composited on black. - NS_IMETHOD GetInputStream( - const char* mimeType, const nsAString& encoderOptions, - mozilla::CanvasUtils::ImageExtraction extractionBehavior, - const nsACString& randomizationKey, nsIInputStream** stream) = 0; + NS_IMETHOD GetInputStream(const char* mimeType, + const nsAString& encoderOptions, + mozilla::CanvasUtils::ImageExtraction spoofing, + nsIInputStream** stream) = 0; // This gets an Azure SourceSurface for the canvas, this will be a snapshot // of the canvas at the time it was called. diff --git a/dom/html/HTMLCanvasElement.cpp b/dom/html/HTMLCanvasElement.cpp @@ -902,12 +902,12 @@ already_AddRefed<CanvasCaptureMediaStream> HTMLCanvasElement::CaptureStream( // Check site-specific permission and display prompt if appropriate. // If no permission, arrange for the frame capture listener to return // all-white, opaque image data. - CanvasUtils::ImageExtraction extractionBehaviour = + CanvasUtils::ImageExtraction spoofing = CanvasUtils::ImageExtractionResult(this, nullptr, &aSubjectPrincipal); rv = RegisterFrameCaptureListener( stream->FrameCaptureListener(), - extractionBehaviour == CanvasUtils::ImageExtraction::Placeholder); + spoofing == CanvasUtils::ImageExtraction::Placeholder); if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; @@ -923,10 +923,10 @@ nsresult HTMLCanvasElement::ExtractData(JSContext* aCx, nsIInputStream** aStream) { // Check site-specific permission and display prompt if appropriate. // If no permission, return all-white, opaque image data. - CanvasUtils::ImageExtraction extractionBehaviour = + CanvasUtils::ImageExtraction spoofing = CanvasUtils::ImageExtractionResult(this, aCx, &aSubjectPrincipal); - if (extractionBehaviour != CanvasUtils::ImageExtraction::Placeholder) { + if (spoofing != CanvasUtils::ImageExtraction::Placeholder) { auto size = GetWidthHeight(); CanvasContextType type = GetCurrentContextType(); CanvasFeatureUsage featureUsage = CanvasFeatureUsage::None; @@ -941,14 +941,7 @@ nsresult HTMLCanvasElement::ExtractData(JSContext* aCx, OwnerDoc()->RecordCanvasUsage(usage); } - nsCString randomizationKey = VoidCString(); - if (extractionBehaviour == CanvasUtils::ImageExtraction::EfficientRandomize) { - nsRFPService::GetFingerprintingRandomizationKeyAsString( - GetCookieJarSettings(), randomizationKey); - } - - return ImageEncoder::ExtractData(aType, aOptions, GetSize(), - extractionBehaviour, randomizationKey, + return ImageEncoder::ExtractData(aType, aOptions, GetSize(), spoofing, mCurrentContext, mOffscreenDisplay, aStream); } @@ -1043,7 +1036,7 @@ void HTMLCanvasElement::ToBlob(JSContext* aCx, BlobCallback& aCallback, // Check site-specific permission and display prompt if appropriate. // If no permission, return all-white, opaque image data. - CanvasUtils::ImageExtraction extractionBehaviour = + CanvasUtils::ImageExtraction spoofing = CanvasUtils::ImageExtractionResult(this, aCx, &aSubjectPrincipal); // Encoder callback when encoding is complete. @@ -1097,8 +1090,8 @@ void HTMLCanvasElement::ToBlob(JSContext* aCx, BlobCallback& aCallback, global, &aCallback, recheckCanRead ? mOffscreenDisplay.get() : nullptr, recheckCanRead ? &aSubjectPrincipal : nullptr); - CanvasRenderingContextHelper::ToBlob(aCx, callback, aType, aParams, - extractionBehaviour, aRv); + CanvasRenderingContextHelper::ToBlob(aCx, callback, aType, aParams, spoofing, + aRv); } OffscreenCanvas* HTMLCanvasElement::TransferControlToOffscreen( diff --git a/dom/media/imagecapture/CaptureTask.cpp b/dom/media/imagecapture/CaptureTask.cpp @@ -162,7 +162,7 @@ void CaptureTask::NotifyRealtimeTrackData(MediaTrackGraph* aGraph, nsAutoString options; rv = dom::ImageEncoder::ExtractDataFromLayersImageAsync( type, options, false, image, CanvasUtils::ImageExtraction::Unrestricted, - VoidCString(), new EncodeComplete(this)); + new EncodeComplete(this)); if (NS_FAILED(rv)) { PostTrackEndEvent(); } diff --git a/dom/webgpu/CanvasContext.cpp b/dom/webgpu/CanvasContext.cpp @@ -355,7 +355,7 @@ mozilla::UniquePtr<uint8_t[]> CanvasContext::GetImageBuffer( NS_IMETHODIMP CanvasContext::GetInputStream( const char* aMimeType, const nsAString& aEncoderOptions, mozilla::CanvasUtils::ImageExtraction aExtractionBehavior, - const nsACString& aRandomizationKey, nsIInputStream** aStream) { + nsIInputStream** aStream) { gfxAlphaType any; RefPtr<gfx::SourceSurface> snapshot = GetSurfaceSnapshot(&any); if (!snapshot) { diff --git a/dom/webgpu/CanvasContext.h b/dom/webgpu/CanvasContext.h @@ -60,7 +60,7 @@ class CanvasContext final : public nsICanvasRenderingContextInternal, NS_IMETHOD GetInputStream( const char* aMimeType, const nsAString& aEncoderOptions, mozilla::CanvasUtils::ImageExtraction aExtractionBehavior, - const nsACString& aRandomizationKey, nsIInputStream** aStream) override; + nsIInputStream** aStream) override; already_AddRefed<gfx::SourceSurface> GetSurfaceSnapshot( gfxAlphaType* aOutAlphaType) override; diff --git a/gfx/thebes/gfxUtils.cpp b/gfx/thebes/gfxUtils.cpp @@ -1126,7 +1126,7 @@ nsresult gfxUtils::EncodeSourceSurfaceAsStream(SourceSurface* aSurface, nsresult rv = encoder->InitFromData( map.mData, BufferSizeFromStrideAndHeight(map.mStride, size.height), size.width, size.height, map.mStride, imgIEncoder::INPUT_FORMAT_HOSTARGB, - aOutputOptions, VoidCString()); + aOutputOptions); dataSurface->Unmap(); if (NS_FAILED(rv)) { return NS_ERROR_FAILURE; @@ -1645,7 +1645,7 @@ nsresult gfxUtils::GetInputStream(gfx::DataSourceSurface* aSurface, return dom::ImageEncoder::GetInputStream( aSurface->GetSize().width, aSurface->GetSize().height, imageBuffer.get(), - format, encoder, aEncoderOptions, VoidCString(), outStream); + format, encoder, aEncoderOptions, outStream); } /* static */ @@ -1676,7 +1676,7 @@ nsresult gfxUtils::GetInputStreamWithRandomNoise( return dom::ImageEncoder::GetInputStream( aSurface->GetSize().width, aSurface->GetSize().height, imageBuffer.get(), - format, encoder, aEncoderOptions, VoidCString(), outStream); + format, encoder, aEncoderOptions, outStream); } class GetFeatureStatusWorkerRunnable final diff --git a/image/encoders/bmp/nsBMPEncoder.cpp b/image/encoders/bmp/nsBMPEncoder.cpp @@ -52,8 +52,7 @@ nsBMPEncoder::InitFromData(const uint8_t* aData, uint32_t aLength, // (unused, req'd by JS) uint32_t aWidth, uint32_t aHeight, uint32_t aStride, uint32_t aInputFormat, - const nsAString& aOutputOptions, - const nsACString& aRandomizationKey) { + const nsAString& aOutputOptions) { // validate input format if (aInputFormat != INPUT_FORMAT_RGB && aInputFormat != INPUT_FORMAT_RGBA && aInputFormat != INPUT_FORMAT_HOSTARGB) { diff --git a/image/encoders/ico/nsICOEncoder.cpp b/image/encoders/ico/nsICOEncoder.cpp @@ -45,8 +45,7 @@ NS_IMETHODIMP nsICOEncoder::InitFromData(const uint8_t* aData, uint32_t aLength, uint32_t aWidth, uint32_t aHeight, uint32_t aStride, uint32_t aInputFormat, - const nsAString& aOutputOptions, - const nsACString& aRandomizationKey) { + const nsAString& aOutputOptions) { // validate input format if (aInputFormat != INPUT_FORMAT_RGB && aInputFormat != INPUT_FORMAT_RGBA && aInputFormat != INPUT_FORMAT_HOSTARGB) { @@ -101,8 +100,7 @@ nsICOEncoder::AddImageFrame(const uint8_t* aData, uint32_t aLength, nsresult rv; nsAutoString noParams; rv = mContainedEncoder->InitFromData(aData, aLength, aWidth, aHeight, - aStride, aInputFormat, noParams, - VoidCString()); + aStride, aInputFormat, noParams); NS_ENSURE_SUCCESS(rv, rv); uint32_t PNGImageBufferSize; @@ -133,8 +131,7 @@ nsICOEncoder::AddImageFrame(const uint8_t* aData, uint32_t aLength, params.AppendInt(mICODirEntry.mBitCount); rv = mContainedEncoder->InitFromData(aData, aLength, aWidth, aHeight, - aStride, aInputFormat, params, - VoidCString()); + aStride, aInputFormat, params); NS_ENSURE_SUCCESS(rv, rv); uint32_t andMaskSize = ((GetRealWidth() + 31) / 32) * 4 * // row AND mask diff --git a/image/encoders/jpeg/nsJPEGEncoder.cpp b/image/encoders/jpeg/nsJPEGEncoder.cpp @@ -97,8 +97,7 @@ nsJPEGEncoder::InitFromData(const uint8_t* aData, uint32_t aLength, // (unused, req'd by JS) uint32_t aWidth, uint32_t aHeight, uint32_t aStride, uint32_t aInputFormat, - const nsAString& aOutputOptions, - const nsACString& aRandomizationKey) { + const nsAString& aOutputOptions) { NS_ENSURE_ARG(aData); // validate input format diff --git a/image/encoders/png/nsPNGEncoder.cpp b/image/encoders/png/nsPNGEncoder.cpp @@ -4,7 +4,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "ImageLogging.h" -#include "mozilla/XorShift128PlusRNG.h" #include "nsCRT.h" #include "nsPNGEncoder.h" #include "nsStreamUtils.h" @@ -26,13 +25,11 @@ NS_IMPL_ISUPPORTS(nsPNGEncoder, imgIEncoder, nsIInputStream, nsPNGEncoder::nsPNGEncoder() : mPNG(nullptr), mPNGinfo(nullptr), - mAddCustomMetadata(false), mIsAnimation(false), mFinished(false), mImageBuffer(nullptr), mImageBufferSize(0), mImageBufferUsed(0), - mImageBufferHash(0), mImageBufferReadPoint(0), mCallback(nullptr), mCallbackTarget(nullptr), @@ -63,16 +60,10 @@ nsPNGEncoder::InitFromData(const uint8_t* aData, uint32_t aLength, // (unused, req'd by JS) uint32_t aWidth, uint32_t aHeight, uint32_t aStride, uint32_t aInputFormat, - const nsAString& aOutputOptions, - const nsACString& aRandomizationKey) { + const nsAString& aOutputOptions) { NS_ENSURE_ARG(aData); nsresult rv; - MOZ_ASSERT_IF(aRandomizationKey.IsEmpty(), aRandomizationKey.IsVoid()); - if (!aRandomizationKey.IsEmpty()) { - mAddCustomMetadata = true; - } - rv = StartImageEncode(aWidth, aHeight, aInputFormat, aOutputOptions); if (!NS_SUCCEEDED(rv)) { return rv; @@ -84,11 +75,6 @@ nsPNGEncoder::InitFromData(const uint8_t* aData, return rv; } - rv = MaybeAddCustomMetadata(aRandomizationKey); - if (!NS_SUCCEEDED(rv)) { - return rv; - } - rv = EndImageEncode(); return rv; @@ -366,37 +352,6 @@ nsPNGEncoder::EndImageEncode() { return NS_OK; } -nsresult nsPNGEncoder::MaybeAddCustomMetadata( - const nsACString& aRandomizationKey) { - MOZ_ASSERT_IF(mAddCustomMetadata, !aRandomizationKey.IsEmpty()); - - if (!mAddCustomMetadata) { - return NS_OK; - } - - nsCString hex; - nsresult rv = nsRFPService::GenerateRandomizationKeyFromHash( - aRandomizationKey, mImageBufferHash, hex); - NS_ENSURE_SUCCESS(rv, rv); - - png_size_t chunkLength = 16; - png_unknown_chunk chunk; - chunk.name[0] = 'd'; - chunk.name[1] = 'e'; - chunk.name[2] = 'B'; - chunk.name[3] = 'G'; - chunk.name[4] = '\0'; - - chunk.data = reinterpret_cast<png_byte*>(hex.BeginWriting()); - chunk.size = chunkLength; - chunk.location = PNG_AFTER_IDAT; - - png_set_unknown_chunks(mPNG, mPNGinfo, &chunk, 1); - png_set_unknown_chunk_location(mPNG, mPNGinfo, 0, PNG_AFTER_IDAT); - - return NS_OK; -} - nsresult nsPNGEncoder::ParseOptions(const nsAString& aOptions, bool* useTransparency, bool* skipFirstFrame, uint32_t* numFrames, uint32_t* numPlays, @@ -821,10 +776,6 @@ nsPNGEncoder::WriteCallback(png_structp png, png_bytep data, png_size_t size) { } } - if (that->mAddCustomMetadata) { - that->mImageBufferHash = HashBytes(data, size, that->mImageBufferHash); - } - memcpy(&that->mImageBuffer[that->mImageBufferUsed], data, size); that->mImageBufferUsed += size; that->NotifyListener(); diff --git a/image/encoders/png/nsPNGEncoder.h b/image/encoders/png/nsPNGEncoder.h @@ -51,12 +51,10 @@ class nsPNGEncoder final : public imgIEncoder { static void WriteCallback(png_structp png, png_bytep data, png_size_t size); void NullOutImageBuffer(); void NotifyListener(); - nsresult MaybeAddCustomMetadata(const nsACString& aRandomizationKey); png_struct* mPNG; png_info* mPNGinfo; - bool mAddCustomMetadata; bool mIsAnimation; bool mFinished; @@ -64,7 +62,6 @@ class nsPNGEncoder final : public imgIEncoder { uint8_t* mImageBuffer; uint32_t mImageBufferSize; uint32_t mImageBufferUsed; - uint32_t mImageBufferHash; uint32_t mImageBufferReadPoint; diff --git a/image/encoders/webp/nsWebPEncoder.cpp b/image/encoders/webp/nsWebPEncoder.cpp @@ -50,8 +50,7 @@ nsWebPEncoder::InitFromData(const uint8_t* aData, uint32_t aLength, // (unused, req'd by JS) uint32_t aWidth, uint32_t aHeight, uint32_t aStride, uint32_t aInputFormat, - const nsAString& aOutputOptions, - const nsACString& aRandomizationKey) { + const nsAString& aOutputOptions) { NS_ENSURE_ARG(aData); // validate input format diff --git a/image/imgIEncoder.idl b/image/imgIEncoder.idl @@ -111,8 +111,7 @@ interface imgIEncoder : nsIAsyncInputStream in uint32_t height, in uint32_t stride, in uint32_t inputFormat, - in AString outputOptions, - in ACString randomizationKey); + in AString outputOptions); /* * For encoding images which may contain multiple frames, the 1-shot diff --git a/image/imgTools.cpp b/image/imgTools.cpp @@ -441,7 +441,7 @@ static nsresult EncodeImageData(DataSourceSurface* aDataSurface, // Encode the bitmap nsresult rv = encoder->InitFromData( aMap.GetData(), dataLength, size.width, size.height, aMap.GetStride(), - imgIEncoder::INPUT_FORMAT_HOSTARGB, aOutputOptions, VoidCString()); + imgIEncoder::INPUT_FORMAT_HOSTARGB, aOutputOptions); NS_ENSURE_SUCCESS(rv, rv); encoder.forget(aStream); diff --git a/media/libpng/pnglibconf.h b/media/libpng/pnglibconf.h @@ -148,9 +148,6 @@ #define PNG_STDIO_SUPPORTED #define PNG_eXIf_SUPPORTED #define PNG_READ_eXIf_SUPPORTED -#define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED -#define PNG_USER_CHUNKS_SUPPORTED -#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED #define PNG_CHECK_cHRM_SUPPORTED #define PNG_ERROR_TEXT_SUPPORTED diff --git a/mfbt/HashFunctions.cpp b/mfbt/HashFunctions.cpp @@ -13,9 +13,8 @@ namespace mozilla { -uint32_t HashBytes(const void* aBytes, size_t aLength, - HashNumber startingHash) { - uint32_t hash = startingHash; +uint32_t HashBytes(const void* aBytes, size_t aLength) { + uint32_t hash = 0; const char* b = reinterpret_cast<const char*>(aBytes); /* Walk word by word. */ diff --git a/mfbt/HashFunctions.h b/mfbt/HashFunctions.h @@ -327,8 +327,7 @@ template <typename WCharT, typename = typename std::enable_if< * same result out of HashBytes as you would out of HashString. */ [[nodiscard]] extern MFBT_API HashNumber HashBytes(const void* bytes, - size_t aLength, - HashNumber startingHash = 0); + size_t aLength); /** * A pseudorandom function mapping 32-bit integers to 32-bit integers. diff --git a/toolkit/components/resistfingerprinting/RFPTargets.inc b/toolkit/components/resistfingerprinting/RFPTargets.inc @@ -24,7 +24,6 @@ ITEM_VALUE(CanvasRandomization, 9) ITEM_VALUE(CanvasImageExtractionPrompt, 10) ITEM_VALUE(CanvasExtractionFromThirdPartiesIsBlocked, 11) ITEM_VALUE(CanvasExtractionBeforeUserInputIsBlocked, 12) -// See also EfficientCanvasRandomization = 76 below ITEM_VALUE(JSLocale, 13) @@ -107,7 +106,6 @@ ITEM_VALUE(MaxTouchPoints, 72) ITEM_VALUE(MaxTouchPointsCollapse, 73) ITEM_VALUE(NavigatorHWConcurrencyTiered,74) ITEM_VALUE(WebGLRandomization, 75) -ITEM_VALUE(EfficientCanvasRandomization, 76) /* diff --git a/toolkit/components/resistfingerprinting/nsRFPService.cpp b/toolkit/components/resistfingerprinting/nsRFPService.cpp @@ -1346,10 +1346,7 @@ nsresult nsRFPService::GetBrowsingSessionKey( RFPTarget::CanvasRandomization) && !nsContentUtils::ShouldResistFingerprinting( "Checking the target activation globally without local context", - RFPTarget::WebGLRandomization) && - !nsContentUtils::ShouldResistFingerprinting( - "Checking the target activation globally without local context", - RFPTarget::EfficientCanvasRandomization)) { + RFPTarget::WebGLRandomization)) { return NS_ERROR_NOT_AVAILABLE; } @@ -1451,9 +1448,7 @@ Maybe<nsTArray<uint8_t>> nsRFPService::GenerateKey(nsIChannel* aChannel) { if (!nsContentUtils::ShouldResistFingerprinting( aChannel, RFPTarget::CanvasRandomization) && !nsContentUtils::ShouldResistFingerprinting( - aChannel, RFPTarget::WebGLRandomization) && - !nsContentUtils::ShouldResistFingerprinting( - aChannel, RFPTarget::EfficientCanvasRandomization)) { + aChannel, RFPTarget::WebGLRandomization)) { return Nothing(); } auto sessionKeyStr = sessionKey.ToString(); @@ -2825,65 +2820,6 @@ uint32_t nsRFPService::CollapseMaxTouchPoints(uint32_t aMaxTouchPoints) { } /* static */ -void nsRFPService::GetFingerprintingRandomizationKeyAsString( - nsICookieJarSettings* aCookieJarSettings, - nsACString& aRandomizationKeyStr) { - NS_ENSURE_TRUE_VOID(aCookieJarSettings); - - nsTArray<uint8_t> randomizationKey(32); - nsresult rv = - aCookieJarSettings->GetFingerprintingRandomizationKey(randomizationKey); - NS_ENSURE_SUCCESS_VOID(rv); - - aRandomizationKeyStr.Assign( - reinterpret_cast<const char*>(randomizationKey.Elements()), - randomizationKey.Length()); -} - -/* static */ -nsresult nsRFPService::GenerateRandomizationKeyFromHash( - const nsACString& aRandomizationKeyStr, uint32_t aContentHash, - nsACString& aHex) { - MOZ_ASSERT(aHex.IsEmpty(), "aHex should be empty"); - - if (aRandomizationKeyStr.IsEmpty()) { - return NS_ERROR_INVALID_ARG; - } - - uint64_t k0 = *reinterpret_cast<const uint64_t*>(aRandomizationKeyStr.Data()); - uint64_t k1 = - *reinterpret_cast<const uint64_t*>(aRandomizationKeyStr.Data() + 8); - mozilla::HashCodeScrambler hcs(k0, k1); - mozilla::HashNumber hashResult = hcs.scramble(aContentHash); - - nsTArray<uint8_t> bufferKey(32); - - uint64_t digest = static_cast<uint64_t>(hashResult) << 32 | aContentHash; - non_crypto::XorShift128PlusRNG rng( - digest, - *reinterpret_cast<const uint64_t*>(aRandomizationKeyStr.Data() + 16)); - - for (size_t i = 0; i < 4; ++i) { - uint64_t val = rng.next(); - for (size_t j = 0; j < 8; ++j) { - uint8_t data = static_cast<uint8_t>((val >> (j * 8)) & 0xFF); - bufferKey.InsertElementAt((i * 8) + j, data); - } - } - - non_crypto::XorShift128PlusRNG rng1( - *reinterpret_cast<uint64_t*>(bufferKey.Elements()), - *reinterpret_cast<uint64_t*>(bufferKey.Elements() + 8)); - - uint64_t rand = rng1.next(); - - aHex.AppendPrintf("%016" PRIX64, rand); - MOZ_ASSERT(aHex.Length() == 16, "Expected 16 hex characters"); - - return NS_OK; -} - -/* static */ void nsRFPService::CalculateFontLocaleAllowlist() { static bool sAcceptLanguagesIsDirty = true; diff --git a/toolkit/components/resistfingerprinting/nsRFPService.h b/toolkit/components/resistfingerprinting/nsRFPService.h @@ -442,14 +442,6 @@ class nsRFPService final : public nsIObserver, public nsIRFPService { static Maybe<RFPTarget> TextToRFPTarget(const nsAString& aText); - static void GetFingerprintingRandomizationKeyAsString( - nsICookieJarSettings* aCookieJarSettings, - nsACString& aRandomizationKeyStr); - - static nsresult GenerateRandomizationKeyFromHash( - const nsACString& aRandomizationKeyStr, uint32_t aContentHash, - nsACString& aHex); - private: nsresult Init();