Global Metrics
path: .metrics.halstead.bugs
old: 4.566575196351224
new: 4.5708066528261595
path: .metrics.halstead.difficulty
old: 81.15116279069767
new: 81.23255813953489
path: .metrics.halstead.level
old: 0.012322682332712423
new: 0.012310334955625536
path: .metrics.halstead.length
old: 2585.0
new: 2586.0
path: .metrics.halstead.purity_ratio
old: 0.5461986366059473
new: 0.5459874229026966
path: .metrics.halstead.effort
old: 1603495.7095431597
new: 1605724.9602070637
path: .metrics.halstead.time
old: 89083.09497461998
new: 89206.94223372574
path: .metrics.halstead.N2
old: 997.0
new: 998.0
path: .metrics.halstead.volume
old: 19759.368250567662
new: 19767.012106757436
path: .metrics.mi.mi_sei
old: -58.41335855548763
new: -58.41626012744902
path: .metrics.mi.mi_original
old: -3.4768705709522294
new: -3.4788817873764515
Spaces Data
Minimal test - lines (278, 930)
path: .spaces[1].metrics.halstead.volume
old: 11778.825024881426
new: 11785.933549338204
path: .spaces[1].metrics.halstead.bugs
old: 2.645487189337893
new: 2.6493380277836787
path: .spaces[1].metrics.halstead.difficulty
old: 60.02586206896552
new: 60.12068965517241
path: .spaces[1].metrics.halstead.time
old: 39279.67368211176
new: 39365.46962312482
path: .spaces[1].metrics.halstead.level
old: 0.01665948585379865
new: 0.016633209062231143
path: .spaces[1].metrics.halstead.effort
old: 707034.1262780117
new: 708578.4532162468
path: .spaces[1].metrics.halstead.N2
old: 633.0
new: 634.0
path: .spaces[1].metrics.halstead.purity_ratio
old: 0.5393079607995286
new: 0.5389826845867424
path: .spaces[1].metrics.halstead.length
old: 1657.0
new: 1658.0
path: .spaces[1].metrics.mi.mi_original
old: 11.503345218859437
new: 11.500207963862309
path: .spaces[1].metrics.mi.mi_visual_studio
old: 6.727102467169261
new: 6.725267815124157
path: .spaces[1].metrics.mi.mi_sei
old: -41.34822162047297
new: -41.352747722699334
Code
add_task(async function test_privacy_other_prefs() {
registerCleanupFunction(() => {
Services.prefs.clearUserPref("security.tls.version.min");
Services.prefs.clearUserPref("security.tls.version.max");
});
const cookieSvc = Ci.nsICookieService;
// Create an object to hold the values to which we will initialize the prefs.
const SETTINGS = {
"network.webRTCIPHandlingPolicy": {
"media.peerconnection.ice.default_address_only": false,
"media.peerconnection.ice.no_host": false,
"media.peerconnection.ice.proxy_only_if_behind_proxy": false,
"media.peerconnection.ice.proxy_only": false,
},
"network.tlsVersionRestriction": {
"security.tls.version.min": tlsMinPref,
"security.tls.version.max": 4,
},
"network.peerConnectionEnabled": {
"media.peerconnection.enabled": true,
},
"services.passwordSavingEnabled": {
"signon.rememberSignons": true,
},
"websites.referrersEnabled": {
"network.http.sendRefererHeader": 2,
},
"websites.resistFingerprinting": {
"privacy.resistFingerprinting": true,
},
"websites.firstPartyIsolate": {
"privacy.firstparty.isolate": false,
},
"websites.cookieConfig": {
"network.cookie.cookieBehavior": cookieSvc.BEHAVIOR_ACCEPT,
"network.cookie.lifetimePolicy": cookieSvc.ACCEPT_NORMALLY,
},
};
let defaultPrefs = new Preferences({ defaultBranch: true });
let defaultCookieBehavior = defaultPrefs.get("network.cookie.cookieBehavior");
let defaultBehavior;
switch (defaultCookieBehavior) {
case cookieSvc.BEHAVIOR_ACCEPT:
defaultBehavior = "allow_all";
break;
case cookieSvc.BEHAVIOR_REJECT_FOREIGN:
defaultBehavior = "reject_third_party";
break;
case cookieSvc.BEHAVIOR_REJECT:
defaultBehavior = "reject_all";
break;
case cookieSvc.BEHAVIOR_LIMIT_FOREIGN:
defaultBehavior = "allow_visited";
break;
case cookieSvc.BEHAVIOR_REJECT_TRACKER:
defaultBehavior = "reject_trackers";
break;
case cookieSvc.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN:
defaultBehavior = "reject_trackers_and_partition_foreign";
break;
default:
ok(
false,
`Unexpected cookie behavior encountered: ${defaultCookieBehavior}`
);
break;
}
async function background() {
browser.test.onMessage.addListener(async (msg, ...args) => {
let data = args[0];
// The second argument is the end of the api name,
// e.g., "network.webRTCIPHandlingPolicy".
let apiObj = args[1].split(".").reduce((o, i) => o[i], browser.privacy);
let settingData;
switch (msg) {
case "set":
try {
await apiObj.set(data);
} catch (e) {
browser.test.sendMessage("settingThrowsException", {
message: e.message,
});
break;
}
settingData = await apiObj.get({});
browser.test.sendMessage("settingData", settingData);
break;
case "get":
settingData = await apiObj.get({});
browser.test.sendMessage("gettingData", settingData);
break;
}
});
}
// Set prefs to our initial values.
for (let setting in SETTINGS) {
for (let pref in SETTINGS[setting]) {
Preferences.set(pref, SETTINGS[setting][pref]);
}
}
registerCleanupFunction(() => {
// Reset the prefs.
for (let setting in SETTINGS) {
for (let pref in SETTINGS[setting]) {
Preferences.reset(pref);
}
}
});
await promiseStartupManager();
let extension = ExtensionTestUtils.loadExtension({
background,
manifest: {
permissions: ["privacy"],
},
useAddonManager: "temporary",
});
await extension.startup();
async function testSetting(setting, value, expected, expectedValue = value) {
extension.sendMessage("set", { value: value }, setting);
let data = await extension.awaitMessage("settingData");
deepEqual(
data.value,
expectedValue,
`Got expected result on setting ${setting} to ${uneval(value)}`
);
for (let pref in expected) {
equal(
Preferences.get(pref),
expected[pref],
`${pref} set correctly for ${expected[pref]}`
);
}
}
async function testSettingException(setting, value, expected) {
extension.sendMessage("set", { value: value }, setting);
let data = await extension.awaitMessage("settingThrowsException");
equal(data.message, expected);
}
async function testGetting(getting, expected, expectedValue) {
extension.sendMessage("get", null, getting);
let data = await extension.awaitMessage("gettingData");
deepEqual(
data.value,
expectedValue,
`Got expected result on getting ${getting}`
);
for (let pref in expected) {
equal(
Preferences.get(pref),
expected[pref],
`${pref} get correctly for ${expected[pref]}`
);
}
}
await testSetting(
"network.webRTCIPHandlingPolicy",
"default_public_and_private_interfaces",
{
"media.peerconnection.ice.default_address_only": true,
"media.peerconnection.ice.no_host": false,
"media.peerconnection.ice.proxy_only_if_behind_proxy": false,
"media.peerconnection.ice.proxy_only": false,
}
);
await testSetting(
"network.webRTCIPHandlingPolicy",
"default_public_interface_only",
{
"media.peerconnection.ice.default_address_only": true,
"media.peerconnection.ice.no_host": true,
"media.peerconnection.ice.proxy_only_if_behind_proxy": false,
"media.peerconnection.ice.proxy_only": false,
}
);
await testSetting(
"network.webRTCIPHandlingPolicy",
"disable_non_proxied_udp",
{
"media.peerconnection.ice.default_address_only": true,
"media.peerconnection.ice.no_host": true,
"media.peerconnection.ice.proxy_only_if_behind_proxy": true,
"media.peerconnection.ice.proxy_only": false,
}
);
await testSetting("network.webRTCIPHandlingPolicy", "proxy_only", {
"media.peerconnection.ice.default_address_only": false,
"media.peerconnection.ice.no_host": false,
"media.peerconnection.ice.proxy_only_if_behind_proxy": false,
"media.peerconnection.ice.proxy_only": true,
});
await testSetting("network.webRTCIPHandlingPolicy", "default", {
"media.peerconnection.ice.default_address_only": false,
"media.peerconnection.ice.no_host": false,
"media.peerconnection.ice.proxy_only_if_behind_proxy": false,
"media.peerconnection.ice.proxy_only": false,
});
await testSetting("network.peerConnectionEnabled", false, {
"media.peerconnection.enabled": false,
});
await testSetting("network.peerConnectionEnabled", true, {
"media.peerconnection.enabled": true,
});
await testSetting("websites.referrersEnabled", false, {
"network.http.sendRefererHeader": 0,
});
await testSetting("websites.referrersEnabled", true, {
"network.http.sendRefererHeader": 2,
});
await testSetting("websites.resistFingerprinting", false, {
"privacy.resistFingerprinting": false,
});
await testSetting("websites.resistFingerprinting", true, {
"privacy.resistFingerprinting": true,
});
await testSetting("websites.trackingProtectionMode", "always", {
"privacy.trackingprotection.enabled": true,
"privacy.trackingprotection.pbmode.enabled": true,
});
await testSetting("websites.trackingProtectionMode", "never", {
"privacy.trackingprotection.enabled": false,
"privacy.trackingprotection.pbmode.enabled": false,
});
await testSetting("websites.trackingProtectionMode", "private_browsing", {
"privacy.trackingprotection.enabled": false,
"privacy.trackingprotection.pbmode.enabled": true,
});
await testSetting("services.passwordSavingEnabled", false, {
"signon.rememberSignons": false,
});
await testSetting("services.passwordSavingEnabled", true, {
"signon.rememberSignons": true,
});
await testSetting(
"websites.cookieConfig",
{ behavior: "reject_third_party", nonPersistentCookies: true },
{
"network.cookie.cookieBehavior": cookieSvc.BEHAVIOR_REJECT_FOREIGN,
"network.cookie.lifetimePolicy": cookieSvc.ACCEPT_SESSION,
}
);
// A missing nonPersistentCookies property should default to false.
await testSetting(
"websites.cookieConfig",
{ behavior: "reject_third_party" },
{
"network.cookie.cookieBehavior": cookieSvc.BEHAVIOR_REJECT_FOREIGN,
"network.cookie.lifetimePolicy": cookieSvc.ACCEPT_NORMALLY,
},
{ behavior: "reject_third_party", nonPersistentCookies: false }
);
// A missing behavior property should reset the pref.
await testSetting(
"websites.cookieConfig",
{ nonPersistentCookies: true },
{
"network.cookie.cookieBehavior": defaultCookieBehavior,
"network.cookie.lifetimePolicy": cookieSvc.ACCEPT_SESSION,
},
{ behavior: defaultBehavior, nonPersistentCookies: true }
);
await testSetting(
"websites.cookieConfig",
{ behavior: "reject_all" },
{
"network.cookie.cookieBehavior": cookieSvc.BEHAVIOR_REJECT,
"network.cookie.lifetimePolicy": cookieSvc.ACCEPT_NORMALLY,
},
{ behavior: "reject_all", nonPersistentCookies: false }
);
await testSetting(
"websites.cookieConfig",
{ behavior: "allow_visited" },
{
"network.cookie.cookieBehavior": cookieSvc.BEHAVIOR_LIMIT_FOREIGN,
"network.cookie.lifetimePolicy": cookieSvc.ACCEPT_NORMALLY,
},
{ behavior: "allow_visited", nonPersistentCookies: false }
);
await testSetting(
"websites.cookieConfig",
{ behavior: "allow_all" },
{
"network.cookie.cookieBehavior": cookieSvc.BEHAVIOR_ACCEPT,
"network.cookie.lifetimePolicy": cookieSvc.ACCEPT_NORMALLY,
},
{ behavior: "allow_all", nonPersistentCookies: false }
);
await testSetting(
"websites.cookieConfig",
{ nonPersistentCookies: true },
{
"network.cookie.cookieBehavior": defaultCookieBehavior,
"network.cookie.lifetimePolicy": cookieSvc.ACCEPT_SESSION,
},
{ behavior: defaultBehavior, nonPersistentCookies: true }
);
await testSetting(
"websites.cookieConfig",
{ nonPersistentCookies: false },
{
"network.cookie.cookieBehavior": defaultCookieBehavior,
"network.cookie.lifetimePolicy": cookieSvc.ACCEPT_NORMALLY,
},
{ behavior: defaultBehavior, nonPersistentCookies: false }
);
await testSetting(
"websites.cookieConfig",
{ behavior: "reject_trackers" },
{
"network.cookie.cookieBehavior": cookieSvc.BEHAVIOR_REJECT_TRACKER,
"network.cookie.lifetimePolicy": cookieSvc.ACCEPT_NORMALLY,
},
{ behavior: "reject_trackers", nonPersistentCookies: false }
);
await testSetting(
"websites.cookieConfig",
{ behavior: "reject_trackers_and_partition_foreign" },
{
"network.cookie.cookieBehavior":
cookieSvc.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN,
"network.cookie.lifetimePolicy": cookieSvc.ACCEPT_NORMALLY,
},
{
behavior: "reject_trackers_and_partition_foreign",
nonPersistentCookies: false,
}
);
// 1. Can't enable FPI when cookie behavior is "reject_trackers_and_partition_foreign"
await testSettingException(
"websites.firstPartyIsolate",
true,
"Can't enable firstPartyIsolate when cookieBehavior is 'reject_trackers_and_partition_foreign'"
);
// 2. Change cookieConfig to reject_trackers should work normally.
await testSetting(
"websites.cookieConfig",
{ behavior: "reject_trackers" },
{
"network.cookie.cookieBehavior": cookieSvc.BEHAVIOR_REJECT_TRACKER,
"network.cookie.lifetimePolicy": cookieSvc.ACCEPT_NORMALLY,
},
{ behavior: "reject_trackers", nonPersistentCookies: false }
);
// 3. Enable FPI
await testSetting("websites.firstPartyIsolate", true, {
"privacy.firstparty.isolate": true,
});
// 4. When FPI is enabled, change setting to "reject_trackers_and_partition_foreign" is invalid
await testSettingException(
"websites.cookieConfig",
{ behavior: "reject_trackers_and_partition_foreign" },
"Invalid cookieConfig 'reject_trackers_and_partition_foreign' when firstPartyIsolate is enabled"
);
// 5. Set conflict settings manually and check prefs.
Preferences.set("network.cookie.cookieBehavior", 5);
await testGetting(
"websites.firstPartyIsolate",
{ "privacy.firstparty.isolate": true },
true
);
await testGetting(
"websites.cookieConfig",
{
"network.cookie.cookieBehavior":
cookieSvc.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN,
"network.cookie.lifetimePolicy": cookieSvc.ACCEPT_NORMALLY,
},
{
behavior: "reject_trackers_and_partition_foreign",
nonPersistentCookies: false,
}
);
// 6. It is okay to set current saved value.
await testSetting("websites.firstPartyIsolate", true, {
"privacy.firstparty.isolate": true,
});
await testSetting(
"websites.cookieConfig",
{ behavior: "reject_trackers_and_partition_foreign" },
{
"network.cookie.cookieBehavior":
cookieSvc.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN,
"network.cookie.lifetimePolicy": cookieSvc.ACCEPT_NORMALLY,
},
{
behavior: "reject_trackers_and_partition_foreign",
nonPersistentCookies: false,
}
);
await testSetting("websites.firstPartyIsolate", false, {
"privacy.firstparty.isolate": false,
});
await testSetting(
"network.tlsVersionRestriction",
{
minimum: "TLSv1.2",
maximum: "TLSv1.3",
},
{
"security.tls.version.min": 3,
"security.tls.version.max": 4,
}
);
// Single values
await testSetting(
"network.tlsVersionRestriction",
{
minimum: "TLSv1.3",
},
{
"security.tls.version.min": 4,
"security.tls.version.max": 4,
},
{
minimum: "TLSv1.3",
maximum: "TLSv1.3",
}
);
// Single values
await testSetting(
"network.tlsVersionRestriction",
{
minimum: "TLSv1.3",
},
{
"security.tls.version.min": 4,
"security.tls.version.max": 4,
},
{
minimum: "TLSv1.3",
maximum: "TLSv1.3",
}
);
// Invalid values.
await testSettingException(
"network.tlsVersionRestriction",
{
minimum: "invalid",
maximum: "invalid",
},
"Setting TLS version invalid is not allowed for security reasons."
);
// Invalid values.
await testSettingException(
"network.tlsVersionRestriction",
{
minimum: "invalid2",
},
"Setting TLS version invalid2 is not allowed for security reasons."
);
// Invalid values.
await testSettingException(
"network.tlsVersionRestriction",
{
maximum: "invalid3",
},
"Setting TLS version invalid3 is not allowed for security reasons."
);
await testSetting(
"network.tlsVersionRestriction",
{
minimum: "TLSv1.2",
},
{
"security.tls.version.min": 3,
"security.tls.version.max": 4,
},
{
minimum: "TLSv1.2",
maximum: "TLSv1.3",
}
);
await testSetting(
"network.tlsVersionRestriction",
{
maximum: "TLSv1.2",
},
{
"security.tls.version.min": tlsMinPref,
"security.tls.version.max": 3,
},
{
minimum: tlsMinVer,
maximum: "TLSv1.2",
}
);
// Not supported version.
if (tlsMinPref === 3) {
await testSettingException(
"network.tlsVersionRestriction",
{
minimum: "TLSv1",
},
"Setting TLS version TLSv1 is not allowed for security reasons."
);
await testSettingException(
"network.tlsVersionRestriction",
{
minimum: "TLSv1.1",
},
"Setting TLS version TLSv1.1 is not allowed for security reasons."
);
await testSettingException(
"network.tlsVersionRestriction",
{
maximum: "TLSv1",
},
"Setting TLS version TLSv1 is not allowed for security reasons."
);
await testSettingException(
"network.tlsVersionRestriction",
{
maximum: "TLSv1.1",
},
"Setting TLS version TLSv1.1 is not allowed for security reasons."
);
}
// Min vs Max
await testSettingException(
"network.tlsVersionRestriction",
{
minimum: "TLSv1.3",
maximum: "TLSv1.2",
},
"Setting TLS min version grater than the max version is not allowed."
);
// Min vs Max (with default max)
await testSetting(
"network.tlsVersionRestriction",
{
minimum: "TLSv1.2",
maximum: "TLSv1.2",
},
{
"security.tls.version.min": 3,
"security.tls.version.max": 3,
}
);
await testSettingException(
"network.tlsVersionRestriction",
{
minimum: "TLSv1.3",
},
"Setting TLS min version grater than the max version is not allowed."
);
// Max vs Min
await testSetting(
"network.tlsVersionRestriction",
{
minimum: "TLSv1.3",
maximum: "TLSv1.3",
},
{
"security.tls.version.min": 4,
"security.tls.version.max": 4,
}
);
await testSettingException(
"network.tlsVersionRestriction",
{
maximum: "TLSv1.2",
},
"Setting TLS max version lower than the min version is not allowed."
);
// Empty value.
await testSetting(
"network.tlsVersionRestriction",
{},
{
"security.tls.version.min": tlsMinPref,
"security.tls.version.max": 4,
},
{
minimum: tlsMinVer,
maximum: "TLSv1.3",
}
);
const HTTPS_ONLY_PREF_NAME = "dom.security.https_only_mode";
const HTTPS_ONLY_PBM_PREF_NAME = "dom.security.https_only_mode_pbm";
Preferences.set(HTTPS_ONLY_PREF_NAME, false);
Preferences.set(HTTPS_ONLY_PBM_PREF_NAME, false);
await testGetting("network.httpsOnlyMode", {}, "never");
Preferences.set(HTTPS_ONLY_PREF_NAME, true);
Preferences.set(HTTPS_ONLY_PBM_PREF_NAME, false);
await testGetting("network.httpsOnlyMode", {}, "always");
Preferences.set(HTTPS_ONLY_PREF_NAME, false);
Preferences.set(HTTPS_ONLY_PBM_PREF_NAME, true);
await testGetting("network.httpsOnlyMode", {}, "private_browsing");
// Please note that if https_only_mode = true, then
// https_only_mode_pbm has no effect.
Preferences.set(HTTPS_ONLY_PREF_NAME, true);
Preferences.set(HTTPS_ONLY_PBM_PREF_NAME, true);
await testGetting("network.httpsOnlyMode", {}, "always");
// trying to "set" should have no effect when readonly!
extension.sendMessage("set", { value: "never" }, "network.httpsOnlyMode");
let readOnlyData = await extension.awaitMessage("settingData");
equal(readOnlyData.value, "always");
equal(Preferences.get(HTTPS_ONLY_PREF_NAME), true);
equal(Preferences.get(HTTPS_ONLY_PBM_PREF_NAME), true);
await extension.unload();
await promiseShutdownManager();
});
Minimal test - lines (405, 420)
path: .spaces[1].spaces[3].metrics.halstead.difficulty
old: 12.0
new: 12.428571428571429
path: .spaces[1].spaces[3].metrics.halstead.purity_ratio
old: 1.5289288717057194
new: 1.5050393580853176
path: .spaces[1].spaces[3].metrics.halstead.N2
old: 28.0
new: 29.0
path: .spaces[1].spaces[3].metrics.halstead.volume
old: 296.1277022428888
new: 300.82814196102987
path: .spaces[1].spaces[3].metrics.halstead.time
old: 197.4184681619259
new: 207.71466944928252
path: .spaces[1].spaces[3].metrics.halstead.effort
old: 3553.532426914666
new: 3738.8640500870856
path: .spaces[1].spaces[3].metrics.halstead.length
old: 63.0
new: 64.0
path: .spaces[1].spaces[3].metrics.halstead.bugs
old: 0.07762213797699279
new: 0.08029808620179398
path: .spaces[1].spaces[3].metrics.halstead.level
old: 0.08333333333333333
new: 0.08045977011494253
path: .spaces[1].spaces[3].metrics.mi.mi_sei
old: 63.047606628992725
new: 62.929462231192275
path: .spaces[1].spaces[3].metrics.mi.mi_visual_studio
old: 56.15903544049458
new: 56.11114570000667
path: .spaces[1].spaces[3].metrics.mi.mi_original
old: 96.03195060324572
new: 95.9500591470114
Code
async function testSetting(setting, value, expected, expectedValue = value) {
extension.sendMessage("set", { value: value }, setting);
let data = await extension.awaitMessage("settingData");
deepEqual(
data.value,
expectedValue,
`Got expected result on setting ${setting} to ${uneval(value)}`
);
for (let pref in expected) {
equal(
Preferences.get(pref),
expected[pref],
`${pref} set correctly for ${expected[pref]}`
);
}
}