forked from mirrors/gecko-dev
Differential Revision: https://phabricator.services.mozilla.com/D58685 --HG-- extra : moz-landing-system : lando
452 lines
14 KiB
JavaScript
452 lines
14 KiB
JavaScript
/* 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 http://mozilla.org/MPL/2.0/. */
|
|
|
|
var classifierTester = {
|
|
URL_PATH:
|
|
"/browser/toolkit/components/url-classifier/tests/browser/flash_block_frame.html",
|
|
OBJECT_ID: "testObject",
|
|
IFRAME_ID: "testFrame",
|
|
FLASHBLOCK_ENABLE_PREF: "plugins.flashBlock.enabled",
|
|
FLASH_PLUGIN_USER_SETTING_PREF: "plugin.state.flash",
|
|
URLCLASSIFIER_DISALLOW_COMPLETIONS_PREF: "urlclassifier.disallow_completions",
|
|
FISSION_PREF: "fission.autostart",
|
|
NEVER_ACTIVATE_PREF_VALUE: 0,
|
|
ASK_TO_ACTIVATE_PREF_VALUE: 1,
|
|
ALWAYS_ACTIVATE_PREF_VALUE: 2,
|
|
|
|
dbUrls: [
|
|
{
|
|
url: "flashallow.example.com/",
|
|
db: "test-flashallow-simple",
|
|
pref: "urlclassifier.flashAllowTable",
|
|
},
|
|
{
|
|
url: "exception.flashallow.example.com/",
|
|
db: "testexcept-flashallow-simple",
|
|
pref: "urlclassifier.flashAllowExceptTable",
|
|
},
|
|
{
|
|
url: "flashblock.example.com/",
|
|
db: "test-flash-simple",
|
|
pref: "urlclassifier.flashTable",
|
|
},
|
|
{
|
|
url: "exception.flashblock.example.com/",
|
|
db: "testexcept-flash-simple",
|
|
pref: "urlclassifier.flashExceptTable",
|
|
},
|
|
{
|
|
url: "subdocument.example.com/",
|
|
db: "test-flashsubdoc-simple",
|
|
pref: "urlclassifier.flashSubDocTable",
|
|
},
|
|
{
|
|
url: "exception.subdocument.example.com/",
|
|
db: "testexcept-flashsubdoc-simple",
|
|
pref: "urlclassifier.flashSubDocExceptTable",
|
|
},
|
|
],
|
|
|
|
setPrefs({
|
|
setDBs = true,
|
|
flashBlockEnable = true,
|
|
flashSetting = classifierTester.ALWAYS_ACTIVATE_PREF_VALUE,
|
|
} = {}) {
|
|
if (setDBs) {
|
|
let DBs = [];
|
|
|
|
for (let dbData of classifierTester.dbUrls) {
|
|
Services.prefs.setCharPref(dbData.pref, dbData.db);
|
|
DBs.push(dbData.db);
|
|
}
|
|
|
|
let completions = Services.prefs.getCharPref(
|
|
classifierTester.URLCLASSIFIER_DISALLOW_COMPLETIONS_PREF
|
|
);
|
|
completions += "," + DBs.join(",");
|
|
Services.prefs.setCharPref(
|
|
classifierTester.URLCLASSIFIER_DISALLOW_COMPLETIONS_PREF,
|
|
completions
|
|
);
|
|
}
|
|
|
|
Services.prefs.setBoolPref(
|
|
classifierTester.FLASHBLOCK_ENABLE_PREF,
|
|
flashBlockEnable
|
|
);
|
|
Services.prefs.setIntPref(
|
|
classifierTester.FLASH_PLUGIN_USER_SETTING_PREF,
|
|
flashSetting
|
|
);
|
|
},
|
|
|
|
unsetPrefs() {
|
|
for (let dbData of classifierTester.dbUrls) {
|
|
Services.prefs.clearUserPref(dbData.pref);
|
|
}
|
|
|
|
Services.prefs.clearUserPref(
|
|
classifierTester.URLCLASSIFIER_DISALLOW_COMPLETIONS_PREF
|
|
);
|
|
Services.prefs.clearUserPref(classifierTester.FLASHBLOCK_ENABLE_PREF);
|
|
Services.prefs.clearUserPref(
|
|
classifierTester.FLASH_PLUGIN_USER_SETTING_PREF
|
|
);
|
|
},
|
|
|
|
// The |domains| property describes the domains of the nested documents making
|
|
// up the page. |domains[0]| represents the domain in the URL bar. The last
|
|
// domain in the list is the domain of the most deeply nested iframe.
|
|
// Only the plugin in the most deeply nested document will be checked.
|
|
testCases: [
|
|
{
|
|
name: "Unknown domain",
|
|
domains: ["http://example.com"],
|
|
expectedFlashClassification: "unknown",
|
|
},
|
|
{
|
|
name: "Nested unknown domains",
|
|
domains: ["http://example.com", "http://example.org"],
|
|
expectedFlashClassification: "unknown",
|
|
},
|
|
{
|
|
name: "Allowed domain",
|
|
domains: ["http://flashallow.example.com"],
|
|
expectedFlashClassification: "allowed",
|
|
},
|
|
{
|
|
name: "Allowed nested domain",
|
|
domains: ["http://example.com", "http://flashallow.example.com"],
|
|
expectedFlashClassification: "allowed",
|
|
},
|
|
{
|
|
name: "Subdocument of allowed domain",
|
|
domains: ["http://flashallow.example.com", "http://example.com"],
|
|
expectedFlashClassification: "allowed",
|
|
},
|
|
{
|
|
name: "Exception to allowed domain",
|
|
domains: ["http://exception.flashallow.example.com"],
|
|
expectedFlashClassification: "unknown",
|
|
},
|
|
{
|
|
name: "Blocked domain",
|
|
domains: ["http://flashblock.example.com"],
|
|
expectedFlashClassification: "denied",
|
|
},
|
|
{
|
|
name: "Nested blocked domain",
|
|
domains: ["http://example.com", "http://flashblock.example.com"],
|
|
expectedFlashClassification: "denied",
|
|
},
|
|
{
|
|
name: "Subdocument of blocked subdocument",
|
|
domains: [
|
|
"http://example.com",
|
|
"http://flashblock.example.com",
|
|
"http://example.com",
|
|
],
|
|
expectedFlashClassification: "denied",
|
|
},
|
|
{
|
|
name: "Blocked subdocument nested among in allowed documents",
|
|
domains: [
|
|
"http://flashallow.example.com",
|
|
"http://flashblock.example.com",
|
|
"http://flashallow.example.com",
|
|
],
|
|
expectedFlashClassification: "denied",
|
|
},
|
|
{
|
|
name: "Exception to blocked domain",
|
|
domains: ["http://exception.flashblock.example.com"],
|
|
expectedFlashClassification: "unknown",
|
|
},
|
|
{
|
|
name: "Sub-document blocked domain in top-level context",
|
|
domains: ["http://subdocument.example.com"],
|
|
expectedFlashClassification: "unknown",
|
|
},
|
|
{
|
|
name: "Sub-document blocked domain",
|
|
domains: ["http://example.com", "http://subdocument.example.com"],
|
|
expectedFlashClassification: "denied",
|
|
},
|
|
{
|
|
name: "Sub-document blocked domain in non-Third-Party context",
|
|
domains: [
|
|
"http://subdocument.example.com",
|
|
"http://subdocument.example.com",
|
|
],
|
|
expectedFlashClassification: "unknown",
|
|
},
|
|
{
|
|
name: "Sub-document blocked domain differing only by scheme",
|
|
domains: [
|
|
"http://subdocument.example.com",
|
|
"https://subdocument.example.com",
|
|
],
|
|
expectedFlashClassification: "denied",
|
|
},
|
|
{
|
|
name: "Sub-document blocked subdocument of an allowed domain",
|
|
domains: [
|
|
"http://flashallow.example.com",
|
|
"http://subdocument.example.com",
|
|
],
|
|
expectedFlashClassification: "denied",
|
|
},
|
|
{
|
|
name: "Subdocument of Sub-document blocked domain",
|
|
domains: [
|
|
"http://example.com",
|
|
"http://subdocument.example.com",
|
|
"http://example.com",
|
|
],
|
|
expectedFlashClassification: "denied",
|
|
},
|
|
{
|
|
name: "Sub-document exception in top-level context",
|
|
domains: ["http://exception.subdocument.example.com"],
|
|
expectedFlashClassification: "unknown",
|
|
},
|
|
{
|
|
name: "Sub-document blocked domain exception",
|
|
domains: [
|
|
"http://example.com",
|
|
"http://exception.subdocument.example.com",
|
|
],
|
|
expectedFlashClassification: "unknown",
|
|
},
|
|
],
|
|
|
|
// Returns null if this value should not be verified given the combination
|
|
// of inputs
|
|
expectedPluginFallbackType(classification, flashSetting) {
|
|
switch (classification) {
|
|
case "unknown":
|
|
if (flashSetting == classifierTester.ALWAYS_ACTIVATE_PREF_VALUE) {
|
|
return null;
|
|
} else if (
|
|
flashSetting == classifierTester.ASK_TO_ACTIVATE_PREF_VALUE
|
|
) {
|
|
return Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY;
|
|
} else if (flashSetting == classifierTester.NEVER_ACTIVATE_PREF_VALUE) {
|
|
return Ci.nsIObjectLoadingContent.PLUGIN_DISABLED;
|
|
}
|
|
break;
|
|
case "allowed":
|
|
if (flashSetting == classifierTester.NEVER_ACTIVATE_PREF_VALUE) {
|
|
return Ci.nsIObjectLoadingContent.PLUGIN_DISABLED;
|
|
}
|
|
return null;
|
|
case "denied":
|
|
return Ci.nsIObjectLoadingContent.PLUGIN_USER_DISABLED;
|
|
}
|
|
throw new Error("Invalid classification or flash setting");
|
|
},
|
|
|
|
// Returns null if this value should not be verified given the combination
|
|
// of inputs
|
|
expectedActivated(classification, flashSetting) {
|
|
switch (classification) {
|
|
case "unknown":
|
|
return flashSetting == classifierTester.ALWAYS_ACTIVATE_PREF_VALUE;
|
|
case "allowed":
|
|
return flashSetting != classifierTester.NEVER_ACTIVATE_PREF_VALUE;
|
|
case "denied":
|
|
return false;
|
|
}
|
|
throw new Error("Invalid classification or flash setting");
|
|
},
|
|
|
|
// Returns null if this value should not be verified given the combination
|
|
// of inputs
|
|
expectedHasRunningPlugin(classification, flashSetting) {
|
|
switch (classification) {
|
|
case "unknown":
|
|
return flashSetting == classifierTester.ALWAYS_ACTIVATE_PREF_VALUE;
|
|
case "allowed":
|
|
return flashSetting != classifierTester.NEVER_ACTIVATE_PREF_VALUE;
|
|
case "denied":
|
|
return false;
|
|
}
|
|
throw new Error("Invalid classification or flash setting");
|
|
},
|
|
|
|
// Returns null if this value should not be verified given the combination
|
|
// of inputs
|
|
expectedPluginListed(classification, flashSetting) {
|
|
if (
|
|
flashSetting == classifierTester.ASK_TO_ACTIVATE_PREF_VALUE &&
|
|
Services.prefs.getCharPref("plugins.navigator.hidden_ctp_plugin") ==
|
|
"Shockwave Flash"
|
|
) {
|
|
return false;
|
|
}
|
|
switch (classification) {
|
|
case "unknown":
|
|
case "allowed":
|
|
return flashSetting != classifierTester.NEVER_ACTIVATE_PREF_VALUE;
|
|
case "denied":
|
|
return false;
|
|
}
|
|
throw new Error("Invalid classification or flash setting");
|
|
},
|
|
|
|
buildTestCaseInNewTab(browser, testCase) {
|
|
return (async function() {
|
|
let iframeDomains = testCase.domains.slice();
|
|
let pageDomain = iframeDomains.shift();
|
|
let tab = await BrowserTestUtils.openNewForegroundTab(
|
|
browser,
|
|
pageDomain + classifierTester.URL_PATH
|
|
);
|
|
|
|
let depth = 0;
|
|
for (let domain of iframeDomains) {
|
|
// Firefox does not like to load the same page in its own iframe. Put some
|
|
// bogus query strings in the URL to make it happy.
|
|
let url =
|
|
domain +
|
|
classifierTester.URL_PATH +
|
|
"?date=" +
|
|
Date.now() +
|
|
"rand=" +
|
|
Math.random();
|
|
let domainLoaded = BrowserTestUtils.browserLoaded(
|
|
tab.linkedBrowser,
|
|
true,
|
|
url
|
|
);
|
|
|
|
await SpecialPowers.spawn(
|
|
tab.linkedBrowser,
|
|
[classifierTester.IFRAME_ID, url, depth],
|
|
(iframeId, url, depth) => {
|
|
let doc = content.document;
|
|
for (let i = 0; i < depth; ++i) {
|
|
doc = doc.getElementById(iframeId).contentDocument;
|
|
}
|
|
doc.getElementById(iframeId).src = url;
|
|
}
|
|
);
|
|
|
|
await domainLoaded;
|
|
++depth;
|
|
}
|
|
return tab;
|
|
})();
|
|
},
|
|
|
|
async getPluginInfo(browser, depth) {
|
|
async function fn(frame, iframeId, depth) {
|
|
return SpecialPowers.spawn(
|
|
frame,
|
|
[iframeId, depth, fn.toString()],
|
|
async (iframeId, depth, fnSource) => {
|
|
// eslint-disable-next-line no-eval
|
|
let fnGetIframePluginInfo = eval(`(() => (${fnSource}))()`);
|
|
|
|
let doc = content.document;
|
|
let win = content.window;
|
|
let frame = doc.getElementById(iframeId);
|
|
if (!frame) {
|
|
throw new Error("Unable to find iframe!");
|
|
}
|
|
if (depth != 0) {
|
|
return fnGetIframePluginInfo(
|
|
frame.contentWindow,
|
|
iframeId,
|
|
--depth
|
|
);
|
|
}
|
|
|
|
let pluginObj = doc.getElementById("testObject");
|
|
if (!(pluginObj instanceof Ci.nsIObjectLoadingContent)) {
|
|
throw new Error("Unable to find plugin!");
|
|
}
|
|
|
|
return {
|
|
pluginFallbackType: pluginObj.pluginFallbackType,
|
|
activated: pluginObj.activated,
|
|
hasRunningPlugin: pluginObj.hasRunningPlugin,
|
|
listed: "Shockwave Flash" in win.navigator.plugins,
|
|
flashClassification: doc.documentFlashClassification,
|
|
};
|
|
}
|
|
);
|
|
}
|
|
|
|
return fn(browser, classifierTester.IFRAME_ID, depth);
|
|
},
|
|
|
|
checkPluginInfo(pluginInfo, expectedClassification, flashSetting) {
|
|
// Flashblocking is disabled when fission is enabled, so all the classifications
|
|
// should be "unknown"
|
|
if (Services.prefs.getBoolPref(classifierTester.FISSION_PREF)) {
|
|
expectedClassification = "unknown";
|
|
}
|
|
|
|
// We've stopped allowing flash to be always activated, so check
|
|
// existing tests that attempt to do so get treated as using ask-to-activate.
|
|
if (flashSetting == classifierTester.ALWAYS_ACTIVATE_PREF_VALUE) {
|
|
flashSetting = classifierTester.ASK_TO_ACTIVATE_PREF_VALUE;
|
|
}
|
|
is(
|
|
pluginInfo.flashClassification,
|
|
expectedClassification,
|
|
"Page's classification should match expected"
|
|
);
|
|
|
|
let expectedPluginFallbackType = classifierTester.expectedPluginFallbackType(
|
|
pluginInfo.flashClassification,
|
|
flashSetting
|
|
);
|
|
if (expectedPluginFallbackType != null) {
|
|
is(
|
|
pluginInfo.pluginFallbackType,
|
|
expectedPluginFallbackType,
|
|
"Plugin should have the correct fallback type"
|
|
);
|
|
}
|
|
|
|
let expectedActivated = classifierTester.expectedActivated(
|
|
pluginInfo.flashClassification,
|
|
flashSetting
|
|
);
|
|
if (expectedActivated != null) {
|
|
is(
|
|
pluginInfo.activated,
|
|
expectedActivated,
|
|
"Plugin should have the correct activation"
|
|
);
|
|
}
|
|
|
|
let expectedHasRunningPlugin = classifierTester.expectedHasRunningPlugin(
|
|
pluginInfo.flashClassification,
|
|
flashSetting
|
|
);
|
|
if (expectedHasRunningPlugin != null) {
|
|
is(
|
|
pluginInfo.hasRunningPlugin,
|
|
expectedHasRunningPlugin,
|
|
"Plugin should have the correct 'plugin running' state"
|
|
);
|
|
}
|
|
|
|
let expectedPluginListed = classifierTester.expectedPluginListed(
|
|
pluginInfo.flashClassification,
|
|
flashSetting
|
|
);
|
|
if (expectedPluginListed != null) {
|
|
is(
|
|
pluginInfo.listed,
|
|
expectedPluginListed,
|
|
"Plugin's existance in navigator.plugins should match expected"
|
|
);
|
|
}
|
|
},
|
|
};
|
|
registerCleanupFunction(classifierTester.unsetPrefs);
|