author | Kirk Steuber <ksteuber@mozilla.com> |
Mon, 13 Feb 2017 13:39:40 -0800 | |
changeset 483154 | 4bf5da6054d181d5e449838363b5622e7e873ae5 |
parent 481376 | eea9995ed14c07675c972400e8ce36b3608c01b1 |
child 545573 | 210461824d9c1aa73e7331f9d681e1e95ffafd6d |
push id | 45237 |
push user | ksteuber@mozilla.com |
push date | Mon, 13 Feb 2017 21:41:05 +0000 |
bugs | 1338287 |
milestone | 54.0a1 |
--- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -13038,17 +13038,17 @@ ArrayContainsTable(const nsTArray<nsCStr /** * Retrieves the classification of the Flash plugins in the document based on * the classification lists. * * For more information, see * toolkit/components/url-classifier/flash-block-lists.rst */ -nsIDocument::FlashClassification +FlashClassification nsDocument::PrincipalFlashClassification(bool aIsTopLevel) { nsresult rv; // If flash blocking is disabled, it is equivalent to all sites being // whitelisted. if (!Preferences::GetBool("plugins.flashBlock.enabled")) { return FlashClassification::Allowed; @@ -13127,17 +13127,17 @@ nsDocument::PrincipalFlashClassification if (!aIsTopLevel && ArrayContainsTable(results, subDocDenyTables) && !ArrayContainsTable(results, subDocDenyExceptionsTables)) { return FlashClassification::Denied; } return FlashClassification::Unknown; } -nsIDocument::FlashClassification +FlashClassification nsDocument::ComputeFlashClassification() { nsCOMPtr<nsIDocShellTreeItem> current = this->GetDocShell(); if (!current) { return FlashClassification::Denied; } nsCOMPtr<nsIDocShellTreeItem> parent; DebugOnly<nsresult> rv = current->GetSameTypeParent(getter_AddRefs(parent)); @@ -13176,17 +13176,17 @@ nsDocument::ComputeFlashClassification() /** * Retrieves the classification of plugins in this document. This is dependent * on the classification of this document and all parent documents. * This function is infallible - It must return some classification that * callers can act on. * * This function will NOT return FlashClassification::Unclassified */ -nsIDocument::FlashClassification +FlashClassification nsDocument::DocumentFlashClassification() { if (mFlashClassification == FlashClassification::Unclassified) { FlashClassification result = ComputeFlashClassification(); mFlashClassification = result; MOZ_ASSERT(result != FlashClassification::Unclassified, "nsDocument::GetPluginClassification should never return Unclassified"); }
--- a/dom/base/nsDocument.h +++ b/dom/base/nsDocument.h @@ -1300,17 +1300,17 @@ protected: bool aPersisted); virtual nsPIDOMWindowOuter* GetWindowInternal() const override; virtual nsIScriptGlobalObject* GetScriptHandlingObjectInternal() const override; virtual bool InternalAllowXULXBL() override; void UpdateScreenOrientation(); - virtual FlashClassification DocumentFlashClassification() override; + virtual mozilla::dom::FlashClassification DocumentFlashClassification() override; #define NS_DOCUMENT_NOTIFY_OBSERVERS(func_, params_) \ NS_OBSERVER_ARRAY_NOTIFY_XPCOM_OBSERVERS(mObservers, nsIDocumentObserver, \ func_, params_); #ifdef DEBUG void VerifyRootContentState(); #endif @@ -1324,21 +1324,21 @@ protected: // Apply the fullscreen state to the document, and trigger related // events. It returns false if the fullscreen element ready check // fails and nothing gets changed. bool ApplyFullscreen(const FullscreenRequest& aRequest); // Retrieves the classification of the Flash plugins in the document based on // the classification lists. - FlashClassification PrincipalFlashClassification(bool aIsTopLevel); + mozilla::dom::FlashClassification PrincipalFlashClassification(bool aIsTopLevel); // Attempts to determine the Flash classification of this page based on the // the classification lists and the classification of parent documents. - FlashClassification ComputeFlashClassification(); + mozilla::dom::FlashClassification ComputeFlashClassification(); nsTArray<nsIObserver*> mCharSetObservers; PLDHashTable *mSubDocuments; // Array of owning references to all children nsAttrAndChildArray mChildren; @@ -1374,17 +1374,17 @@ protected: // full-screen element onto this stack, and when we cancel full-screen we // pop one off this stack, restoring the previous full-screen state nsTArray<nsWeakPtr> mFullScreenStack; // The root of the doc tree in which this document is in. This is only // non-null when this document is in fullscreen mode. nsWeakPtr mFullscreenRoot; - FlashClassification mFlashClassification; + mozilla::dom::FlashClassification mFlashClassification; private: static bool CustomElementConstructor(JSContext* aCx, unsigned aArgc, JS::Value* aVp); /** * Check if the passed custom element name, aOptions.mIs, is a registered * custom element type or not, then return the custom element name for future * usage. *
--- a/dom/base/nsIDocument.h +++ b/dom/base/nsIDocument.h @@ -2890,24 +2890,17 @@ public: // determine whether some code is being called from a tracking script. void NoteScriptTrackingStatus(const nsACString& aURL, bool isTracking); bool IsScriptTracking(const nsACString& aURL) const; bool PrerenderHref(nsIURI* aHref); // For more information on Flash classification, see // toolkit/components/url-classifier/flash-block-lists.rst - enum class FlashClassification { - Unclassified, // Denotes a classification that has not yet been computed. - // Allows for lazy classification. - Unknown, // Site is not on the whitelist or blacklist - Allowed, // Site is on the Flash whitelist - Denied // Site is on the Flash blacklist - }; - virtual FlashClassification DocumentFlashClassification() = 0; + virtual mozilla::dom::FlashClassification DocumentFlashClassification() = 0; protected: bool GetUseCounter(mozilla::UseCounter aUseCounter) { return mUseCounters[aUseCounter]; } void SetChildDocumentUseCounter(mozilla::UseCounter aUseCounter)
--- a/dom/base/nsObjectLoadingContent.cpp +++ b/dom/base/nsObjectLoadingContent.cpp @@ -3334,21 +3334,21 @@ 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) - nsIDocument::FlashClassification documentClassification = nsIDocument::FlashClassification::Allowed; + FlashClassification documentClassification = FlashClassification::Allowed; if (IsFlashMIME(mContentType)) { documentClassification = ownerDoc->DocumentFlashClassification(); } - if (documentClassification == nsIDocument::FlashClassification::Denied) { + if (documentClassification == FlashClassification::Denied) { aReason = eFallbackSuppressed; return false; } // Check the permission manager for permission based on the principal of // the toplevel content. nsCOMPtr<nsIPermissionManager> permissionManager = services::GetPermissionManager(); NS_ENSURE_TRUE(permissionManager, false); @@ -3411,17 +3411,17 @@ nsObjectLoadingContent::ShouldPlay(Fallb if (PreferFallback(enabledState == nsIPluginTag::STATE_CLICKTOPLAY)) { aReason = eFallbackAlternate; return false; } switch (enabledState) { case nsIPluginTag::STATE_ENABLED: - return documentClassification == nsIDocument::FlashClassification::Allowed; + return documentClassification == FlashClassification::Allowed; case nsIPluginTag::STATE_CLICKTOPLAY: return false; } MOZ_CRASH("Unexpected enabledState"); } bool nsObjectLoadingContent::FavorFallbackMode(bool aIsPluginClickToPlay) {
--- a/dom/webidl/Document.webidl +++ b/dom/webidl/Document.webidl @@ -431,16 +431,30 @@ partial interface Document { // Extension to give chrome and XBL JS the ability to determine whether // the document is sandboxed without permission to run scripts // and whether inline scripts are blocked by the document's CSP. partial interface Document { [Func="IsChromeOrXBL"] readonly attribute boolean hasScriptsBlockedBySandbox; [Func="IsChromeOrXBL"] readonly attribute boolean inlineScriptAllowedByCSP; }; +// For more information on Flash classification, see +// toolkit/components/url-classifier/flash-block-lists.rst +enum FlashClassification { + "unclassified", // Denotes a classification that has not yet been computed. + // Allows for lazy classification. + "unknown", // Site is not on the whitelist or blacklist + "allowed", // Site is on the Flash whitelist + "denied" // Site is on the Flash blacklist +}; +partial interface Document { + [ChromeOnly] + readonly attribute FlashClassification documentFlashClassification; +}; + Document implements XPathEvaluator; Document implements GlobalEventHandlers; Document implements DocumentAndElementEventHandlers; Document implements TouchEventHandlers; Document implements ParentNode; Document implements OnErrorEventHandlerForNodes; Document implements GeometryUtils; Document implements FontFaceSource;
--- a/toolkit/components/url-classifier/tests/browser/browser_flash_block_lists.js +++ b/toolkit/components/url-classifier/tests/browser/browser_flash_block_lists.js @@ -71,142 +71,159 @@ registerCleanupFunction(unsetDBPrefs); // 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 + 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 + pluginListed: true, + expectedFlashClassification: "unknown" }, { name: "Allowed domain", domains: ["http://flashallow.example.com"], expectedActivated: true, expectedHasRunningPlugin: true, - pluginListed: true + pluginListed: true, + expectedFlashClassification: "allowed" }, { name: "Allowed nested domain", domains: ["http://example.com", "http://flashallow.example.com"], expectedActivated: true, expectedHasRunningPlugin: true, - pluginListed: true + pluginListed: true, + expectedFlashClassification: "allowed" }, { name: "Subdocument of allowed domain", domains: ["http://flashallow.example.com", "http://example.com"], expectedActivated: true, expectedHasRunningPlugin: true, - pluginListed: 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 + pluginListed: true, + expectedFlashClassification: "unknown" }, { name: "Blocked domain", domains: ["http://flashblock.example.com"], expectedPluginFallbackType: Ci.nsIObjectLoadingContent.PLUGIN_USER_DISABLED, expectedActivated: false, expectedHasRunningPlugin: false, - pluginListed: 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 @@ -244,17 +261,18 @@ function getPluginInfo(browser, 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) + listed: ("Shockwave Flash" in win.navigator.plugins), + flashClassification: doc.documentFlashClassification }; }); } add_task(function* checkFlashBlockLists() { setDBPrefs(); yield classifierHelper.waitForInit(); @@ -283,16 +301,20 @@ add_task(function* checkFlashBlockLists( 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); @@ -311,12 +333,14 @@ add_task(function* checkFlashBlockDisabl 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); } });