Verified Commit 442dcc5e authored by Fatih's avatar Fatih Committed by Pier Angelo Vendrame
Browse files

Bug 1912129: Reduce time precision for EXSLT date time function. r=timhuang

parent 79feae7c
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -198,3 +198,5 @@ lineno = "172"
lineno = "176"

["browser_exslt_timezone_load.js"]

["browser_exslt_time_precision.js"]
+71 −0
Original line number Diff line number Diff line
/**
 * Bug 1912129 - A test case for verifying EXSLT date will report second-precise
 *               time fingerprinting resistance is enabled.
 */

function getTime(tab) {
  const extractTime = function () {
    const xslText = `
    <xsl:stylesheet version="1.0"
                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    xmlns:date="http://exslt.org/dates-and-times"
                    extension-element-prefixes="date">
      <xsl:output method="text" />
      <xsl:template match="/">
        <xsl:value-of select="date:date-time()" />
      </xsl:template>
    </xsl:stylesheet>`;

    const parser = new DOMParser();
    const xsltProcessor = new XSLTProcessor();
    const xslStylesheet = parser.parseFromString(xslText, "application/xml");
    xsltProcessor.importStylesheet(xslStylesheet);
    const xmlDoc = parser.parseFromString("<test />", "application/xml");
    const styledDoc = xsltProcessor.transformToDocument(xmlDoc);
    const time = styledDoc.firstChild.textContent;

    return time;
  };

  const extractTimeExpr = `(${extractTime.toString()})();`;

  return SpecialPowers.spawn(
    tab.linkedBrowser,
    [extractTimeExpr],
    async funccode => content.eval(funccode)
  );
}

add_task(async function test_new_window() {
  await SpecialPowers.pushPrefEnv({
    set: [
      ["privacy.fingerprintingProtection", true],
      ["privacy.fingerprintingProtection.overrides", "+ReduceTimerPrecision"],
    ],
  });

  // Open a tab for extracting the time from XSLT.
  const tab = await BrowserTestUtils.openNewForegroundTab({
    gBrowser,
    opening: TEST_PATH + "file_dummy.html",
    forceNewProcess: true,
  });

  for (let i = 0; i < 10; i++) {
    // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
    await new Promise(res => setTimeout(res, 25));

    // The regex could be a lot shorter (e.g. /\.(\d{3})/) but I wrote the whole
    // thing to make sure the time is in the expected format and to allow us
    // to re-use this regex in the future if we need to.
    // Note: Date format is not locale dependent.
    const regex = /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.(\d{3})[-+]\d{2}:\d{2}/;
    const time = await getTime(tab);
    const [, milliseconds] = time.match(regex);

    is(milliseconds, "000", "Date's precision was reduced to seconds.");
  }

  BrowserTestUtils.removeTab(tab);
  await SpecialPowers.popPrefEnv();
});
+11 −4
Original line number Diff line number Diff line
@@ -593,12 +593,19 @@ nsresult txEXSLTFunctionCall::evaluate(txIEvalContext* aContext,
      Document* sourceDoc = getSourceDocument(aContext);
      NS_ENSURE_STATE(sourceDoc);

      PR_ExplodeTime(
          PR_Now(),
      PRTimeParamFn timezone =
          sourceDoc->ShouldResistFingerprinting(RFPTarget::JSDateTimeUTC)
              ? PR_GMTParameters
              : PR_LocalTimeParameters,
          &prtime);
              : PR_LocalTimeParameters;

      PRTime time =
          sourceDoc->ShouldResistFingerprinting(RFPTarget::ReduceTimerPrecision)
              ? (PRTime)nsRFPService::ReduceTimePrecisionAsSecs(
                    (double)PR_Now() / PR_USEC_PER_SEC, 0,
                    RTPCallerType::ResistFingerprinting) *
                    PR_USEC_PER_SEC
              : PR_Now();
      PR_ExplodeTime(time, timezone, &prtime);

      int32_t offset =
          (prtime.tm_params.tp_gmt_offset + prtime.tm_params.tp_dst_offset) /