Bug 1409973 - Add tests for Date.toLocaleString and Intl.DateTimeFormat.format fingerprinting resistance draft
authorTom Ritter <tom@mozilla.com>
Tue, 23 Jan 2018 15:13:50 -0600
changeset 759619 196f500ffa1321c613783133cf7f531f3d748d54
parent 759123 41492f00c669b1e9d707c0c2d34f1f21f7ebc668
child 759620 a5335732601811a5ee4068159839744529588680
push id100406
push userbmo:tom@mozilla.com
push dateMon, 26 Feb 2018 04:17:42 +0000
bugs1409973
milestone60.0a1
Bug 1409973 - Add tests for Date.toLocaleString and Intl.DateTimeFormat.format fingerprinting resistance MozReview-Commit-ID: KxJHQ8xPDlp
browser/components/resistfingerprinting/moz.build
browser/components/resistfingerprinting/test/chrome/chrome.ini
browser/components/resistfingerprinting/test/chrome/test_bug1409973_date_time_format.html
--- a/browser/components/resistfingerprinting/moz.build
+++ b/browser/components/resistfingerprinting/moz.build
@@ -9,8 +9,12 @@ with Files("**"):
 
 BROWSER_CHROME_MANIFESTS += [
     'test/browser/browser.ini',
 ]
 
 MOCHITEST_MANIFESTS += [
     'test/mochitest/mochitest.ini',
 ]
+
+MOCHITEST_CHROME_MANIFESTS += [
+    'test/chrome/chrome.ini',
+]
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/browser/components/resistfingerprinting/test/chrome/chrome.ini
@@ -0,0 +1,6 @@
+[DEFAULT]
+support-files =
+  ../../../../../dom/imptests/testharness.js
+  ../../../../../dom/imptests/testharnessreport.js
+
+[test_bug1409973_date_time_format.html]
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/browser/components/resistfingerprinting/test/chrome/test_bug1409973_date_time_format.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+<script>
+  /* globals SpecialPowers, SimpleTest */
+  ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+  SimpleTest.waitForExplicitFinish();
+
+  const originalAvailable = Services.locale.getAvailableLocales();
+  const originalRequested = Services.locale.getRequestedLocales();
+  Services.locale.setAvailableLocales(["ko-KR"]);
+  Services.locale.setRequestedLocales(["ko-KR"]);
+
+  // First be sure we have a non-UTC timezone and a non en-US locale.
+  var setTimeZone = SpecialPowers.Cu.getJSTestingFunctions().setTimeZone;
+  setTimeZone("EST5EDT");
+  // Now sanity check the defaults
+  let date = new Date(2003, 4, 6, 2, 30, 15);
+  // These tests should pass, but we don't enable them because every time CLDR data changed,
+  // the test would start failing. We leave them here for future debugging.
+  // SimpleTest.is(date.toLocaleString(), "2003. 5. 6. 오전 2:30:15", "Sanity Check of toLocaleString");
+  // SimpleTest.is(date.toString(), "Tue May 06 2003 02:30:15 GMT-0400 (EDT)", "Sanity check of control timezone failed.");
+
+  let defaultOptions = new Intl.DateTimeFormat(undefined, {
+    month: "numeric", day: "numeric", year: "numeric", hour: "numeric", minute: "numeric", second: "numeric",
+    timeZoneName: "long"
+  }).resolvedOptions();
+  SimpleTest.is(defaultOptions.locale, "ko-KR", "defaultOptions Intl.DateTimeFormat.format.locale");
+  SimpleTest.is(defaultOptions.timeZone, "EST5EDT", "defaultOptions Intl.DateTimeFormat.format.timeZone");
+  SimpleTest.is(defaultOptions.timeZoneName, "long", "defaultOptions Intl.DateTimeFormat.format.timeZoneName");
+
+  // Then create output it as UTC en-US date string; which should be constant
+  const referenceLocaleString = date.toLocaleString("en-US", {timeZone: "UTC", timeZoneName: "long"});
+  let sanityCheck = new Intl.DateTimeFormat("en-us", {timeZone: "UTC", timeZoneName: "long"}).resolvedOptions();
+  SimpleTest.is(sanityCheck.locale, "en-US", "Sanity Check of Intl.DateTimeFormat.format.locale");
+  SimpleTest.is(sanityCheck.timeZone, "UTC", "Sanity Check of Intl.DateTimeFormat.format.timeZone");
+  SimpleTest.is(sanityCheck.timeZoneName, "long", "Sanity Check of Intl.DateTimeFormat.format.timeZoneName");
+
+  // Set preferences.
+  SpecialPowers.pushPrefEnv({
+    set: [
+      ["privacy.resistFingerprinting", true],
+      // In real world, this will be set if the user decides to spoof preferred languages by en-US.
+      ["javascript.use_us_english_locale", true]
+    ]
+  }, function() {
+    // Now confirm that calling toLocaleString with no arguements gives us UTC
+    SimpleTest.is(date.toLocaleString(undefined, {timeZoneName: "long"}), referenceLocaleString, "Date.toLocaleString");
+    // And that a no-options Intl.DateTimeFormat formatter looks correct too
+    let options = new Intl.DateTimeFormat(undefined, {
+      month: "numeric", day: "numeric", year: "numeric", hour: "numeric", minute: "numeric", second: "numeric",
+      timeZoneName: "long"
+    }).resolvedOptions();
+    SimpleTest.is(options.locale, "en-US", "Resist Fingerprinting Intl.DateTimeFormat.format.locale");
+    SimpleTest.is(options.timeZone, "UTC", "Resist Fingerprinting Intl.DateTimeFormat.format.timeZone");
+    SimpleTest.is(options.timeZoneName, "long", "Resist Fingerprinting Intl.DateTimeFormat.format.timeZoneName");
+
+    // Cleanup
+    Services.locale.setRequestedLocales(originalRequested);
+    Services.locale.setAvailableLocales(originalAvailable);
+    SimpleTest.finish();
+  });
+</script>