From e34612e16e34861cca3ad5c9cc9f6b576804e74e Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Fri, 4 Jan 2019 14:45:42 +0100 Subject: [PATCH] Bug 1514202 - Port flash url-classifier to nsIUrlClassifierFeature - part 1 - Flash feature, r=dimi, r=edgar, r=valentin --- dom/ipc/PURLClassifierLocal.ipdl | 4 + dom/ipc/URLClassifierChild.h | 9 +- dom/ipc/URLClassifierParent.cpp | 21 +- modules/libpref/init/StaticPrefList.h | 16 + modules/libpref/init/all.js | 3 - netwerk/base/SimpleChannelParent.cpp | 7 + netwerk/base/nsIParentChannel.idl | 6 + netwerk/ipc/NeckoMessageUtils.h | 7 + netwerk/protocol/data/DataChannelParent.cpp | 7 + netwerk/protocol/file/FileChannelParent.cpp | 7 + netwerk/protocol/ftp/FTPChannelParent.cpp | 7 + .../http/HttpBackgroundChannelChild.cpp | 19 + .../http/HttpBackgroundChannelChild.h | 3 + .../http/HttpBackgroundChannelParent.cpp | 31 ++ .../http/HttpBackgroundChannelParent.h | 3 + netwerk/protocol/http/HttpBaseChannel.cpp | 14 + netwerk/protocol/http/HttpBaseChannel.h | 5 + netwerk/protocol/http/HttpChannelChild.cpp | 9 + netwerk/protocol/http/HttpChannelChild.h | 2 + netwerk/protocol/http/HttpChannelParent.cpp | 11 + netwerk/protocol/http/NullHttpChannel.cpp | 6 + .../protocol/http/PHttpBackgroundChannel.ipdl | 5 + netwerk/protocol/http/nsIHttpChannel.idl | 14 + .../viewsource/nsViewSourceChannel.cpp | 7 + .../AsyncUrlChannelClassifier.cpp | 398 ++++++++++-------- .../url-classifier/UrlClassifierCommon.cpp | 61 +++ netwerk/url-classifier/UrlClassifierCommon.h | 5 + .../UrlClassifierFeatureFactory.cpp | 8 + .../UrlClassifierFeatureFlash.cpp | 155 +++++++ .../UrlClassifierFeatureFlash.h | 41 ++ .../UrlClassifierFeatureLoginReputation.cpp | 13 + .../UrlClassifierFeatureLoginReputation.h | 4 + .../UrlClassifierFeatureResult.cpp | 12 +- .../UrlClassifierFeatureResult.h | 7 +- ...UrlClassifierFeatureTrackingAnnotation.cpp | 15 + .../UrlClassifierFeatureTrackingAnnotation.h | 4 + ...UrlClassifierFeatureTrackingProtection.cpp | 15 + .../UrlClassifierFeatureTrackingProtection.h | 4 + netwerk/url-classifier/moz.build | 1 + .../nsIUrlClassifierFeature.idl | 11 + .../nsUrlClassifierDBService.cpp | 29 +- .../exthandler/nsExternalProtocolHandler.cpp | 6 + 42 files changed, 829 insertions(+), 183 deletions(-) create mode 100644 netwerk/url-classifier/UrlClassifierFeatureFlash.cpp create mode 100644 netwerk/url-classifier/UrlClassifierFeatureFlash.h diff --git a/dom/ipc/PURLClassifierLocal.ipdl b/dom/ipc/PURLClassifierLocal.ipdl index f61e5e83f64c..28801ceb735c 100644 --- a/dom/ipc/PURLClassifierLocal.ipdl +++ b/dom/ipc/PURLClassifierLocal.ipdl @@ -6,13 +6,17 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ include protocol PContent; + include PURLClassifierInfo; +using refcounted class nsIURI from "mozilla/ipc/URIUtils.h"; + namespace mozilla { namespace dom { struct URLClassifierLocalResult { + nsIURI uri; nsCString featureName; nsCString matchingList; }; diff --git a/dom/ipc/URLClassifierChild.h b/dom/ipc/URLClassifierChild.h index 2fa48e5bd131..b61dcf5ed415 100644 --- a/dom/ipc/URLClassifierChild.h +++ b/dom/ipc/URLClassifierChild.h @@ -9,6 +9,7 @@ #include "mozilla/dom/PURLClassifierChild.h" #include "mozilla/dom/PURLClassifierLocalChild.h" +#include "mozilla/ipc/URIUtils.h" #include "mozilla/net/UrlClassifierFeatureResult.h" #include "nsIURIClassifier.h" #include "nsIUrlClassifierFeature.h" @@ -63,8 +64,14 @@ class URLClassifierLocalChild : public PURLClassifierLocalChild { continue; } + RefPtr uri = result.uri(); + if (NS_WARN_IF(!uri)) { + continue; + } + RefPtr r = - new net::UrlClassifierFeatureResult(feature, result.matchingList()); + new net::UrlClassifierFeatureResult(uri, feature, + result.matchingList()); finalResults.AppendElement(r); break; } diff --git a/dom/ipc/URLClassifierParent.cpp b/dom/ipc/URLClassifierParent.cpp index 71806abbe468..66fb68dc4e40 100644 --- a/dom/ipc/URLClassifierParent.cpp +++ b/dom/ipc/URLClassifierParent.cpp @@ -53,8 +53,8 @@ class IPCFeature final : public nsIUrlClassifierFeature { public: NS_DECL_ISUPPORTS - explicit IPCFeature(const IPCURLClassifierFeature& aFeature) - : mIPCFeature(aFeature) {} + IPCFeature(nsIURI* aURI, const IPCURLClassifierFeature& aFeature) + : mURI(aURI), mIPCFeature(aFeature) {} NS_IMETHOD GetName(nsACString& aName) override { @@ -102,9 +102,22 @@ class IPCFeature final : public nsIUrlClassifierFeature { return NS_OK; } + NS_IMETHOD + GetURIByListType(nsIChannel* aChannel, + nsIUrlClassifierFeature::listType aListType, + nsIURI** aURI) override { + NS_ENSURE_ARG_POINTER(aURI); + + // This method should not be called, but we have a URI, let's return it. + nsCOMPtr uri = mURI; + uri.forget(aURI); + return NS_OK; + } + private: ~IPCFeature() = default; + nsCOMPtr mURI; IPCURLClassifierFeature mIPCFeature; }; @@ -130,7 +143,7 @@ mozilla::ipc::IPCResult URLClassifierLocalParent::StartClassify( nsTArray> features; for (const IPCURLClassifierFeature& feature : aFeatures) { - features.AppendElement(new IPCFeature(feature)); + features.AppendElement(new IPCFeature(aURI, feature)); } // Doesn't matter if we pass blacklist, whitelist or any other list. @@ -154,6 +167,8 @@ URLClassifierLocalParent::OnClassifyComplete( net::UrlClassifierFeatureResult* r = static_cast(result); + + ipcResult->uri() = r->URI(); r->Feature()->GetName(ipcResult->featureName()); ipcResult->matchingList() = r->List(); } diff --git a/modules/libpref/init/StaticPrefList.h b/modules/libpref/init/StaticPrefList.h index bd2d5406c15f..371dad56f79c 100644 --- a/modules/libpref/init/StaticPrefList.h +++ b/modules/libpref/init/StaticPrefList.h @@ -1940,6 +1940,22 @@ VARCACHE_PREF( ) #undef PREF_VALUE +//--------------------------------------------------------------------------- +// Plugins prefs +//--------------------------------------------------------------------------- + +VARCACHE_PREF( + "plugins.flashBlock.enabled", + plugins_flashBlock_enabled, + bool, false +) + +VARCACHE_PREF( + "plugins.http_https_only", + plugins_http_https_only, + bool, true +) + //--------------------------------------------------------------------------- // Reporting API //--------------------------------------------------------------------------- diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 7d01fcfc9efd..b69ac150163c 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -5655,9 +5655,6 @@ pref("urlclassifier.flashSubDocTable", "block-flashsubdoc-digest256"); pref("urlclassifier.flashSubDocExceptTable", "except-flashsubdoc-digest256"); pref("urlclassifier.flashInfobarTable", "except-flashinfobar-digest256"); -pref("plugins.http_https_only", true); -pref("plugins.flashBlock.enabled", false); - // Turn off Spatial navigation by default. pref("snav.enabled", false); diff --git a/netwerk/base/SimpleChannelParent.cpp b/netwerk/base/SimpleChannelParent.cpp index f21e45ce2c2c..80cec908f913 100644 --- a/netwerk/base/SimpleChannelParent.cpp +++ b/netwerk/base/SimpleChannelParent.cpp @@ -52,6 +52,13 @@ SimpleChannelParent::NotifyTrackingResource(bool aIsThirdParty) { return NS_OK; } +NS_IMETHODIMP +SimpleChannelParent::NotifyFlashPluginStateChanged( + nsIHttpChannel::FlashPluginState aState) { + // Nothing to do. + return NS_OK; +} + NS_IMETHODIMP SimpleChannelParent::SetClassifierMatchedInfo(const nsACString& aList, const nsACString& aProvider, diff --git a/netwerk/base/nsIParentChannel.idl b/netwerk/base/nsIParentChannel.idl index f551e8515bef..c6234bdb002b 100644 --- a/netwerk/base/nsIParentChannel.idl +++ b/netwerk/base/nsIParentChannel.idl @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsIStreamListener.idl" +#include "nsIHttpChannel.idl" interface nsITabParent; @@ -46,6 +47,11 @@ interface nsIParentChannel : nsIStreamListener */ [noscript] void notifyTrackingCookieBlocked(in uint32_t aRejectedReason); + /** + * Called to notify the HttpChannelChild that flash plugin state has changed. + */ + [noscript] void notifyFlashPluginStateChanged(in nsIHttpChannel_FlashPluginState aState); + /** * Called to set matched information when URL matches SafeBrowsing list. * @param aList diff --git a/netwerk/ipc/NeckoMessageUtils.h b/netwerk/ipc/NeckoMessageUtils.h index 89565c3079cc..0097c93fe1e8 100644 --- a/netwerk/ipc/NeckoMessageUtils.h +++ b/netwerk/ipc/NeckoMessageUtils.h @@ -10,6 +10,7 @@ #include "ipc/IPCMessageUtils.h" #include "nsExceptionHandler.h" +#include "nsIHttpChannel.h" #include "nsPrintfCString.h" #include "nsString.h" #include "prio.h" @@ -179,6 +180,12 @@ struct ParamTraits { } }; +template <> +struct ParamTraits + : public ContiguousEnumSerializerInclusive< + nsIHttpChannel::FlashPluginState, nsIHttpChannel::FlashPluginUnknown, + nsIHttpChannel::FlashPluginLastValue> {}; + } // namespace IPC #endif // mozilla_net_NeckoMessageUtils_h diff --git a/netwerk/protocol/data/DataChannelParent.cpp b/netwerk/protocol/data/DataChannelParent.cpp index 53cc417eefde..6ad8f820866a 100644 --- a/netwerk/protocol/data/DataChannelParent.cpp +++ b/netwerk/protocol/data/DataChannelParent.cpp @@ -52,6 +52,13 @@ DataChannelParent::NotifyTrackingResource(bool aIsThirdParty) { return NS_OK; } +NS_IMETHODIMP +DataChannelParent::NotifyFlashPluginStateChanged( + nsIHttpChannel::FlashPluginState aState) { + // Nothing to do. + return NS_OK; +} + NS_IMETHODIMP DataChannelParent::SetClassifierMatchedInfo(const nsACString &aList, const nsACString &aProvider, diff --git a/netwerk/protocol/file/FileChannelParent.cpp b/netwerk/protocol/file/FileChannelParent.cpp index f0e0407334fe..a711a20ec768 100644 --- a/netwerk/protocol/file/FileChannelParent.cpp +++ b/netwerk/protocol/file/FileChannelParent.cpp @@ -52,6 +52,13 @@ FileChannelParent::NotifyTrackingResource(bool aIsThirdParty) { return NS_OK; } +NS_IMETHODIMP +FileChannelParent::NotifyFlashPluginStateChanged( + nsIHttpChannel::FlashPluginState aState) { + // Nothing to do. + return NS_OK; +} + NS_IMETHODIMP FileChannelParent::SetClassifierMatchedInfo(const nsACString &aList, const nsACString &aProvider, diff --git a/netwerk/protocol/ftp/FTPChannelParent.cpp b/netwerk/protocol/ftp/FTPChannelParent.cpp index 6cb78e0f9e0e..d68f030e8bb7 100644 --- a/netwerk/protocol/ftp/FTPChannelParent.cpp +++ b/netwerk/protocol/ftp/FTPChannelParent.cpp @@ -523,6 +523,13 @@ FTPChannelParent::NotifyTrackingResource(bool aIsThirdParty) { return NS_OK; } +NS_IMETHODIMP +FTPChannelParent::NotifyFlashPluginStateChanged( + nsIHttpChannel::FlashPluginState aState) { + // One day, this should probably be filled in. + return NS_OK; +} + NS_IMETHODIMP FTPChannelParent::SetClassifierMatchedInfo(const nsACString& aList, const nsACString& aProvider, diff --git a/netwerk/protocol/http/HttpBackgroundChannelChild.cpp b/netwerk/protocol/http/HttpBackgroundChannelChild.cpp index e2bfc4a7602e..af9c16f06feb 100644 --- a/netwerk/protocol/http/HttpBackgroundChannelChild.cpp +++ b/netwerk/protocol/http/HttpBackgroundChannelChild.cpp @@ -358,6 +358,25 @@ IPCResult HttpBackgroundChannelChild::RecvNotifyTrackingResource( return IPC_OK(); } +IPCResult HttpBackgroundChannelChild::RecvNotifyFlashPluginStateChanged( + const nsIHttpChannel::FlashPluginState& aState) { + LOG( + ("HttpBackgroundChannelChild::RecvNotifyFlashPluginStateChanged " + "[this=%p]\n", + this)); + MOZ_ASSERT(OnSocketThread()); + + if (NS_WARN_IF(!mChannelChild)) { + return IPC_OK(); + } + + // NotifyFlashPluginStateChanged has no order dependency to OnStartRequest. + // It this be handled as soon as possible + mChannelChild->ProcessNotifyFlashPluginStateChanged(aState); + + return IPC_OK(); +} + IPCResult HttpBackgroundChannelChild::RecvSetClassifierMatchedInfo( const ClassifierInfo& info) { LOG(("HttpBackgroundChannelChild::RecvSetClassifierMatchedInfo [this=%p]\n", diff --git a/netwerk/protocol/http/HttpBackgroundChannelChild.h b/netwerk/protocol/http/HttpBackgroundChannelChild.h index e50373b58a35..eb3f343d6b05 100644 --- a/netwerk/protocol/http/HttpBackgroundChannelChild.h +++ b/netwerk/protocol/http/HttpBackgroundChannelChild.h @@ -72,6 +72,9 @@ class HttpBackgroundChannelChild final : public PHttpBackgroundChannelChild { IPCResult RecvNotifyTrackingResource(const bool& aIsThirdParty) override; + IPCResult RecvNotifyFlashPluginStateChanged( + const nsIHttpChannel::FlashPluginState& aState) override; + IPCResult RecvSetClassifierMatchedInfo(const ClassifierInfo& info) override; void ActorDestroy(ActorDestroyReason aWhy) override; diff --git a/netwerk/protocol/http/HttpBackgroundChannelParent.cpp b/netwerk/protocol/http/HttpBackgroundChannelParent.cpp index 002ae0b21756..fb2613c549d1 100644 --- a/netwerk/protocol/http/HttpBackgroundChannelParent.cpp +++ b/netwerk/protocol/http/HttpBackgroundChannelParent.cpp @@ -426,6 +426,37 @@ bool HttpBackgroundChannelParent::OnNotifyTrackingResource(bool aIsThirdParty) { return SendNotifyTrackingResource(aIsThirdParty); } +bool HttpBackgroundChannelParent::OnNotifyFlashPluginStateChanged( + nsIHttpChannel::FlashPluginState aState) { + LOG( + ("HttpBackgroundChannelParent::OnNotifyFlashPluginStateChanged " + "[this=%p]\n", + this)); + AssertIsInMainProcess(); + + if (NS_WARN_IF(!mIPCOpened)) { + return false; + } + + if (!IsOnBackgroundThread()) { + MutexAutoLock lock(mBgThreadMutex); + RefPtr self = this; + nsresult rv = mBackgroundThread->Dispatch( + NS_NewRunnableFunction( + "net::HttpBackgroundChannelParent::OnNotifyFlashPluginStateChanged", + [self, aState]() { + self->OnNotifyFlashPluginStateChanged(aState); + }), + NS_DISPATCH_NORMAL); + + MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv)); + + return NS_SUCCEEDED(rv); + } + + return SendNotifyFlashPluginStateChanged(aState); +} + bool HttpBackgroundChannelParent::OnSetClassifierMatchedInfo( const nsACString& aList, const nsACString& aProvider, const nsACString& aFullHash) { diff --git a/netwerk/protocol/http/HttpBackgroundChannelParent.h b/netwerk/protocol/http/HttpBackgroundChannelParent.h index b7ba74745e23..3c0af1ed37ee 100644 --- a/netwerk/protocol/http/HttpBackgroundChannelParent.h +++ b/netwerk/protocol/http/HttpBackgroundChannelParent.h @@ -75,6 +75,9 @@ class HttpBackgroundChannelParent final : public PHttpBackgroundChannelParent { // To send NotifyTrackingResource message over background channel. bool OnNotifyTrackingResource(bool aIsThirdParty); + // To send NotifyFlashPluginStateChanged message over background channel. + bool OnNotifyFlashPluginStateChanged(nsIHttpChannel::FlashPluginState aState); + // To send SetClassifierMatchedInfo message over background channel. bool OnSetClassifierMatchedInfo(const nsACString& aList, const nsACString& aProvider, diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp index 025462fdfb04..cf0b3b48ac62 100644 --- a/netwerk/protocol/http/HttpBaseChannel.cpp +++ b/netwerk/protocol/http/HttpBaseChannel.cpp @@ -168,6 +168,7 @@ HttpBaseChannel::HttpBaseChannel() mCanceled(false), mIsFirstPartyTrackingResource(false), mIsThirdPartyTrackingResource(false), + mFlashPluginState(nsIHttpChannel::FlashPluginUnknown), mLoadFlags(LOAD_NORMAL), mCaps(0), mClassOfService(0), @@ -319,6 +320,12 @@ void HttpBaseChannel::SetIsTrackingResource(bool aIsThirdParty) { } } +void HttpBaseChannel::SetFlashPluginState( + nsIHttpChannel::FlashPluginState aState) { + LOG(("HttpBaseChannel::SetFlashPluginState %p", this)); + mFlashPluginState = aState; +} + nsresult HttpBaseChannel::Init(nsIURI* aURI, uint32_t aCaps, nsProxyInfo* aProxyInfo, uint32_t aProxyResolveFlags, nsIURI* aProxyURI, @@ -1485,6 +1492,13 @@ HttpBaseChannel::GetIsThirdPartyTrackingResource(bool* aIsTrackingResource) { return NS_OK; } +NS_IMETHODIMP +HttpBaseChannel::GetFlashPluginState(nsIHttpChannel::FlashPluginState* aState) { + uint32_t flashPluginState = mFlashPluginState; + *aState = (nsIHttpChannel::FlashPluginState)flashPluginState; + return NS_OK; +} + NS_IMETHODIMP HttpBaseChannel::OverrideTrackingFlagsForDocumentCookieAccessor( nsIHttpChannel* aDocumentChannel) { diff --git a/netwerk/protocol/http/HttpBaseChannel.h b/netwerk/protocol/http/HttpBaseChannel.h index 4a535378916a..3d33f4748457 100644 --- a/netwerk/protocol/http/HttpBaseChannel.h +++ b/netwerk/protocol/http/HttpBaseChannel.h @@ -238,6 +238,8 @@ class HttpBaseChannel : public nsHashPropertyBag, bool *aIsTrackingResource) override; NS_IMETHOD OverrideTrackingFlagsForDocumentCookieAccessor( nsIHttpChannel *aDocumentChannel) override; + NS_IMETHOD GetFlashPluginState( + nsIHttpChannel::FlashPluginState *aState) override; // nsIHttpChannelInternal NS_IMETHOD GetDocumentURI(nsIURI **aDocumentURI) override; @@ -413,6 +415,8 @@ class HttpBaseChannel : public nsHashPropertyBag, void SetIsTrackingResource(bool aIsThirdParty); + void SetFlashPluginState(nsIHttpChannel::FlashPluginState aState); + const uint64_t &ChannelId() const { return mChannelId; } void InternalSetUploadStream(nsIInputStream *uploadStream) { @@ -647,6 +651,7 @@ class HttpBaseChannel : public nsHashPropertyBag, Atomic mCanceled; Atomic mIsFirstPartyTrackingResource; Atomic mIsThirdPartyTrackingResource; + Atomic mFlashPluginState; uint32_t mLoadFlags; uint32_t mCaps; diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp index c8bac4562232..d177c6f4a03c 100644 --- a/netwerk/protocol/http/HttpChannelChild.cpp +++ b/netwerk/protocol/http/HttpChannelChild.cpp @@ -1862,6 +1862,15 @@ void HttpChannelChild::ProcessNotifyTrackingResource(bool aIsThirdParty) { SetIsTrackingResource(aIsThirdParty); } +void HttpChannelChild::ProcessNotifyFlashPluginStateChanged( + nsIHttpChannel::FlashPluginState aState) { + LOG(("HttpChannelChild::ProcessNotifyFlashPluginStateChanged [this=%p]\n", + this)); + MOZ_ASSERT(OnSocketThread()); + + SetFlashPluginState(aState); +} + void HttpChannelChild::FlushedForDiversion() { LOG(("HttpChannelChild::FlushedForDiversion [this=%p]\n", this)); MOZ_RELEASE_ASSERT(mDivertingToParent); diff --git a/netwerk/protocol/http/HttpChannelChild.h b/netwerk/protocol/http/HttpChannelChild.h index a00f0949a013..5e1081868efa 100644 --- a/netwerk/protocol/http/HttpChannelChild.h +++ b/netwerk/protocol/http/HttpChannelChild.h @@ -265,6 +265,8 @@ class HttpChannelChild final : public PHttpChannelChild, void ProcessNotifyCookieAllowed(); void ProcessNotifyTrackingCookieBlocked(uint32_t aRejectedReason); void ProcessNotifyTrackingResource(bool aIsThirdParty); + void ProcessNotifyFlashPluginStateChanged( + nsIHttpChannel::FlashPluginState aState); void ProcessSetClassifierMatchedInfo(const nsCString& aList, const nsCString& aProvider, const nsCString& aFullHash); diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp index 5ceb1ef25594..000bb854c1f5 100644 --- a/netwerk/protocol/http/HttpChannelParent.cpp +++ b/netwerk/protocol/http/HttpChannelParent.cpp @@ -1826,6 +1826,17 @@ HttpChannelParent::NotifyTrackingResource(bool aIsThirdParty) { return NS_OK; } +NS_IMETHODIMP +HttpChannelParent::NotifyFlashPluginStateChanged( + nsIHttpChannel::FlashPluginState aState) { + LOG(("HttpChannelParent::NotifyFlashPluginStateChanged [this=%p]\n", this)); + if (!mIPCClosed) { + MOZ_ASSERT(mBgParent); + Unused << mBgParent->OnNotifyFlashPluginStateChanged(aState); + } + return NS_OK; +} + NS_IMETHODIMP HttpChannelParent::Delete() { if (!mIPCClosed) Unused << DoSendDeleteSelf(); diff --git a/netwerk/protocol/http/NullHttpChannel.cpp b/netwerk/protocol/http/NullHttpChannel.cpp index 6dba9e3eee1d..aee6bbedee06 100644 --- a/netwerk/protocol/http/NullHttpChannel.cpp +++ b/netwerk/protocol/http/NullHttpChannel.cpp @@ -88,6 +88,12 @@ NullHttpChannel::GetIsTrackingResource(bool *aIsTrackingResource) { return NS_ERROR_NOT_IMPLEMENTED; } +NS_IMETHODIMP +NullHttpChannel::GetFlashPluginState( + nsIHttpChannel::FlashPluginState *aResult) { + return NS_ERROR_NOT_IMPLEMENTED; +} + NS_IMETHODIMP NullHttpChannel::GetIsThirdPartyTrackingResource(bool *aIsTrackingResource) { return NS_ERROR_NOT_IMPLEMENTED; diff --git a/netwerk/protocol/http/PHttpBackgroundChannel.ipdl b/netwerk/protocol/http/PHttpBackgroundChannel.ipdl index 3b4191d73305..50359499a7d1 100644 --- a/netwerk/protocol/http/PHttpBackgroundChannel.ipdl +++ b/netwerk/protocol/http/PHttpBackgroundChannel.ipdl @@ -13,6 +13,7 @@ include "mozilla/net/NeckoMessageUtils.h"; using class nsHttpHeaderArray from "nsHttpHeaderArray.h"; using struct mozilla::net::ResourceTimingStruct from "mozilla/net/TimingStruct.h"; +using nsIHttpChannel::FlashPluginState from "mozilla/net/NeckoMessageUtils.h"; namespace mozilla { namespace net { @@ -66,6 +67,10 @@ child: // protection list. async NotifyTrackingResource(bool aIsThirdParty); + // Tell the child that the current channel's document is not allowed to load + // flash content. + async NotifyFlashPluginStateChanged(FlashPluginState aState); + // Tell the child information of matched URL againts SafeBrowsing list async SetClassifierMatchedInfo(ClassifierInfo info); diff --git a/netwerk/protocol/http/nsIHttpChannel.idl b/netwerk/protocol/http/nsIHttpChannel.idl index e63e97cb9686..f4e4a0d30c5e 100644 --- a/netwerk/protocol/http/nsIHttpChannel.idl +++ b/netwerk/protocol/http/nsIHttpChannel.idl @@ -495,6 +495,20 @@ interface nsIHttpChannel : nsIChannel */ [infallible] readonly attribute boolean isThirdPartyTrackingResource; + /** + * Returns the allowing status for flash plugin for this channel. + */ + cenum FlashPluginState : 8 { + FlashPluginUnknown = 0, + FlashPluginAllowed = 1, + FlashPluginDenied = 2, + FlashPluginDeniedInSubdocuments = 3, + + // Keep this equal to the last value. + FlashPluginLastValue = 3, + }; + [infallible] readonly attribute nsIHttpChannel_FlashPluginState flashPluginState; + /** * This method is used by the document.cookie call site in order * to override the tracking status of an HTTP channel. This should diff --git a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp index 39632af560f6..253de988d8f3 100644 --- a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp +++ b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp @@ -765,6 +765,13 @@ nsViewSourceChannel::GetIsTrackingResource(bool *aIsTrackingResource) { : mHttpChannel->GetIsTrackingResource(aIsTrackingResource); } +NS_IMETHODIMP +nsViewSourceChannel::GetFlashPluginState( + nsIHttpChannel::FlashPluginState *aResult) { + return !mHttpChannel ? NS_ERROR_NULL_POINTER + : mHttpChannel->GetFlashPluginState(aResult); +} + NS_IMETHODIMP nsViewSourceChannel::GetIsThirdPartyTrackingResource( bool *aIsTrackingResource) { diff --git a/netwerk/url-classifier/AsyncUrlChannelClassifier.cpp b/netwerk/url-classifier/AsyncUrlChannelClassifier.cpp index f4ab87fe75db..1f976258e4c7 100644 --- a/netwerk/url-classifier/AsyncUrlChannelClassifier.cpp +++ b/netwerk/url-classifier/AsyncUrlChannelClassifier.cpp @@ -24,6 +24,74 @@ namespace net { namespace { +// When we do blacklist/whitelist classification, from a list of features, we +// need to aggregate them per URI, because not all the features work with the +// same channel's URI. +// This struct contains only the features able to deal with a particular URI. +// See more in GetFeatureTasks(). +struct FeatureTask { + nsCOMPtr mURI; + // Let's use RefPtr<> here, because this needs to be used with methods which + // require it. + nsTArray> mFeatures; +}; + +// Features are able to classify particular URIs from a channel. For instance, +// tracking-annotation feature uses the top-level URI to whitelist the current +// channel's URI; flash feature always uses the channel's URI. Because of +// this, this function aggregates feature per URI in an array of FeatureTask +// object. +nsresult GetFeatureTasks( + nsIChannel* aChannel, + const nsTArray>& aFeatures, + nsIUrlClassifierFeature::listType aListType, + nsTArray& aTasks) { + MOZ_ASSERT(!aFeatures.IsEmpty()); + + // Let's unify features per nsIURI. + for (nsIUrlClassifierFeature* feature : aFeatures) { + nsCOMPtr uri; + nsresult rv = + feature->GetURIByListType(aChannel, aListType, getter_AddRefs(uri)); + if (NS_WARN_IF(NS_FAILED(rv)) || !uri) { + if (UC_LOG_ENABLED()) { + nsAutoCString errorName; + GetErrorName(rv, errorName); + UC_LOG( + ("GetFeatureTasks got an unexpected error (rv=%s) while trying to " + "create a whitelist URI. Allowing tracker.", + errorName.get())); + } + return rv; + } + + MOZ_ASSERT(uri); + + bool found = false; + for (FeatureTask& task : aTasks) { + bool equal = false; + rv = task.mURI->Equals(uri, &equal); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + if (equal) { + task.mFeatures.AppendElement(feature); + found = true; + break; + } + } + + if (!found) { + FeatureTask* task = aTasks.AppendElement(); + task->mURI = uri; + task->mFeatures.AppendElement(feature); + } + } + + return NS_OK; +} + nsresult TrackerFound( const nsTArray>& aResults, nsIChannel* aChannel, const std::function& aCallback) { @@ -48,81 +116,6 @@ nsresult TrackerFound( return NS_OK; } -nsresult CreateWhiteListURI(nsIChannel* aChannel, nsIURI** aURI) { - MOZ_ASSERT(aChannel); - MOZ_ASSERT(aURI); - - nsresult rv; - nsCOMPtr chan = do_QueryInterface(aChannel, &rv); - NS_ENSURE_SUCCESS(rv, rv); - if (!chan) { - return NS_ERROR_FAILURE; - } - - nsCOMPtr topWinURI; - rv = chan->GetTopWindowURI(getter_AddRefs(topWinURI)); - NS_ENSURE_SUCCESS(rv, rv); - if (!topWinURI) { - if (UC_LOG_ENABLED()) { - nsresult rv; - nsCOMPtr httpChan = do_QueryInterface(aChannel, &rv); - nsCOMPtr uri; - rv = httpChan->GetURI(getter_AddRefs(uri)); - nsAutoCString spec; - uri->GetAsciiSpec(spec); - spec.Truncate( - std::min(spec.Length(), UrlClassifierCommon::sMaxSpecLength)); - UC_LOG( - ("CreateWhiteListURI: No window URI associated with %s", spec.get())); - } - return NS_OK; - } - - nsCOMPtr securityManager = - do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr chanPrincipal; - rv = securityManager->GetChannelURIPrincipal(aChannel, - getter_AddRefs(chanPrincipal)); - NS_ENSURE_SUCCESS(rv, rv); - - // Craft a whitelist URL like "toplevel.page/?resource=third.party.domain" - nsAutoCString pageHostname, resourceDomain; - rv = topWinURI->GetHost(pageHostname); - NS_ENSURE_SUCCESS(rv, rv); - rv = chanPrincipal->GetBaseDomain(resourceDomain); - NS_ENSURE_SUCCESS(rv, rv); - nsAutoCString whitelistEntry = NS_LITERAL_CSTRING("http://") + pageHostname + - NS_LITERAL_CSTRING("/?resource=") + - resourceDomain; - UC_LOG(("CreateWhiteListURI: Looking for %s in the whitelist (channel=%p)", - whitelistEntry.get(), aChannel)); - - nsCOMPtr whitelistURI; - rv = NS_NewURI(getter_AddRefs(whitelistURI), whitelistEntry); - NS_ENSURE_SUCCESS(rv, rv); - - whitelistURI.forget(aURI); - return NS_OK; -} - -nsresult IsTrackerWhitelisted( - nsIURI* aWhiteListURI, - const nsTArray>& aFeatures, - nsIUrlClassifierFeatureCallback* aCallback) { - MOZ_ASSERT(aWhiteListURI); - MOZ_ASSERT(!aFeatures.IsEmpty()); - MOZ_ASSERT(aCallback); - - nsresult rv; - nsCOMPtr uriClassifier = - do_GetService(NS_URICLASSIFIERSERVICE_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - return uriClassifier->AsyncClassifyLocalWithFeatures( - aWhiteListURI, aFeatures, nsIUrlClassifierFeature::whitelist, aCallback); -} - // This class is designed to get the results of checking whitelist. class WhitelistClassifierCallback final : public nsIUrlClassifierFeatureCallback { @@ -131,25 +124,34 @@ class WhitelistClassifierCallback final NS_DECL_NSIURLCLASSIFIERFEATURECALLBACK WhitelistClassifierCallback( - nsIChannel* aChannel, nsIURI* aURI, + nsIChannel* aChannel, const nsTArray>& aBlacklistResults, std::function& aCallback) : mChannel(aChannel), - mURI(aURI), + mTaskCount(0), mBlacklistResults(aBlacklistResults), mChannelCallback(aCallback) { MOZ_ASSERT(mChannel); - MOZ_ASSERT(mURI); MOZ_ASSERT(!mBlacklistResults.IsEmpty()); } + void SetTaskCount(uint32_t aTaskCount) { + MOZ_ASSERT(aTaskCount > 0); + mTaskCount = aTaskCount; + } + private: ~WhitelistClassifierCallback() = default; + nsresult OnClassifyCompleteInternal(); + nsCOMPtr mChannel; nsCOMPtr mURI; + uint32_t mTaskCount; nsTArray> mBlacklistResults; std::function mChannelCallback; + + nsTArray> mWhitelistResults; }; NS_IMPL_ISUPPORTS(WhitelistClassifierCallback, nsIUrlClassifierFeatureCallback) @@ -157,18 +159,33 @@ NS_IMPL_ISUPPORTS(WhitelistClassifierCallback, nsIUrlClassifierFeatureCallback) NS_IMETHODIMP WhitelistClassifierCallback::OnClassifyComplete( const nsTArray>& aWhitelistResults) { + MOZ_ASSERT(mTaskCount > 0); + UC_LOG(("WhitelistClassifierCallback[%p]:OnClassifyComplete channel=%p", this, mChannel.get())); + mWhitelistResults.AppendElements(aWhitelistResults); + + if (--mTaskCount) { + // More callbacks will come. + return NS_OK; + } + + return OnClassifyCompleteInternal(); +} + +nsresult WhitelistClassifierCallback::OnClassifyCompleteInternal() { nsTArray> remainingResults; for (nsIUrlClassifierFeatureResult* blacklistResult : mBlacklistResults) { - nsIUrlClassifierFeature* blacklistFeature = - static_cast(blacklistResult)->Feature(); + UrlClassifierFeatureResult* result = + static_cast(blacklistResult); + + nsIUrlClassifierFeature* blacklistFeature = result->Feature(); MOZ_ASSERT(blacklistFeature); bool found = false; - for (nsIUrlClassifierFeatureResult* whitelistResult : aWhitelistResults) { + for (nsIUrlClassifierFeatureResult* whitelistResult : mWhitelistResults) { // We can do pointer comparison because Features are singletons. if (static_cast(whitelistResult) ->Feature() == blacklistFeature) { @@ -188,13 +205,12 @@ WhitelistClassifierCallback::OnClassifyComplete( continue; } - if (nsContentUtils::IsURIInList(mURI, skipList)) { + if (nsContentUtils::IsURIInList(result->URI(), skipList)) { if (UC_LOG_ENABLED()) { - nsCString spec = mURI->GetSpecOrDefault(); UC_LOG( - ("WhitelistClassifierCallback[%p]::OnClassifyComplete uri %s found " - "in skiplist", - this, spec.get())); + ("WhitelistClassifierCallback[%p]::OnClassifyComplete uri found in " + "skiplist", + this)); } continue; @@ -207,13 +223,10 @@ WhitelistClassifierCallback::OnClassifyComplete( if (remainingResults.IsEmpty()) { if (UC_LOG_ENABLED()) { - nsCString spec = mURI->GetSpecOrDefault(); - spec.Truncate( - std::min(spec.Length(), UrlClassifierCommon::sMaxSpecLength)); UC_LOG( - ("WhitelistClassifierCallback[%p]::OnClassifyComplete uri %s fully " + ("WhitelistClassifierCallback[%p]::OnClassifyComplete uri fully " "whitelisted", - this, spec.get())); + this)); } mChannelCallback(); @@ -221,12 +234,10 @@ WhitelistClassifierCallback::OnClassifyComplete( } if (UC_LOG_ENABLED()) { - nsCString spec = mURI->GetSpecOrDefault(); - spec.Truncate(std::min(spec.Length(), UrlClassifierCommon::sMaxSpecLength)); UC_LOG( - ("WhitelistClassifierCallback[%p]::OnClassifyComplete " - "channel[%p] uri=%s, should not be whitelisted", - this, mChannel.get(), spec.get())); + ("WhitelistClassifierCallback[%p]::OnClassifyComplete channel[%p] " + "should not be whitelisted", + this, mChannel.get())); } return TrackerFound(remainingResults, mChannel, mChannelCallback); @@ -239,19 +250,29 @@ class BlacklistClassifierCallback final NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSIURLCLASSIFIERFEATURECALLBACK - BlacklistClassifierCallback(nsIChannel* aChannel, nsIURI* aURI, + BlacklistClassifierCallback(nsIChannel* aChannel, std::function&& aCallback) - : mChannel(aChannel), mURI(aURI), mChannelCallback(std::move(aCallback)) { + : mChannel(aChannel), + mTaskCount(0), + mChannelCallback(std::move(aCallback)) { MOZ_ASSERT(mChannel); - MOZ_ASSERT(mURI); + } + + void SetTaskCount(uint32_t aTaskCount) { + MOZ_ASSERT(aTaskCount > 0); + mTaskCount = aTaskCount; } private: ~BlacklistClassifierCallback() = default; + nsresult OnClassifyCompleteInternal(); + nsCOMPtr mChannel; - nsCOMPtr mURI; + uint32_t mTaskCount; std::function mChannelCallback; + + nsTArray> mResults; }; NS_IMPL_ISUPPORTS(BlacklistClassifierCallback, nsIUrlClassifierFeatureCallback) @@ -259,18 +280,29 @@ NS_IMPL_ISUPPORTS(BlacklistClassifierCallback, nsIUrlClassifierFeatureCallback) NS_IMETHODIMP BlacklistClassifierCallback::OnClassifyComplete( const nsTArray>& aResults) { - UC_LOG(("BlacklistClassifierCallback[%p]:OnClassifyComplete", this)); + MOZ_ASSERT(mTaskCount > 0); + UC_LOG(("BlacklistClassifierCallback[%p]:OnClassifyComplete - remaining %d", + this, mTaskCount)); + + mResults.AppendElements(aResults); + + if (--mTaskCount) { + // More callbacks will come. + return NS_OK; + } + + return OnClassifyCompleteInternal(); +} + +nsresult BlacklistClassifierCallback::OnClassifyCompleteInternal() { // All good! The URL has not been classified. - if (aResults.IsEmpty()) { + if (mResults.IsEmpty()) { if (UC_LOG_ENABLED()) { - nsCString spec = mURI->GetSpecOrDefault(); - spec.Truncate( - std::min(spec.Length(), UrlClassifierCommon::sMaxSpecLength)); UC_LOG( - ("BlacklistClassifierCallback[%p]::OnClassifyComplete uri %s not " - "found in blacklist", - this, spec.get())); + ("BlacklistClassifierCallback[%p]::OnClassifyComplete uri not found " + "in blacklist", + this)); } mChannelCallback(); @@ -278,63 +310,79 @@ BlacklistClassifierCallback::OnClassifyComplete( } if (UC_LOG_ENABLED()) { - nsCString spec = mURI->GetSpecOrDefault(); - spec.Truncate(std::min(spec.Length(), UrlClassifierCommon::sMaxSpecLength)); UC_LOG( - ("BlacklistClassifierCallback[%p]::OnClassifyComplete uri %s is in " + ("BlacklistClassifierCallback[%p]::OnClassifyComplete uri is in " "blacklist. Start checking whitelist.", - this, spec.get())); + this)); } - nsCOMPtr whitelistURI; - nsresult rv = CreateWhiteListURI(mChannel, getter_AddRefs(whitelistURI)); - if (NS_FAILED(rv)) { - nsAutoCString errorName; - GetErrorName(rv, errorName); - NS_WARNING( - nsPrintfCString("BlacklistClassifierCallback[%p]:OnClassifyComplete " - "got an unexpected error (rv=%s) while trying to " - "create a whitelist URI. Allowing tracker.", - this, errorName.get()) - .get()); - return TrackerFound(aResults, mChannel, mChannelCallback); + nsTArray> features; + for (nsIUrlClassifierFeatureResult* result : mResults) { + features.AppendElement( + static_cast(result)->Feature()); } - if (!whitelistURI) { + nsTArray tasks; + nsresult rv = GetFeatureTasks(mChannel, features, + nsIUrlClassifierFeature::whitelist, tasks); + if (NS_WARN_IF(NS_FAILED(rv))) { + return TrackerFound(mResults, mChannel, mChannelCallback); + } + + if (tasks.IsEmpty()) { UC_LOG( ("BlacklistClassifierCallback[%p]:OnClassifyComplete could not create " "a whitelist URI. Ignoring whitelist.", this)); - return TrackerFound(aResults, mChannel, mChannelCallback); + return TrackerFound(mResults, mChannel, mChannelCallback); } - nsCOMPtr callback = - new WhitelistClassifierCallback(mChannel, mURI, aResults, - mChannelCallback); + RefPtr callback = + new WhitelistClassifierCallback(mChannel, mResults, mChannelCallback); - // xpcom parser creates array of interfaces using RefPtr<>. - nsTArray> refPtrFeatures; - for (nsIUrlClassifierFeatureResult* result : aResults) { - refPtrFeatures.AppendElement( - static_cast(result)->Feature()); - } + nsCOMPtr uriClassifier = + do_GetService(NS_URICLASSIFIERSERVICE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); - rv = IsTrackerWhitelisted(whitelistURI, refPtrFeatures, callback); - if (NS_WARN_IF(NS_FAILED(rv))) { - if (UC_LOG_ENABLED()) { - nsAutoCString errorName; - GetErrorName(rv, errorName); - UC_LOG( - ("BlacklistClassifierCallback[%p]:OnClassifyComplete " - "IsTrackerWhitelisted has failed with rv=%s.", - this, errorName.get())); + uint32_t pendingCallbacks = 0; + for (FeatureTask& task : tasks) { + rv = uriClassifier->AsyncClassifyLocalWithFeatures( + task.mURI, task.mFeatures, nsIUrlClassifierFeature::whitelist, + callback); + + if (NS_WARN_IF(NS_FAILED(rv))) { + if (UC_LOG_ENABLED()) { + nsAutoCString errorName; + GetErrorName(rv, errorName); + UC_LOG(( + "BlacklistClassifierCallback[%p]:OnClassifyComplete Failed " + "calling AsyncClassifyLocalWithFeatures with rv=%s. Let's move on.", + this, errorName.get())); + } + + continue; } - return TrackerFound(aResults, mChannel, mChannelCallback); + ++pendingCallbacks; + } + + // All the AsyncClassifyLocalWithFeatures() calls return error. We do not + // expect callbacks. + if (pendingCallbacks == 0) { + if (UC_LOG_ENABLED()) { + UC_LOG( + ("BlacklistClassifierCallback[%p]:OnClassifyComplete All " + "AsyncClassifyLocalWithFeatures() calls return errors. We cannot " + "continue.", + this)); + } + + return TrackerFound(mResults, mChannel, mChannelCallback); } // Nothing else do here. Let's wait for the WhitelistClassifierCallback. + callback->SetTaskCount(pendingCallbacks); return NS_OK; } @@ -349,44 +397,62 @@ BlacklistClassifierCallback::OnClassifyComplete( return NS_ERROR_INVALID_ARG; } - nsCOMPtr uri; - nsresult rv = aChannel->GetURI(getter_AddRefs(uri)); - if (NS_FAILED(rv) || !uri) { - return rv; - } - + // We need to obtain the list of nsIUrlClassifierFeature objects able to + // classify this channel. If the list is empty, we do an early return. nsTArray> features; UrlClassifierFeatureFactory::GetFeaturesFromChannel(aChannel, features); if (features.IsEmpty()) { - UC_LOG(("AsyncUrlChannelClassifier: Feature list is empty for channel %p", - aChannel)); + UC_LOG( + ("AsyncUrlChannelClassifier: Nothing to do for channel %p", aChannel)); return NS_ERROR_FAILURE; } + nsTArray tasks; + nsresult rv = GetFeatureTasks(aChannel, features, + nsIUrlClassifierFeature::blacklist, tasks); + if (NS_WARN_IF(NS_FAILED(rv)) || tasks.IsEmpty()) { + return rv; + } + + MOZ_ASSERT(!tasks.IsEmpty()); + nsCOMPtr uriClassifier = do_GetService(NS_URICLASSIFIERSERVICE_CONTRACTID, &rv); if (NS_FAILED(rv)) { return rv; } - nsCOMPtr callback = - new BlacklistClassifierCallback(aChannel, uri, std::move(aCallback)); + RefPtr callback = + new BlacklistClassifierCallback(aChannel, std::move(aCallback)); - if (UC_LOG_ENABLED()) { - nsCString spec = uri->GetSpecOrDefault(); - spec.Truncate(std::min(spec.Length(), UrlClassifierCommon::sMaxSpecLength)); - UC_LOG(("AsyncUrlChannelClassifier: Checking blacklist for uri=%s\n", - spec.get())); + uint32_t pendingCallbacks = 0; + for (FeatureTask& task : tasks) { + if (UC_LOG_ENABLED()) { + nsCString spec = task.mURI->GetSpecOrDefault(); + spec.Truncate( + std::min(spec.Length(), UrlClassifierCommon::sMaxSpecLength)); + UC_LOG(("AsyncUrlChannelClassifier: Checking blacklist for uri=%s\n", + spec.get())); + } + + rv = uriClassifier->AsyncClassifyLocalWithFeatures( + task.mURI, task.mFeatures, nsIUrlClassifierFeature::blacklist, + callback); + if (NS_WARN_IF(NS_FAILED(rv))) { + continue; + } + + ++pendingCallbacks; } - // xpcom parser creates array of interfaces using RefPtr<>. - nsTArray> refPtrFeatures; - for (nsIUrlClassifierFeature* feature : features) { - refPtrFeatures.AppendElement(feature); + // All the AsyncClassifyLocalWithFeatures() calls return error. We do not + // expect callbacks. + if (pendingCallbacks == 0) { + return NS_ERROR_FAILURE; } - return uriClassifier->AsyncClassifyLocalWithFeatures( - uri, refPtrFeatures, nsIUrlClassifierFeature::blacklist, callback); + callback->SetTaskCount(pendingCallbacks); + return NS_OK; } } // namespace net diff --git a/netwerk/url-classifier/UrlClassifierCommon.cpp b/netwerk/url-classifier/UrlClassifierCommon.cpp index 118dbddb809d..45a70ae60620 100644 --- a/netwerk/url-classifier/UrlClassifierCommon.cpp +++ b/netwerk/url-classifier/UrlClassifierCommon.cpp @@ -244,5 +244,66 @@ UrlClassifierCommon::ShouldEnableTrackingProtectionOrAnnotation( return NS_OK; } +/* static */ nsresult UrlClassifierCommon::CreatePairwiseWhiteListURI( + nsIChannel* aChannel, nsIURI** aURI) { + MOZ_ASSERT(aChannel); + MOZ_ASSERT(aURI); + + nsresult rv; + nsCOMPtr chan = do_QueryInterface(aChannel, &rv); + NS_ENSURE_SUCCESS(rv, rv); + if (!chan) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr topWinURI; + rv = chan->GetTopWindowURI(getter_AddRefs(topWinURI)); + NS_ENSURE_SUCCESS(rv, rv); + if (!topWinURI) { + if (UC_LOG_ENABLED()) { + nsresult rv; + nsCOMPtr httpChan = do_QueryInterface(aChannel, &rv); + nsCOMPtr uri; + rv = httpChan->GetURI(getter_AddRefs(uri)); + nsAutoCString spec; + uri->GetAsciiSpec(spec); + spec.Truncate( + std::min(spec.Length(), UrlClassifierCommon::sMaxSpecLength)); + UC_LOG(("CreatePairwiseWhiteListURI: No window URI associated with %s", + spec.get())); + } + return NS_OK; + } + + nsCOMPtr securityManager = + do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr chanPrincipal; + rv = securityManager->GetChannelURIPrincipal(aChannel, + getter_AddRefs(chanPrincipal)); + NS_ENSURE_SUCCESS(rv, rv); + + // Craft a whitelist URL like "toplevel.page/?resource=third.party.domain" + nsAutoCString pageHostname, resourceDomain; + rv = topWinURI->GetHost(pageHostname); + NS_ENSURE_SUCCESS(rv, rv); + rv = chanPrincipal->GetBaseDomain(resourceDomain); + NS_ENSURE_SUCCESS(rv, rv); + nsAutoCString whitelistEntry = NS_LITERAL_CSTRING("http://") + pageHostname + + NS_LITERAL_CSTRING("/?resource=") + + resourceDomain; + UC_LOG( + ("CreatePairwiseWhiteListURI: Looking for %s in the whitelist " + "(channel=%p)", + whitelistEntry.get(), aChannel)); + + nsCOMPtr whitelistURI; + rv = NS_NewURI(getter_AddRefs(whitelistURI), whitelistEntry); + NS_ENSURE_SUCCESS(rv, rv); + + whitelistURI.forget(aURI); + return NS_OK; +} + } // namespace net } // namespace mozilla diff --git a/netwerk/url-classifier/UrlClassifierCommon.h b/netwerk/url-classifier/UrlClassifierCommon.h index 92ab53ddf56b..43eba415f195 100644 --- a/netwerk/url-classifier/UrlClassifierCommon.h +++ b/netwerk/url-classifier/UrlClassifierCommon.h @@ -41,6 +41,11 @@ class UrlClassifierCommon final { const nsACString& aList, const nsACString& aProvider, const nsACString& aFullHash); + + // Use this function only when you are looking for a pairwise whitelist uri + // with the format: http://toplevel.page/?resource=channel.uri.domain + static nsresult CreatePairwiseWhiteListURI(nsIChannel* aChannel, + nsIURI** aURI); }; } // namespace net diff --git a/netwerk/url-classifier/UrlClassifierFeatureFactory.cpp b/netwerk/url-classifier/UrlClassifierFeatureFactory.cpp index 780a2321e8a1..1ecfd83c53a5 100644 --- a/netwerk/url-classifier/UrlClassifierFeatureFactory.cpp +++ b/netwerk/url-classifier/UrlClassifierFeatureFactory.cpp @@ -7,6 +7,7 @@ #include "mozilla/net/UrlClassifierFeatureFactory.h" // List of Features +#include "UrlClassifierFeatureFlash.h" #include "UrlClassifierFeatureLoginReputation.h" #include "UrlClassifierFeatureTrackingProtection.h" #include "UrlClassifierFeatureTrackingAnnotation.h" @@ -22,6 +23,7 @@ namespace net { return; } + UrlClassifierFeatureFlash::Initialize(); UrlClassifierFeatureTrackingAnnotation::Initialize(); UrlClassifierFeatureTrackingProtection::Initialize(); } @@ -32,6 +34,7 @@ namespace net { return; } + UrlClassifierFeatureFlash::Shutdown(); UrlClassifierFeatureLoginReputation::MaybeShutdown(); UrlClassifierFeatureTrackingAnnotation::Shutdown(); UrlClassifierFeatureTrackingProtection::Shutdown(); @@ -61,6 +64,11 @@ namespace net { if (feature) { aFeatures.AppendElement(feature); } + + // Flash + nsTArray> flashFeatures; + UrlClassifierFeatureFlash::MaybeCreate(aChannel, flashFeatures); + aFeatures.AppendElements(flashFeatures); } /* static */ diff --git a/netwerk/url-classifier/UrlClassifierFeatureFlash.cpp b/netwerk/url-classifier/UrlClassifierFeatureFlash.cpp new file mode 100644 index 000000000000..d6f7167f6f34 --- /dev/null +++ b/netwerk/url-classifier/UrlClassifierFeatureFlash.cpp @@ -0,0 +1,155 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "UrlClassifierFeatureFlash.h" +#include "mozilla/net/HttpBaseChannel.h" +#include "nsScriptSecurityManager.h" +#include "nsQueryObject.h" + +namespace mozilla { +namespace net { + +namespace { + +struct FlashFeatures { + const char* mName; + const char* mBlacklistPrefTables; + const char* mWhitelistPrefTables; + bool mSubdocumentOnly; + nsIHttpChannel::FlashPluginState mFlashPluginState; + RefPtr mFeature; +}; + +static FlashFeatures sFlashFeaturesMap[] = { + {"flash-deny", "urlclassifier.flashTable", "urlclassifier.flashExceptTable", + false, nsIHttpChannel::FlashPluginDenied}, + {"flash-allow", "urlclassifier.flashAllowTable", + "urlclassifier.flashAllowExceptTable", false, + nsIHttpChannel::FlashPluginAllowed}, + {"flash-deny-subdoc", "urlclassifier.flashSubDocTable", + "urlclassifier.flashSubDocExceptTable", true, + nsIHttpChannel::FlashPluginDeniedInSubdocuments}, +}; + +} // namespace + +UrlClassifierFeatureFlash::UrlClassifierFeatureFlash(uint32_t aId) + : UrlClassifierFeatureBase( + nsDependentCString(sFlashFeaturesMap[aId].mName), + nsDependentCString(sFlashFeaturesMap[aId].mBlacklistPrefTables), + nsDependentCString(sFlashFeaturesMap[aId].mWhitelistPrefTables), + EmptyCString(), // aPrefBlacklistHosts + EmptyCString(), // aPrefWhitelistHosts + EmptyCString(), // aPrefBlacklistTableName + EmptyCString(), // aPrefWhitelistTableName + EmptyCString()) // aPrefSkipHosts + , + mFlashPluginState(sFlashFeaturesMap[aId].mFlashPluginState) { + static_assert(nsIHttpChannel::FlashPluginDeniedInSubdocuments == + nsIHttpChannel::FlashPluginLastValue, + "nsIHttpChannel::FlashPluginLastValue is out-of-sync!"); +} + +/* static */ void UrlClassifierFeatureFlash::Initialize() { + uint32_t numFeatures = + (sizeof(sFlashFeaturesMap) / sizeof(sFlashFeaturesMap[0])); + for (uint32_t i = 0; i < numFeatures; ++i) { + MOZ_ASSERT(!sFlashFeaturesMap[i].mFeature); + sFlashFeaturesMap[i].mFeature = new UrlClassifierFeatureFlash(i); + sFlashFeaturesMap[i].mFeature->InitializePreferences(); + } +} + +/* static */ void UrlClassifierFeatureFlash::Shutdown() { + uint32_t numFeatures = + (sizeof(sFlashFeaturesMap) / sizeof(sFlashFeaturesMap[0])); + for (uint32_t i = 0; i < numFeatures; ++i) { + MOZ_ASSERT(sFlashFeaturesMap[i].mFeature); + sFlashFeaturesMap[i].mFeature->ShutdownPreferences(); + sFlashFeaturesMap[i].mFeature = nullptr; + } +} + +/* static */ void UrlClassifierFeatureFlash::MaybeCreate( + nsIChannel* aChannel, + nsTArray>& aFeatures) { + // All disabled. + if (!StaticPrefs::plugins_flashBlock_enabled()) { + return; + } + + // We use Flash feature just for document loading. + nsCOMPtr loadInfo = aChannel->GetLoadInfo(); + nsContentPolicyType contentPolicyType = + loadInfo ? loadInfo->GetExternalContentPolicyType() + : nsIContentPolicy::TYPE_INVALID; + + if (contentPolicyType != nsIContentPolicy::TYPE_DOCUMENT && + contentPolicyType != nsIContentPolicy::TYPE_SUBDOCUMENT) { + return; + } + + // Only allow plugins for documents from an HTTP/HTTPS origin. + if (StaticPrefs::plugins_http_https_only()) { + nsCOMPtr httpChannel = do_QueryInterface(aChannel); + if (!httpChannel) { + return; + } + } + + uint32_t numFeatures = + (sizeof(sFlashFeaturesMap) / sizeof(sFlashFeaturesMap[0])); + for (uint32_t i = 0; i < numFeatures; ++i) { + MOZ_ASSERT(sFlashFeaturesMap[i].mFeature); + if (!sFlashFeaturesMap[i].mSubdocumentOnly || + contentPolicyType == nsIContentPolicy::TYPE_SUBDOCUMENT) { + aFeatures.AppendElement(sFlashFeaturesMap[i].mFeature); + } + } +} + +NS_IMETHODIMP +UrlClassifierFeatureFlash::ProcessChannel(nsIChannel* aChannel, + const nsACString& aList, + bool* aShouldContinue) { + NS_ENSURE_ARG_POINTER(aChannel); + NS_ENSURE_ARG_POINTER(aShouldContinue); + + // This is not a blocking feature. + *aShouldContinue = true; + + UC_LOG(("UrlClassifierFeatureFlash::ProcessChannel, annotating channel[%p]", + aChannel)); + + nsCOMPtr parentChannel; + NS_QueryNotificationCallbacks(aChannel, parentChannel); + if (parentChannel) { + // This channel is a parent-process proxy for a child process + // request. We should notify the child process as well. + parentChannel->NotifyFlashPluginStateChanged(mFlashPluginState); + } + + RefPtr httpChannel = do_QueryObject(aChannel); + if (httpChannel) { + httpChannel->SetFlashPluginState(mFlashPluginState); + } + + return NS_OK; +} + +NS_IMETHODIMP +UrlClassifierFeatureFlash::GetURIByListType( + nsIChannel* aChannel, nsIUrlClassifierFeature::listType aListType, + nsIURI** aURI) { + NS_ENSURE_ARG_POINTER(aChannel); + NS_ENSURE_ARG_POINTER(aURI); + + // Here we return the channel's URI always. + return aChannel->GetURI(aURI); +} + +} // namespace net +} // namespace mozilla diff --git a/netwerk/url-classifier/UrlClassifierFeatureFlash.h b/netwerk/url-classifier/UrlClassifierFeatureFlash.h new file mode 100644 index 000000000000..082fda85b9fa --- /dev/null +++ b/netwerk/url-classifier/UrlClassifierFeatureFlash.h @@ -0,0 +1,41 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#ifndef mozilla_UrlClassifierFeatureFlash_h +#define mozilla_UrlClassifierFeatureFlash_h + +#include "UrlClassifierFeatureBase.h" + +namespace mozilla { +namespace net { + +class UrlClassifierFeatureFlash final : public UrlClassifierFeatureBase { + public: + static void Initialize(); + static void Shutdown(); + + static void MaybeCreate( + nsIChannel* aChannel, + nsTArray>& aFeatures); + + NS_IMETHOD + ProcessChannel(nsIChannel* aChannel, const nsACString& aList, + bool* aShouldContinue) override; + + NS_IMETHOD GetURIByListType(nsIChannel* aChannel, + nsIUrlClassifierFeature::listType aListType, + nsIURI** aURI) override; + + private: + explicit UrlClassifierFeatureFlash(uint32_t aId); + + nsIHttpChannel::FlashPluginState mFlashPluginState; +}; + +} // namespace net +} // namespace mozilla + +#endif // mozilla_UrlClassifierFeatureFlash_h diff --git a/netwerk/url-classifier/UrlClassifierFeatureLoginReputation.cpp b/netwerk/url-classifier/UrlClassifierFeatureLoginReputation.cpp index bcb0df8faeba..4dea5f36cf7b 100644 --- a/netwerk/url-classifier/UrlClassifierFeatureLoginReputation.cpp +++ b/netwerk/url-classifier/UrlClassifierFeatureLoginReputation.cpp @@ -93,5 +93,18 @@ UrlClassifierFeatureLoginReputation::HasHostInPreferences( aHost, aListType, aPrefTableName, aResult); } +NS_IMETHODIMP +UrlClassifierFeatureLoginReputation::GetURIByListType( + nsIChannel* aChannel, nsIUrlClassifierFeature::listType aListType, + nsIURI** aURI) { + NS_ENSURE_ARG_POINTER(aChannel); + NS_ENSURE_ARG_POINTER(aURI); + MOZ_ASSERT(aListType == nsIUrlClassifierFeature::whitelist, + "UrlClassifierFeatureLoginReputation is meant to be used just to " + "whitelist URLs"); + + return aChannel->GetURI(aURI); +} + } // namespace net } // namespace mozilla diff --git a/netwerk/url-classifier/UrlClassifierFeatureLoginReputation.h b/netwerk/url-classifier/UrlClassifierFeatureLoginReputation.h index d7e6197af80c..13c4429cdcac 100644 --- a/netwerk/url-classifier/UrlClassifierFeatureLoginReputation.h +++ b/netwerk/url-classifier/UrlClassifierFeatureLoginReputation.h @@ -37,6 +37,10 @@ class UrlClassifierFeatureLoginReputation final NS_IMETHOD ProcessChannel(nsIChannel* aChannel, const nsACString& aList, bool* aShouldContinue) override; + NS_IMETHOD GetURIByListType(nsIChannel* aChannel, + nsIUrlClassifierFeature::listType aListType, + nsIURI** aURI) override; + private: UrlClassifierFeatureLoginReputation(); }; diff --git a/netwerk/url-classifier/UrlClassifierFeatureResult.cpp b/netwerk/url-classifier/UrlClassifierFeatureResult.cpp index 258d860c91fd..464c6cefe0d9 100644 --- a/netwerk/url-classifier/UrlClassifierFeatureResult.cpp +++ b/netwerk/url-classifier/UrlClassifierFeatureResult.cpp @@ -10,11 +10,19 @@ namespace mozilla { namespace net { UrlClassifierFeatureResult::UrlClassifierFeatureResult( - nsIUrlClassifierFeature* aFeature, const nsACString& aList) - : mFeature(aFeature), mList(aList) {} + nsIURI* aURI, nsIUrlClassifierFeature* aFeature, const nsACString& aList) + : mURI(aURI), mFeature(aFeature), mList(aList) {} UrlClassifierFeatureResult::~UrlClassifierFeatureResult() = default; +NS_IMETHODIMP +UrlClassifierFeatureResult::GetUri(nsIURI** aURI) { + NS_ENSURE_ARG_POINTER(aURI); + nsCOMPtr uri = mURI; + uri.forget(aURI); + return NS_OK; +} + NS_IMETHODIMP UrlClassifierFeatureResult::GetFeature(nsIUrlClassifierFeature** aFeature) { NS_ENSURE_ARG_POINTER(aFeature); diff --git a/netwerk/url-classifier/UrlClassifierFeatureResult.h b/netwerk/url-classifier/UrlClassifierFeatureResult.h index b6cf942c56ad..5987ed8d1062 100644 --- a/netwerk/url-classifier/UrlClassifierFeatureResult.h +++ b/netwerk/url-classifier/UrlClassifierFeatureResult.h @@ -10,6 +10,8 @@ #include "nsIUrlClassifierFeature.h" #include "nsString.h" +class nsIURI; + namespace mozilla { namespace net { @@ -18,9 +20,11 @@ class UrlClassifierFeatureResult final : public nsIUrlClassifierFeatureResult { NS_DECL_ISUPPORTS NS_DECL_NSIURLCLASSIFIERFEATURERESULT - UrlClassifierFeatureResult(nsIUrlClassifierFeature* aFeature, + UrlClassifierFeatureResult(nsIURI* aURI, nsIUrlClassifierFeature* aFeature, const nsACString& aList); + nsIURI* URI() const { return mURI; } + nsIUrlClassifierFeature* Feature() const { return mFeature; } // Comma separated list of tables. @@ -30,6 +34,7 @@ class UrlClassifierFeatureResult final : public nsIUrlClassifierFeatureResult { ~UrlClassifierFeatureResult(); private: + nsCOMPtr mURI; nsCOMPtr mFeature; const nsCString mList; }; diff --git a/netwerk/url-classifier/UrlClassifierFeatureTrackingAnnotation.cpp b/netwerk/url-classifier/UrlClassifierFeatureTrackingAnnotation.cpp index a14db800020c..db5917088542 100644 --- a/netwerk/url-classifier/UrlClassifierFeatureTrackingAnnotation.cpp +++ b/netwerk/url-classifier/UrlClassifierFeatureTrackingAnnotation.cpp @@ -201,5 +201,20 @@ UrlClassifierFeatureTrackingAnnotation::ProcessChannel(nsIChannel* aChannel, return NS_OK; } +NS_IMETHODIMP +UrlClassifierFeatureTrackingAnnotation::GetURIByListType( + nsIChannel* aChannel, nsIUrlClassifierFeature::listType aListType, + nsIURI** aURI) { + NS_ENSURE_ARG_POINTER(aChannel); + NS_ENSURE_ARG_POINTER(aURI); + + if (aListType == nsIUrlClassifierFeature::blacklist) { + return aChannel->GetURI(aURI); + } + + MOZ_ASSERT(aListType == nsIUrlClassifierFeature::whitelist); + return UrlClassifierCommon::CreatePairwiseWhiteListURI(aChannel, aURI); +} + } // namespace net } // namespace mozilla diff --git a/netwerk/url-classifier/UrlClassifierFeatureTrackingAnnotation.h b/netwerk/url-classifier/UrlClassifierFeatureTrackingAnnotation.h index 596775e53574..3f6fbba7ebb3 100644 --- a/netwerk/url-classifier/UrlClassifierFeatureTrackingAnnotation.h +++ b/netwerk/url-classifier/UrlClassifierFeatureTrackingAnnotation.h @@ -27,6 +27,10 @@ class UrlClassifierFeatureTrackingAnnotation final NS_IMETHOD ProcessChannel(nsIChannel* aChannel, const nsACString& aList, bool* aShouldContinue) override; + NS_IMETHOD GetURIByListType(nsIChannel* aChannel, + nsIUrlClassifierFeature::listType aListType, + nsIURI** aURI) override; + private: UrlClassifierFeatureTrackingAnnotation(); }; diff --git a/netwerk/url-classifier/UrlClassifierFeatureTrackingProtection.cpp b/netwerk/url-classifier/UrlClassifierFeatureTrackingProtection.cpp index 263457e59170..fb780b471a24 100644 --- a/netwerk/url-classifier/UrlClassifierFeatureTrackingProtection.cpp +++ b/netwerk/url-classifier/UrlClassifierFeatureTrackingProtection.cpp @@ -130,5 +130,20 @@ UrlClassifierFeatureTrackingProtection::ProcessChannel(nsIChannel* aChannel, return NS_OK; } +NS_IMETHODIMP +UrlClassifierFeatureTrackingProtection::GetURIByListType( + nsIChannel* aChannel, nsIUrlClassifierFeature::listType aListType, + nsIURI** aURI) { + NS_ENSURE_ARG_POINTER(aChannel); + NS_ENSURE_ARG_POINTER(aURI); + + if (aListType == nsIUrlClassifierFeature::blacklist) { + return aChannel->GetURI(aURI); + } + + MOZ_ASSERT(aListType == nsIUrlClassifierFeature::whitelist); + return UrlClassifierCommon::CreatePairwiseWhiteListURI(aChannel, aURI); +} + } // namespace net } // namespace mozilla diff --git a/netwerk/url-classifier/UrlClassifierFeatureTrackingProtection.h b/netwerk/url-classifier/UrlClassifierFeatureTrackingProtection.h index 25cfa3e29f1d..4713d2cf166c 100644 --- a/netwerk/url-classifier/UrlClassifierFeatureTrackingProtection.h +++ b/netwerk/url-classifier/UrlClassifierFeatureTrackingProtection.h @@ -27,6 +27,10 @@ class UrlClassifierFeatureTrackingProtection final NS_IMETHOD ProcessChannel(nsIChannel* aChannel, const nsACString& aList, bool* aShouldContinue) override; + NS_IMETHOD GetURIByListType(nsIChannel* aChannel, + nsIUrlClassifierFeature::listType aListType, + nsIURI** aURI) override; + private: UrlClassifierFeatureTrackingProtection(); }; diff --git a/netwerk/url-classifier/moz.build b/netwerk/url-classifier/moz.build index e3eeb562307c..2adee50d93f7 100644 --- a/netwerk/url-classifier/moz.build +++ b/netwerk/url-classifier/moz.build @@ -23,6 +23,7 @@ UNIFIED_SOURCES += [ 'UrlClassifierCommon.cpp', 'UrlClassifierFeatureBase.cpp', 'UrlClassifierFeatureFactory.cpp', + 'UrlClassifierFeatureFlash.cpp', 'UrlClassifierFeatureLoginReputation.cpp', 'UrlClassifierFeatureResult.cpp', 'UrlClassifierFeatureTrackingAnnotation.cpp', diff --git a/netwerk/url-classifier/nsIUrlClassifierFeature.idl b/netwerk/url-classifier/nsIUrlClassifierFeature.idl index 235c2bfae6ce..f20dd0f8389d 100644 --- a/netwerk/url-classifier/nsIUrlClassifierFeature.idl +++ b/netwerk/url-classifier/nsIUrlClassifierFeature.idl @@ -11,6 +11,7 @@ [ref] native StringArrayRef(nsTArray); interface nsIChannel; +interface nsIURI; /** * A single URLClassifier feature. @@ -62,6 +63,14 @@ interface nsIUrlClassifierFeature : nsISupports * processing other features. */ [noscript] boolean processChannel(in nsIChannel aChannel, in ACString aList); + + /** + * Features can work with different URLs from a channel (channel url, or + * top-level, or something else). This method returns what we need to use for + * the current list. + */ + [noscript] nsIURI getURIByListType(in nsIChannel channel, + in nsIUrlClassifierFeature_listType listType); }; /** @@ -71,6 +80,8 @@ interface nsIUrlClassifierFeature : nsISupports [builtinclass, scriptable, uuid(ccb88140-5d66-4873-9815-a1b98d6cdc92)] interface nsIUrlClassifierFeatureResult : nsISupports { + readonly attribute nsIURI uri; + readonly attribute nsIUrlClassifierFeature feature; // Comma separate tables or preferences. diff --git a/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp b/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp index 4f69827d866e..fb2358fd2f83 100644 --- a/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp +++ b/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp @@ -127,11 +127,12 @@ class FeatureHolder final { }; static already_AddRefed Create( - const nsTArray>& aFeatures, + nsIURI* aURI, const nsTArray>& aFeatures, nsIUrlClassifierFeature::listType aListType) { MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(aURI); - RefPtr holder = new FeatureHolder(); + RefPtr holder = new FeatureHolder(aURI); for (nsIUrlClassifierFeature* feature : aFeatures) { FeatureData* featureData = holder->mFeatureData.AppendElement(); @@ -202,20 +203,24 @@ class FeatureHolder final { } RefPtr result = - new mozilla::net::UrlClassifierFeatureResult(featureData.mFeature, - list); + new mozilla::net::UrlClassifierFeatureResult( + mURI, featureData.mFeature, list); aResults.AppendElement(result); } } private: - FeatureHolder() { MOZ_ASSERT(NS_IsMainThread()); } + explicit FeatureHolder(nsIURI* aURI) : mURI(aURI) { + MOZ_ASSERT(NS_IsMainThread()); + } ~FeatureHolder() { for (FeatureData& featureData : mFeatureData) { NS_ReleaseOnMainThreadSystemGroup("FeatureHolder:mFeatureData", featureData.mFeature.forget()); } + + NS_ReleaseOnMainThreadSystemGroup("FeatureHolder:mURI", mURI.forget()); } TableData* GetOrCreateTableData(const nsACString& aTable) { @@ -230,6 +235,7 @@ class FeatureHolder final { return tableData; } + nsCOMPtr mURI; nsTArray mFeatureData; nsTArray> mTableData; }; @@ -300,6 +306,13 @@ class DummyFeature final : public nsIUrlClassifierFeature { return NS_OK; } + NS_IMETHODIMP + GetURIByListType(nsIChannel* aChannel, + nsIUrlClassifierFeature::listType aListType, + nsIURI** aURI) override { + return NS_ERROR_NOT_IMPLEMENTED; + } + private: ~DummyFeature() = default; @@ -2839,7 +2852,8 @@ nsUrlClassifierDBService::AsyncClassifyLocalWithFeatures( auto startTime = TimeStamp::Now(); // For telemetry. // Let's keep the features alive and release them on the correct thread. - RefPtr holder = FeatureHolder::Create(aFeatures, aListType); + RefPtr holder = + FeatureHolder::Create(aURI, aFeatures, aListType); if (NS_WARN_IF(!holder)) { return NS_ERROR_FAILURE; } @@ -2905,7 +2919,8 @@ bool nsUrlClassifierDBService::AsyncClassifyLocalWithFeaturesUsingPreferences( LOG(("URI found in preferences. Table: %s", tableName.get())); RefPtr result = - new mozilla::net::UrlClassifierFeatureResult(feature, tableName); + new mozilla::net::UrlClassifierFeatureResult(aURI, feature, + tableName); results.AppendElement(result); } } diff --git a/uriloader/exthandler/nsExternalProtocolHandler.cpp b/uriloader/exthandler/nsExternalProtocolHandler.cpp index 6918fb00e1e4..b1639472d3ee 100644 --- a/uriloader/exthandler/nsExternalProtocolHandler.cpp +++ b/uriloader/exthandler/nsExternalProtocolHandler.cpp @@ -416,6 +416,12 @@ NS_IMETHODIMP nsExtProtocolChannel::NotifyTrackingResource(bool aIsThirdParty) { return NS_OK; } +NS_IMETHODIMP nsExtProtocolChannel::NotifyFlashPluginStateChanged( + nsIHttpChannel::FlashPluginState aState) { + // nothing to do + return NS_OK; +} + NS_IMETHODIMP nsExtProtocolChannel::Delete() { // nothing to do return NS_OK;