--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -13173,22 +13173,21 @@ ArrayContainsTable(const nsTArray<nsCStr
*
* For more information, see
* toolkit/components/url-classifier/flash-block-lists.rst
*/
FlashClassification
nsDocument::PrincipalFlashClassification()
{
nsresult rv;
- bool isThirdPartyDoc = IsThirdParty();
// If flash blocking is disabled, it is equivalent to all sites being
- // whitelisted.
+ // on neither list.
if (!Preferences::GetBool("plugins.flashBlock.enabled")) {
- return FlashClassification::Allowed;
+ return FlashClassification::Unknown;
}
nsCOMPtr<nsIPrincipal> principal = GetPrincipal();
if (principal->GetIsNullPrincipal()) {
return FlashClassification::Denied;
}
nsCOMPtr<nsIURI> classificationURI;
@@ -13206,16 +13205,18 @@ nsDocument::PrincipalFlashClassification
Preferences::GetCString("urlclassifier.flashAllowExceptTable",
&allowExceptionsTables);
MaybeAddTableToTableList(allowExceptionsTables, tables);
Preferences::GetCString("urlclassifier.flashTable", &denyTables);
MaybeAddTableToTableList(denyTables, tables);
Preferences::GetCString("urlclassifier.flashExceptTable",
&denyExceptionsTables);
MaybeAddTableToTableList(denyExceptionsTables, tables);
+
+ bool isThirdPartyDoc = IsThirdParty();
if (isThirdPartyDoc) {
Preferences::GetCString("urlclassifier.flashSubDocTable",
&subDocDenyTables);
MaybeAddTableToTableList(subDocDenyTables, tables);
Preferences::GetCString("urlclassifier.flashSubDocExceptTable",
&subDocDenyExceptionsTables);
MaybeAddTableToTableList(subDocDenyExceptionsTables, tables);
}
--- a/dom/base/nsObjectLoadingContent.cpp
+++ b/dom/base/nsObjectLoadingContent.cpp
@@ -3269,17 +3269,17 @@ nsObjectLoadingContent::ShouldPlay(Fallb
return false;
}
nsCOMPtr<nsPIDOMWindowOuter> topWindow = window->GetTop();
NS_ENSURE_TRUE(topWindow, false);
nsCOMPtr<nsIDocument> topDoc = topWindow->GetDoc();
NS_ENSURE_TRUE(topDoc, false);
// Check the flash blocking status for this page (this applies to Flash only)
- FlashClassification documentClassification = FlashClassification::Allowed;
+ FlashClassification documentClassification = FlashClassification::Unknown;
if (IsFlashMIME(mContentType)) {
documentClassification = ownerDoc->DocumentFlashClassification();
}
if (documentClassification == FlashClassification::Denied) {
aReason = eFallbackSuppressed;
return false;
}
@@ -3344,20 +3344,26 @@ nsObjectLoadingContent::ShouldPlay(Fallb
return false;
}
if (PreferFallback(enabledState == nsIPluginTag::STATE_CLICKTOPLAY)) {
aReason = eFallbackAlternate;
return false;
}
+ // On the following switch we don't need to handle the case where
+ // documentClassification is FlashClassification::Denied because
+ // that's already handled above.
switch (enabledState) {
case nsIPluginTag::STATE_ENABLED:
- return documentClassification == FlashClassification::Allowed;
+ return true;
case nsIPluginTag::STATE_CLICKTOPLAY:
+ if (documentClassification == FlashClassification::Allowed) {
+ return true;
+ }
return false;
}
MOZ_CRASH("Unexpected enabledState");
}
bool
nsObjectLoadingContent::FavorFallbackMode(bool aIsPluginClickToPlay) {
if (!IsFlashMIME(mContentType)) {
--- a/toolkit/components/url-classifier/tests/browser/browser.ini
+++ b/toolkit/components/url-classifier/tests/browser/browser.ini
@@ -1,6 +1,13 @@
[DEFAULT]
support-files =
flash_block_frame.html
classifierHelper.js
+ classifierTester.js
-[browser_flash_block_lists.js]
+[browser_flashblock_on_with_never_activate.js]
+[browser_flashblock_off_with_never_activate.js]
+[browser_flashblock_on_with_ask_to_activate.js]
+[browser_flashblock_off_with_ask_to_activate.js]
+[browser_flashblock_on_with_always_activate.js]
+[browser_flashblock_off_with_always_activate.js]
+
deleted file mode 100644
--- a/toolkit/components/url-classifier/tests/browser/browser_flash_block_lists.js
+++ /dev/null
@@ -1,364 +0,0 @@
-/* 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/. */
-"use strict";
-requestLongerTimeout(3);
-
-var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-Cu.import("resource://gre/modules/Task.jsm");
-Cc["@mozilla.org/moz/jssubscript-loader;1"]
- .getService(Ci.mozIJSSubScriptLoader)
- .loadSubScript("chrome://mochitests/content/browser/toolkit/components/url-classifier/tests/browser/classifierHelper.js",
- this);
-
-const URL_PATH = "/browser/toolkit/components/url-classifier/tests/browser/flash_block_frame.html";
-const OBJECT_ID = "testObject";
-const IFRAME_ID = "testFrame";
-const FLASHBLOCK_ENABLE_PREF = "plugins.flashBlock.enabled";
-
-var 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.flashThirdPartyTable"
- },
- {
- url: "exception.subdocument.example.com/",
- db: "testexcept-flashsubdoc-simple",
- pref: "urlclassifier.flashThirdPartyExceptTable"
- }
-];
-
-function setDBPrefs() {
- for (let dbData of dbUrls) {
- Services.prefs.setCharPref(dbData.pref, dbData.db);
- }
- Services.prefs.setBoolPref(FLASHBLOCK_ENABLE_PREF, true);
-}
-
-function unsetDBPrefs() {
- for (let dbData of dbUrls) {
- Services.prefs.clearUserPref(dbData.pref);
- }
- Services.prefs.clearUserPref(FLASHBLOCK_ENABLE_PREF);
-}
-registerCleanupFunction(unsetDBPrefs);
-
-// 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.
-var testCases = [
- {
- name: "Unknown domain",
- domains: ["http://example.com"],
- expectedPluginFallbackType: Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY,
- expectedActivated: false,
- expectedHasRunningPlugin: false,
- pluginListed: true,
- expectedFlashClassification: "unknown"
- },
- {
- name: "Nested unknown domains",
- domains: ["http://example.com", "http://example.org"],
- expectedPluginFallbackType: Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY,
- expectedActivated: false,
- expectedHasRunningPlugin: false,
- pluginListed: true,
- expectedFlashClassification: "unknown"
- },
- {
- name: "Allowed domain",
- domains: ["http://flashallow.example.com"],
- expectedActivated: true,
- expectedHasRunningPlugin: true,
- pluginListed: true,
- expectedFlashClassification: "allowed"
- },
- {
- name: "Allowed nested domain",
- domains: ["http://example.com", "http://flashallow.example.com"],
- expectedActivated: true,
- expectedHasRunningPlugin: true,
- pluginListed: true,
- expectedFlashClassification: "allowed"
- },
- {
- name: "Subdocument of allowed domain",
- domains: ["http://flashallow.example.com", "http://example.com"],
- expectedActivated: true,
- expectedHasRunningPlugin: true,
- pluginListed: true,
- expectedFlashClassification: "allowed"
- },
- {
- name: "Exception to allowed domain",
- domains: ["http://exception.flashallow.example.com"],
- expectedPluginFallbackType: Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY,
- expectedActivated: false,
- expectedHasRunningPlugin: false,
- pluginListed: true,
- expectedFlashClassification: "unknown"
- },
- {
- name: "Blocked domain",
- domains: ["http://flashblock.example.com"],
- expectedPluginFallbackType: Ci.nsIObjectLoadingContent.PLUGIN_USER_DISABLED,
- expectedActivated: false,
- expectedHasRunningPlugin: false,
- pluginListed: false,
- expectedFlashClassification: "denied"
- },
- {
- name: "Nested blocked domain",
- domains: ["http://example.com", "http://flashblock.example.com"],
- expectedPluginFallbackType: Ci.nsIObjectLoadingContent.PLUGIN_USER_DISABLED,
- expectedActivated: false,
- expectedHasRunningPlugin: false,
- pluginListed: false,
- expectedFlashClassification: "denied"
- },
- {
- name: "Subdocument of blocked subdocument",
- domains: ["http://example.com", "http://flashblock.example.com", "http://example.com"],
- expectedPluginFallbackType: Ci.nsIObjectLoadingContent.PLUGIN_USER_DISABLED,
- expectedActivated: false,
- expectedHasRunningPlugin: false,
- pluginListed: false,
- expectedFlashClassification: "denied"
- },
- {
- name: "Blocked subdocument nested among in allowed documents",
- domains: ["http://flashallow.example.com", "http://flashblock.example.com", "http://flashallow.example.com"],
- expectedPluginFallbackType: Ci.nsIObjectLoadingContent.PLUGIN_USER_DISABLED,
- expectedActivated: false,
- expectedHasRunningPlugin: false,
- pluginListed: false,
- expectedFlashClassification: "denied"
- },
- {
- name: "Exception to blocked domain",
- domains: ["http://exception.flashblock.example.com"],
- expectedPluginFallbackType: Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY,
- expectedActivated: false,
- expectedHasRunningPlugin: false,
- pluginListed: true,
- expectedFlashClassification: "unknown"
- },
- {
- name: "Sub-document blocked domain in top-level context",
- domains: ["http://subdocument.example.com"],
- expectedPluginFallbackType: Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY,
- expectedActivated: false,
- expectedHasRunningPlugin: false,
- pluginListed: true,
- expectedFlashClassification: "unknown"
- },
- {
- name: "Sub-document blocked domain",
- domains: ["http://example.com", "http://subdocument.example.com"],
- expectedPluginFallbackType: Ci.nsIObjectLoadingContent.PLUGIN_USER_DISABLED,
- expectedActivated: false,
- expectedHasRunningPlugin: false,
- pluginListed: false,
- expectedFlashClassification: "denied"
- },
- {
- name: "Sub-document blocked domain in non-Third-Party context",
- domains: ["http://subdocument.example.com", "http://subdocument.example.com"],
- expectedPluginFallbackType: Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY,
- expectedActivated: false,
- expectedHasRunningPlugin: false,
- pluginListed: true,
- expectedFlashClassification: "unknown"
- },
- {
- name: "Sub-document blocked domain differing only by scheme",
- domains: ["http://subdocument.example.com", "https://subdocument.example.com"],
- expectedPluginFallbackType: Ci.nsIObjectLoadingContent.PLUGIN_USER_DISABLED,
- expectedActivated: false,
- expectedHasRunningPlugin: false,
- pluginListed: false,
- expectedFlashClassification: "denied"
- },
- {
- name: "Sub-document blocked subdocument of an allowed domain",
- domains: ["http://flashallow.example.com", "http://subdocument.example.com"],
- expectedPluginFallbackType: Ci.nsIObjectLoadingContent.PLUGIN_USER_DISABLED,
- expectedActivated: false,
- expectedHasRunningPlugin: false,
- pluginListed: false,
- expectedFlashClassification: "denied"
- },
- {
- name: "Subdocument of Sub-document blocked domain",
- domains: ["http://example.com", "http://subdocument.example.com", "http://example.com"],
- expectedPluginFallbackType: Ci.nsIObjectLoadingContent.PLUGIN_USER_DISABLED,
- expectedActivated: false,
- expectedHasRunningPlugin: false,
- pluginListed: false,
- expectedFlashClassification: "denied"
- },
- {
- name: "Sub-document exception in top-level context",
- domains: ["http://exception.subdocument.example.com"],
- expectedPluginFallbackType: Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY,
- expectedActivated: false,
- expectedHasRunningPlugin: false,
- pluginListed: true,
- expectedFlashClassification: "unknown"
- },
- {
- name: "Sub-document blocked domain exception",
- domains: ["http://example.com", "http://exception.subdocument.example.com"],
- expectedPluginFallbackType: Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY,
- expectedActivated: false,
- expectedHasRunningPlugin: false,
- pluginListed: true,
- expectedFlashClassification: "unknown"
- }
-];
-
-function buildDocumentStructure(browser, iframeDomains) {
- return Task.spawn(function* () {
- 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 + URL_PATH + "?date=" + Date.now() + "rand=" + Math.random();
- let domainLoaded = BrowserTestUtils.browserLoaded(browser, true, url);
-
- ContentTask.spawn(browser, {iframeId: IFRAME_ID, url: url, depth: depth},
- function*({iframeId, url, depth}) {
- let doc = content.document;
- for (let i = 0; i < depth; ++i) {
- doc = doc.getElementById(iframeId).contentDocument;
- }
- doc.getElementById(iframeId).src = url;
- });
-
- yield domainLoaded;
- ++depth;
- }
- });
-}
-
-function getPluginInfo(browser, depth) {
- return ContentTask.spawn(browser,
- {iframeId: IFRAME_ID, depth: depth},
- function* ({iframeId, depth}) {
- let doc = content.document;
- let win = content.window;
- for (let i = 0; i < depth; ++i) {
- let frame = doc.getElementById(iframeId);
- doc = frame.contentDocument;
- win = frame.contentWindow;
- }
-
- 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
- };
- });
-}
-
-add_task(function* checkFlashBlockLists() {
- setDBPrefs();
-
- yield classifierHelper.waitForInit();
- yield classifierHelper.addUrlToDB(dbUrls);
-
- for (let testCase of testCases) {
- info(`RUNNING TEST: ${testCase.name}`);
-
- let iframeDomains = testCase.domains.slice();
- let pageDomain = iframeDomains.shift();
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser,
- pageDomain + URL_PATH);
-
- yield buildDocumentStructure(tab.linkedBrowser, iframeDomains);
-
- let pluginInfo = yield getPluginInfo(tab.linkedBrowser, iframeDomains.length);
-
- if ("expectedPluginFallbackType" in testCase) {
- is(pluginInfo.pluginFallbackType, testCase.expectedPluginFallbackType,
- "Plugin should have the correct fallback type");
- }
- if ("expectedActivated" in testCase) {
- is(pluginInfo.activated, testCase.expectedActivated,
- "Plugin should have the correct activation");
- }
- if ("expectedHasRunningPlugin" in testCase) {
- is(pluginInfo.hasRunningPlugin, testCase.expectedHasRunningPlugin,
- "Plugin should have the correct 'plugin running' state");
- }
- if ("pluginListed" in testCase) {
- is(pluginInfo.listed, testCase.pluginListed,
- "Plugin's existance in navigator.plugins should match expected")
- }
- if ("expectedFlashClassification" in testCase) {
- is(pluginInfo.flashClassification, testCase.expectedFlashClassification,
- "Page's classification should match expected");
- }
-
- yield BrowserTestUtils.removeTab(tab);
- }
-});
-
-add_task(function* checkFlashBlockDisabled() {
- setDBPrefs();
- Services.prefs.setBoolPref(FLASHBLOCK_ENABLE_PREF, false);
-
- yield classifierHelper.waitForInit();
- yield classifierHelper.addUrlToDB(dbUrls);
-
- for (let testCase of testCases) {
- info(`RUNNING TEST: ${testCase.name} (flashblock disabled)`);
-
- let iframeDomains = testCase.domains.slice();
- let pageDomain = iframeDomains.shift();
- let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser,
- pageDomain + URL_PATH);
-
- yield buildDocumentStructure(tab.linkedBrowser, iframeDomains);
-
- let pluginInfo = yield getPluginInfo(tab.linkedBrowser, iframeDomains.length);
-
- // With flashblock disabled, all plugins should be activated.
- ok(pluginInfo.activated, "Plugin should be activated");
- ok(pluginInfo.hasRunningPlugin, "Plugin should be running");
- ok(pluginInfo.listed, "Flash should be listed in navigator.plugins");
- is(pluginInfo.flashClassification, "allowed",
- "Page's classification should be 'allowed'");
-
- yield BrowserTestUtils.removeTab(tab);
- }
-});
new file mode 100644
--- /dev/null
+++ b/toolkit/components/url-classifier/tests/browser/browser_flashblock_off_with_always_activate.js
@@ -0,0 +1,43 @@
+/* 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/. */
+"use strict";
+requestLongerTimeout(2);
+
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+
+Cu.import("resource://gre/modules/Task.jsm");
+const scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
+ getService(Ci.mozIJSSubScriptLoader);
+scriptLoader.loadSubScript(
+ "chrome://mochitests/content/browser/toolkit/components/url-classifier/tests/browser/classifierHelper.js",
+ this);
+scriptLoader.loadSubScript(
+ "chrome://mochitests/content/browser/toolkit/components/url-classifier/tests/browser/classifierTester.js",
+ this);
+
+add_task(function* checkFlashBlockLists() {
+ classifierTester.setPrefs({
+ setDBs: true,
+ flashBlockEnable: false,
+ flashSetting: classifierTester.ALWAYS_ACTIVATE_PREF_VALUE
+ });
+
+ yield classifierHelper.waitForInit();
+ yield classifierHelper.addUrlToDB(classifierTester.dbUrls);
+
+ for (let testCase of classifierTester.testCases) {
+ info(`RUNNING TEST: ${testCase.name} (Ask to Activate, Flashblock off)`);
+ let tab = yield classifierTester.buildTestCaseInNewTab(gBrowser, testCase);
+
+ let depth = testCase.domains.length - 1;
+ let pluginInfo = yield classifierTester.getPluginInfo(tab.linkedBrowser,
+ depth);
+
+ classifierTester.checkPluginInfo(pluginInfo,
+ "unknown",
+ classifierTester.ALWAYS_ACTIVATE_PREF_VALUE);
+
+ yield BrowserTestUtils.removeTab(tab);
+ }
+});
new file mode 100644
--- /dev/null
+++ b/toolkit/components/url-classifier/tests/browser/browser_flashblock_off_with_ask_to_activate.js
@@ -0,0 +1,43 @@
+/* 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/. */
+"use strict";
+requestLongerTimeout(2);
+
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+
+Cu.import("resource://gre/modules/Task.jsm");
+const scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
+ getService(Ci.mozIJSSubScriptLoader);
+scriptLoader.loadSubScript(
+ "chrome://mochitests/content/browser/toolkit/components/url-classifier/tests/browser/classifierHelper.js",
+ this);
+scriptLoader.loadSubScript(
+ "chrome://mochitests/content/browser/toolkit/components/url-classifier/tests/browser/classifierTester.js",
+ this);
+
+add_task(function* checkFlashBlockLists() {
+ classifierTester.setPrefs({
+ setDBs: true,
+ flashBlockEnable: false,
+ flashSetting: classifierTester.ASK_TO_ACTIVATE_PREF_VALUE
+ });
+
+ yield classifierHelper.waitForInit();
+ yield classifierHelper.addUrlToDB(classifierTester.dbUrls);
+
+ for (let testCase of classifierTester.testCases) {
+ info(`RUNNING TEST: ${testCase.name} (Ask to Activate, Flashblock off)`);
+ let tab = yield classifierTester.buildTestCaseInNewTab(gBrowser, testCase);
+
+ let depth = testCase.domains.length - 1;
+ let pluginInfo = yield classifierTester.getPluginInfo(tab.linkedBrowser,
+ depth);
+
+ classifierTester.checkPluginInfo(pluginInfo,
+ "unknown",
+ classifierTester.ASK_TO_ACTIVATE_PREF_VALUE);
+
+ yield BrowserTestUtils.removeTab(tab);
+ }
+});
new file mode 100644
--- /dev/null
+++ b/toolkit/components/url-classifier/tests/browser/browser_flashblock_off_with_never_activate.js
@@ -0,0 +1,43 @@
+/* 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/. */
+"use strict";
+requestLongerTimeout(2);
+
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+
+Cu.import("resource://gre/modules/Task.jsm");
+const scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
+ getService(Ci.mozIJSSubScriptLoader);
+scriptLoader.loadSubScript(
+ "chrome://mochitests/content/browser/toolkit/components/url-classifier/tests/browser/classifierHelper.js",
+ this);
+scriptLoader.loadSubScript(
+ "chrome://mochitests/content/browser/toolkit/components/url-classifier/tests/browser/classifierTester.js",
+ this);
+
+add_task(function* checkFlashBlockLists() {
+ classifierTester.setPrefs({
+ setDBs: true,
+ flashBlockEnable: false,
+ flashSetting: classifierTester.NEVER_ACTIVATE_PREF_VALUE
+ });
+
+ yield classifierHelper.waitForInit();
+ yield classifierHelper.addUrlToDB(classifierTester.dbUrls);
+
+ for (let testCase of classifierTester.testCases) {
+ info(`RUNNING TEST: ${testCase.name} (Never Activate, Flashblock off)`);
+ let tab = yield classifierTester.buildTestCaseInNewTab(gBrowser, testCase);
+
+ let depth = testCase.domains.length - 1;
+ let pluginInfo = yield classifierTester.getPluginInfo(tab.linkedBrowser,
+ depth);
+
+ classifierTester.checkPluginInfo(pluginInfo,
+ "unknown",
+ classifierTester.NEVER_ACTIVATE_PREF_VALUE);
+
+ yield BrowserTestUtils.removeTab(tab);
+ }
+});
new file mode 100644
--- /dev/null
+++ b/toolkit/components/url-classifier/tests/browser/browser_flashblock_on_with_always_activate.js
@@ -0,0 +1,43 @@
+/* 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/. */
+"use strict";
+requestLongerTimeout(2);
+
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+
+Cu.import("resource://gre/modules/Task.jsm");
+const scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
+ getService(Ci.mozIJSSubScriptLoader);
+scriptLoader.loadSubScript(
+ "chrome://mochitests/content/browser/toolkit/components/url-classifier/tests/browser/classifierHelper.js",
+ this);
+scriptLoader.loadSubScript(
+ "chrome://mochitests/content/browser/toolkit/components/url-classifier/tests/browser/classifierTester.js",
+ this);
+
+add_task(function* checkFlashBlockLists() {
+ classifierTester.setPrefs({
+ setDBs: true,
+ flashBlockEnable: true,
+ flashSetting: classifierTester.ALWAYS_ACTIVATE_PREF_VALUE
+ });
+
+ yield classifierHelper.waitForInit();
+ yield classifierHelper.addUrlToDB(classifierTester.dbUrls);
+
+ for (let testCase of classifierTester.testCases) {
+ info(`RUNNING TEST: ${testCase.name} (Ask to Activate, Flashblock on)`);
+ let tab = yield classifierTester.buildTestCaseInNewTab(gBrowser, testCase);
+
+ let depth = testCase.domains.length - 1;
+ let pluginInfo = yield classifierTester.getPluginInfo(tab.linkedBrowser,
+ depth);
+
+ classifierTester.checkPluginInfo(pluginInfo,
+ testCase.expectedFlashClassification,
+ classifierTester.ALWAYS_ACTIVATE_PREF_VALUE);
+
+ yield BrowserTestUtils.removeTab(tab);
+ }
+});
new file mode 100644
--- /dev/null
+++ b/toolkit/components/url-classifier/tests/browser/browser_flashblock_on_with_ask_to_activate.js
@@ -0,0 +1,43 @@
+/* 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/. */
+"use strict";
+requestLongerTimeout(2);
+
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+
+Cu.import("resource://gre/modules/Task.jsm");
+const scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
+ getService(Ci.mozIJSSubScriptLoader);
+scriptLoader.loadSubScript(
+ "chrome://mochitests/content/browser/toolkit/components/url-classifier/tests/browser/classifierHelper.js",
+ this);
+scriptLoader.loadSubScript(
+ "chrome://mochitests/content/browser/toolkit/components/url-classifier/tests/browser/classifierTester.js",
+ this);
+
+add_task(function* checkFlashBlockLists() {
+ classifierTester.setPrefs({
+ setDBs: true,
+ flashBlockEnable: true,
+ flashSetting: classifierTester.ASK_TO_ACTIVATE_PREF_VALUE
+ });
+
+ yield classifierHelper.waitForInit();
+ yield classifierHelper.addUrlToDB(classifierTester.dbUrls);
+
+ for (let testCase of classifierTester.testCases) {
+ info(`RUNNING TEST: ${testCase.name} (Ask to Activate, Flashblock on)`);
+ let tab = yield classifierTester.buildTestCaseInNewTab(gBrowser, testCase);
+
+ let depth = testCase.domains.length - 1;
+ let pluginInfo = yield classifierTester.getPluginInfo(tab.linkedBrowser,
+ depth);
+
+ classifierTester.checkPluginInfo(pluginInfo,
+ testCase.expectedFlashClassification,
+ classifierTester.ASK_TO_ACTIVATE_PREF_VALUE);
+
+ yield BrowserTestUtils.removeTab(tab);
+ }
+});
new file mode 100644
--- /dev/null
+++ b/toolkit/components/url-classifier/tests/browser/browser_flashblock_on_with_never_activate.js
@@ -0,0 +1,43 @@
+/* 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/. */
+"use strict";
+requestLongerTimeout(2);
+
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+
+Cu.import("resource://gre/modules/Task.jsm");
+const scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
+ getService(Ci.mozIJSSubScriptLoader);
+scriptLoader.loadSubScript(
+ "chrome://mochitests/content/browser/toolkit/components/url-classifier/tests/browser/classifierHelper.js",
+ this);
+scriptLoader.loadSubScript(
+ "chrome://mochitests/content/browser/toolkit/components/url-classifier/tests/browser/classifierTester.js",
+ this);
+
+add_task(function* checkFlashBlockLists() {
+ classifierTester.setPrefs({
+ setDBs: true,
+ flashBlockEnable: true,
+ flashSetting: classifierTester.NEVER_ACTIVATE_PREF_VALUE
+ });
+
+ yield classifierHelper.waitForInit();
+ yield classifierHelper.addUrlToDB(classifierTester.dbUrls);
+
+ for (let testCase of classifierTester.testCases) {
+ info(`RUNNING TEST: ${testCase.name} (Never Activate, Flashblock on)`);
+ let tab = yield classifierTester.buildTestCaseInNewTab(gBrowser, testCase);
+
+ let depth = testCase.domains.length - 1;
+ let pluginInfo = yield classifierTester.getPluginInfo(tab.linkedBrowser,
+ depth);
+
+ classifierTester.checkPluginInfo(pluginInfo,
+ testCase.expectedFlashClassification,
+ classifierTester.NEVER_ACTIVATE_PREF_VALUE);
+
+ yield BrowserTestUtils.removeTab(tab);
+ }
+});
new file mode 100644
--- /dev/null
+++ b/toolkit/components/url-classifier/tests/browser/classifierTester.js
@@ -0,0 +1,337 @@
+/* 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/. */
+
+Cu.import("resource://gre/modules/Task.jsm");
+
+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",
+ NEVER_ACTIVATE_PREF_VALUE: 0,
+ ASK_TO_ACTIVATE_PREF_VALUE: 1,
+ ALWAYS_ACTIVATE_PREF_VALUE: 2,
+ ALLOW_CTA_PREF: "plugins.click_to_play",
+
+ 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.flashThirdPartyTable"
+ },
+ {
+ url: "exception.subdocument.example.com/",
+ db: "testexcept-flashsubdoc-simple",
+ pref: "urlclassifier.flashThirdPartyExceptTable"
+ }
+ ],
+
+ setPrefs: function ({setDBs = true, flashBlockEnable = true, flashSetting = classifierTester.ALWAYS_ACTIVATE_PREF_VALUE} = {}) {
+ if (setDBs) {
+ for (let dbData of classifierTester.dbUrls) {
+ Services.prefs.setCharPref(dbData.pref, dbData.db);
+ }
+ }
+ Services.prefs.setBoolPref(classifierTester.FLASHBLOCK_ENABLE_PREF,
+ flashBlockEnable);
+ Services.prefs.setIntPref(classifierTester.FLASH_PLUGIN_USER_SETTING_PREF,
+ flashSetting);
+ Services.prefs.setBoolPref(classifierTester.ALLOW_CTA_PREF, true);
+ },
+
+ unsetPrefs: function () {
+ for (let dbData of classifierTester.dbUrls) {
+ Services.prefs.clearUserPref(dbData.pref);
+ }
+ Services.prefs.clearUserPref(classifierTester.FLASHBLOCK_ENABLE_PREF);
+ Services.prefs.clearUserPref(classifierTester.FLASH_PLUGIN_USER_SETTING_PREF);
+ Services.prefs.clearUserPref(classifierTester.ALLOW_CTA_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: function (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: function (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: function (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: function (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: function (browser, testCase) {
+ return Task.spawn(function* () {
+ let iframeDomains = testCase.domains.slice();
+ let pageDomain = iframeDomains.shift();
+ let tab = yield 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);
+
+ ContentTask.spawn(tab.linkedBrowser, {iframeId: classifierTester.IFRAME_ID, url: url, depth: depth},
+ function*({iframeId, url, depth}) {
+ let doc = content.document;
+ for (let i = 0; i < depth; ++i) {
+ doc = doc.getElementById(iframeId).contentDocument;
+ }
+ doc.getElementById(iframeId).src = url;
+ });
+
+ yield domainLoaded;
+ ++depth;
+ }
+ return tab;
+ });
+ },
+
+ getPluginInfo: function (browser, depth) {
+ return ContentTask.spawn(browser,
+ {iframeId: classifierTester.IFRAME_ID, depth: depth},
+ function* ({iframeId, depth}) {
+ let doc = content.document;
+ let win = content.window;
+ for (let i = 0; i < depth; ++i) {
+ let frame = doc.getElementById(iframeId);
+ doc = frame.contentDocument;
+ win = frame.contentWindow;
+ }
+
+ 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
+ };
+ });
+ },
+
+ checkPluginInfo: function (pluginInfo, expectedClassification, flashSetting) {
+ 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);