Verified Commit 0151652b authored by Pier Angelo Vendrame's avatar Pier Angelo Vendrame 🎃 Committed by ma1
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 8955ffc7
Loading
Loading
Loading
Loading
+2 −1
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
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
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
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>