Commit a4533eed authored by Pier Angelo Vendrame's avatar Pier Angelo Vendrame 🎃
Browse files

Bug 2038357 - Consider zoom when spoofing img srcset scaling. r=tjr

Ensure RFP-spoofed srcset scaling accounts for page zoom so that its
behavior matches the non-spoofed case.

Differential Revision: https://phabricator.services.mozilla.com/D300259
parent 676a2df5
Loading
Loading
Loading
Loading
+2 −1
Changes for dom/base/ResponsiveImageSelector.cpp: 2 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -352,7 +352,8 @@ bool ResponsiveImageSelector::SelectImage(bool aReselect) {
    displayDensity = overrideDPPX;
  }
  if (doc->ShouldResistFingerprinting(RFPTarget::WindowDevicePixelRatio)) {
    displayDensity = nsRFPService::GetDevicePixelRatioAtZoom(1);
    displayDensity =
        nsRFPService::GetDevicePixelRatioAtZoom(pctx->GetFullZoom());
  }

  // Per spec, "In a UA-specific manner, choose one image source"
+3 −0
Changes for toolkit/components/resistfingerprinting/tests/browser/browser.toml: 3 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ support-files = [
  "font-fingerprinter.html",
  "head-fpp-matrix.js",
  "head.js",
  "srcset.html",
  "scriptExecPage.html",
  "serviceWorker.js",
  "serviceWorkerTester.js",
@@ -60,6 +61,8 @@ support-files = ["file_pdf.pdf"]

["browser_service_worker_randomization_key_originattrs.js"]

["browser_srcset.js"]

["browser_usercharacteristics.js"]

["browser_usercharacteristics_gamepads.js"]
+61 −0
Changes for toolkit/components/resistfingerprinting/tests/browser/browser_srcset.js: 61 added lines, 0 removed lines.
Original line number Diff line number Diff line
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */

"use strict";

async function runForZoomLevel(tab, zoom) {
  const [dpr, scale] = await SpecialPowers.spawn(
    tab.linkedBrowser,
    [zoom],
    async zoom => {
      const img = content.document.getElementById("srcset");

      const { Layout } = ChromeUtils.importESModule(
        "chrome://mochitests/content/browser/accessible/tests/browser/Layout.sys.mjs"
      );
      Layout.zoomDocument(content.document, zoom);

      // The zoom change might trigger a new load. Be sure it is complete
      // before checking the scale.
      await new Promise(resolve => {
        img.addEventListener("error", resolve, { once: true });
        if (img.complete) {
          resolve();
        }
      });

      // Workaround: content.devicePixelRatio has the unspoofed value.
      const dpr = content.wrappedJSObject.devicePixelRatio;
      const current = img.currentSrc;
      const scale =
        current.substring(current.length - 6, current.length - 4) / 10;
      return [dpr, scale];
    }
  );

  is(
    Math.abs(dpr - scale) < 0.1,
    true,
    `Image scale (${scale}) is within DPR (${dpr})`
  );
}

add_task(async () => {
  await SpecialPowers.pushPrefEnv({
    set: [["privacy.resistFingerprinting", true]],
  });

  const testPage =
    getRootDirectory(gTestPath).replace(
      "chrome://mochitests/content",
      "https://example.com"
    ) + "srcset.html";
  const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, testPage);

  for (let zoom = 0.3; zoom < 2.09; zoom += 0.1) {
    await runForZoomLevel(tab, zoom);
  }

  BrowserTestUtils.removeTab(tab);
});
+12 −0
Changes for toolkit/components/resistfingerprinting/tests/browser/srcset.html: 12 added lines, 0 removed lines.
Original line number Diff line number Diff line
<!DOCTYPE html>
<html>
  <body>
    <img id="srcset" srcset="
        03.png 0.3x, 04.png 0.4x, 05.png 0.5x, 06.png 0.6x, 07.png 0.7x, 08.png 0.8x, 09.png 0.9x,
        10.png 1x, 11.png 1.1x, 12.png 1.2x, 13.png 1.3x, 14.png 1.4x, 15.png 1.5x, 16.png 1.6x, 17.png 1.7x, 18.png 1.8x, 19.png 1.9x,
        20.png 2x, 21.png 2.1x, 22.png 2.2x, 23.png 2.3x, 24.png 2.4x, 25.png 2.5x, 26.png 2.6x, 27.png 2.7x, 28.png 2.8x, 29.png 2.9x,
        30.png 3x, 31.png 3.1x, 32.png 3.2x, 33.png 3.3x, 34.png 3.4x, 35.png 3.5x, 36.png 3.6x, 37.png 3.7x, 38.png 3.8x, 39.png 3.9x,
        40.png 4x
      ">
  </body>
</html>