--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -264,16 +264,17 @@
#include "nsISpeculativeConnect.h"
#include "mozilla/MediaManager.h"
#ifdef MOZ_WEBRTC
#include "IPeerConnection.h"
#endif // MOZ_WEBRTC
#include "nsIURIClassifier.h"
+#include "mozilla/ClearOnShutdown.h"
using namespace mozilla;
using namespace mozilla::dom;
typedef nsTArray<Link*> LinkArray;
static LazyLogModule gDocumentLeakPRLog("DocumentLeak");
static LazyLogModule gCspPRLog("CSP");
@@ -304,16 +305,75 @@ GetHttpChannelHelper(nsIChannel* aChanne
}
httpChannel = do_QueryInterface(baseChannel);
httpChannel.forget(aHttpChannel);
return NS_OK;
}
+////////////////////////////////////////////////////////////////////
+// PrincipalFlashClassifier
+
+// Classify the flash based on the document principal.
+// The usage of this class is as follows:
+//
+// 1) Call AsyncClassify() as early as possible to asynchronously do
+// classification against all the flash blocking related tables
+// via nsIURIClassifier.asyncClassifyLocalWithTables.
+//
+// 2) At any time you need the classification result, call Result()
+// and it is guaranteed to give you the result. Note that you have
+// to specify "aIsThirdParty" to the function so please make sure
+// you can already corretly decide if the document is third-party.
+//
+// Behind the scenes, the sync classification API
+// (nsIURIClassifier.classifyLocalWithTable) may be called as a fallback to
+// synchronously get the result if the asyncClassifyLocalWithTables hasn't
+// been done yet.
+//
+// 3) You can call Result() as many times as you want and only the first time
+// may it unfortunately call the blocking sync API. The subsequent call
+// will just return the result we came out in the first time.
+//
+class PrincipalFlashClassifier final : public nsIURIClassifierCallback
+{
+public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSIURICLASSIFIERCALLBACK
+
+ explicit PrincipalFlashClassifier();
+
+ // Fire async classification based on the given principal.
+ void AsyncClassify(nsIPrincipal* aPrincipal);
+
+ // Would block if the result hasn't come out.
+ mozilla::dom::FlashClassification Result(nsIPrincipal* aPrincipal,
+ bool aIsThirdParty);
+
+private:
+ ~PrincipalFlashClassifier() = default;
+
+ void Reset();
+ bool EnsureUriClassifier();
+ mozilla::dom::FlashClassification CheckIfClassifyNeeded(nsIPrincipal* aPrincipal);
+ mozilla::dom::FlashClassification Resolve(bool aIsThirdParty);
+ mozilla::dom::FlashClassification AsyncClassifyInternal(nsIPrincipal* aPrincipal);
+ nsCString GetClassificationTables(bool aIsThirdParty);
+
+ // For the fallback sync classification.
+ nsCOMPtr<nsIURI> mClassificationURI;
+
+ nsCOMPtr<nsIURIClassifier> mUriClassifier;
+ bool mAsyncClassified;
+ nsTArray<nsCString> mMatchedTables;
+ mozilla::dom::FlashClassification mResult;
+};
+
+
#define NAME_NOT_VALID ((nsSimpleContentList*)1)
nsIdentifierMapEntry::~nsIdentifierMapEntry()
{
}
void
nsIdentifierMapEntry::Traverse(nsCycleCollectionTraversalCallback* aCallback)
@@ -1431,16 +1491,20 @@ nsDocument::nsDocument(const char* aCont
MOZ_LOG(gDocumentLeakPRLog, LogLevel::Debug, ("DOCUMENT %p created", this));
// Start out mLastStyleSheetSet as null, per spec
SetDOMStringToNull(mLastStyleSheetSet);
// void state used to differentiate an empty source from an unselected source
mPreloadPictureFoundSource.SetIsVoid(true);
+
+ // For determining if this is a flash document which should be
+ // blocked based on its principal.
+ mPrincipalFlashClassifier = new PrincipalFlashClassifier();
}
void
nsDocument::ClearAllBoxObjects()
{
if (mBoxObjectTable) {
for (auto iter = mBoxObjectTable->Iter(); !iter.Done(); iter.Next()) {
nsPIBoxObject* boxObject = iter.UserData();
@@ -2579,16 +2643,21 @@ nsDocument::StartDocumentLoad(const char
}
// If this is not a data document, set CSP.
if (!mLoadedAsData) {
nsresult rv = InitCSP(aChannel);
NS_ENSURE_SUCCESS(rv, rv);
}
+ // Perform a async flash classification based on the doc principal
+ // in an early stage to reduce the blocking time.
+ mFlashClassification = FlashClassification::Unclassified;
+ mPrincipalFlashClassifier->AsyncClassify(GetPrincipal());
+
return NS_OK;
}
void
nsDocument::SendToConsole(nsCOMArray<nsISecurityConsoleMessage>& aMessages)
{
for (uint32_t i = 0; i < aMessages.Length(); ++i) {
nsAutoString messageTag;
@@ -13179,16 +13248,31 @@ nsIDocument::UpdateStyleBackendType()
NS_WARNING("stylo: No docshell yet, assuming Gecko style system");
} else if (nsLayoutUtils::SupportsServoStyleBackend(this)) {
mStyleBackendType = StyleBackendType::Servo;
}
#endif
}
/**
+ * Retrieves the classification of the Flash plugins in the document based on
+ * the classification lists. We perform AsyncInitFlashClassification on
+ * StartDocumentLoad() and the result may not be initialized when this function
+ * gets called. In that case, We can only unfortunately have a blocking wait.
+ *
+ * For more information, see
+ * toolkit/components/url-classifier/flash-block-lists.rst
+ */
+FlashClassification
+nsDocument::PrincipalFlashClassification()
+{
+ return mPrincipalFlashClassifier->Result(GetPrincipal(), IsThirdParty());
+}
+
+/**
* Helper function for |nsDocument::PrincipalFlashClassification|
*
* Adds a table name string to a table list (a comma separated string). The
* table will not be added if the name is an empty string.
*/
static void
MaybeAddTableToTableList(const nsACString& aTableNames,
nsACString& aTableList)
@@ -13218,134 +13302,356 @@ ArrayContainsTable(const nsTArray<nsCStr
// cannot contain another existing table name.
if (FindInReadable(table, aTableNames)) {
return true;
}
}
return false;
}
-/**
- * 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
- */
+namespace {
+
+// An object to store all preferences we need for flash blocking feature.
+struct PrefStore
+{
+ PrefStore()
+ {
+ Preferences::AddBoolVarCache(&mFlashBlockEnabled,
+ "plugins.flashBlock.enabled");
+ Preferences::AddBoolVarCache(&mPluginsHttpOnly,
+ "plugins.http_https_only");
+
+ // We only need to register string-typed preferences.
+ Preferences::RegisterCallback(UpdateStringPrefs, "urlclassifier.flashAllowTable", this);
+ Preferences::RegisterCallback(UpdateStringPrefs, "urlclassifier.flashAllowExceptTable", this);
+ Preferences::RegisterCallback(UpdateStringPrefs, "urlclassifier.flashTable", this);
+ Preferences::RegisterCallback(UpdateStringPrefs, "urlclassifier.flashExceptTable", this);
+ Preferences::RegisterCallback(UpdateStringPrefs, "urlclassifier.flashSubDocTable", this);
+ Preferences::RegisterCallback(UpdateStringPrefs, "urlclassifier.flashSubDocExceptTable", this);
+
+ UpdateStringPrefs();
+ }
+
+ ~PrefStore()
+ {
+ Preferences::UnregisterCallback(UpdateStringPrefs, "urlclassifier.flashAllowTable", this);
+ Preferences::UnregisterCallback(UpdateStringPrefs, "urlclassifier.flashAllowExceptTable", this);
+ Preferences::UnregisterCallback(UpdateStringPrefs, "urlclassifier.flashTable", this);
+ Preferences::UnregisterCallback(UpdateStringPrefs, "urlclassifier.flashExceptTable", this);
+ Preferences::UnregisterCallback(UpdateStringPrefs, "urlclassifier.flashSubDocTable", this);
+ Preferences::UnregisterCallback(UpdateStringPrefs, "urlclassifier.flashSubDocExceptTable", this);
+ }
+
+ void UpdateStringPrefs()
+ {
+ Preferences::GetCString("urlclassifier.flashAllowTable", &mAllowTables);
+ Preferences::GetCString("urlclassifier.flashAllowExceptTable", &mAllowExceptionsTables);
+ Preferences::GetCString("urlclassifier.flashTable", &mDenyTables);
+ Preferences::GetCString("urlclassifier.flashExceptTable", &mDenyExceptionsTables);
+ Preferences::GetCString("urlclassifier.flashSubDocTable", &mSubDocDenyTables);
+ Preferences::GetCString("urlclassifier.flashSubDocExceptTable", &mSubDocDenyExceptionsTables);
+ }
+
+ static void UpdateStringPrefs(const char*, void* aClosure)
+ {
+ static_cast<PrefStore*>(aClosure)->UpdateStringPrefs();
+ }
+
+ bool mFlashBlockEnabled;
+ bool mPluginsHttpOnly;
+
+ nsCString mAllowTables;
+ nsCString mAllowExceptionsTables;
+ nsCString mDenyTables;
+ nsCString mDenyExceptionsTables;
+ nsCString mSubDocDenyTables;
+ nsCString mSubDocDenyExceptionsTables;
+};
+
+static const
+PrefStore& GetPrefStore()
+{
+ static UniquePtr<PrefStore> sPrefStore;
+ if (!sPrefStore) {
+ sPrefStore.reset(new PrefStore());
+ ClearOnShutdown(&sPrefStore);
+ }
+ return *sPrefStore;
+}
+
+} // end of unnamed namespace.
+
+////////////////////////////////////////////////////////////////////
+// PrincipalFlashClassifier implementation.
+
+NS_IMPL_ISUPPORTS(PrincipalFlashClassifier, nsIURIClassifierCallback)
+
+PrincipalFlashClassifier::PrincipalFlashClassifier()
+{
+ Reset();
+}
+
+void
+PrincipalFlashClassifier::Reset()
+{
+ mAsyncClassified = false;
+ mMatchedTables.Clear();
+ mResult = FlashClassification::Unclassified;
+}
+
+nsCString
+PrincipalFlashClassifier::GetClassificationTables(bool aIsThirdParty)
+{
+ nsAutoCString tables;
+ auto& prefs = GetPrefStore();
+
+ MaybeAddTableToTableList(prefs.mAllowTables, tables);
+ MaybeAddTableToTableList(prefs.mAllowExceptionsTables, tables);
+ MaybeAddTableToTableList(prefs.mDenyTables, tables);
+ MaybeAddTableToTableList(prefs.mDenyExceptionsTables, tables);
+
+ if (aIsThirdParty) {
+ MaybeAddTableToTableList(prefs.mSubDocDenyTables, tables);
+ MaybeAddTableToTableList(prefs.mSubDocDenyExceptionsTables, tables);
+ }
+
+ return tables;
+}
+
+bool
+PrincipalFlashClassifier::EnsureUriClassifier()
+{
+ if (mUriClassifier) {
+ return true;
+ }
+ mUriClassifier = do_GetService(NS_URICLASSIFIERSERVICE_CONTRACTID);
+ return !!mUriClassifier;
+}
+
FlashClassification
-nsDocument::PrincipalFlashClassification()
+PrincipalFlashClassifier::Result(nsIPrincipal* aPrincipal, bool aIsThirdParty)
+{
+ if (FlashClassification::Unclassified != mResult) {
+ // We already have the result. Just return it.
+ return mResult;
+ }
+
+ // TODO: Bug 1342333 - Entirely remove the use of the sync API
+ // (ClassifyLocalWithTables).
+ if (!mAsyncClassified) {
+
+ //
+ // We may
+ // 1) have called AsyncClassifyLocalWithTables but OnClassifyComplete
+ // hasn't been called.
+ // 2) haven't even called AsyncClassifyLocalWithTables.
+ //
+ // In both cases we need to do the synchronous classification as the fallback.
+ //
+
+ if (!EnsureUriClassifier()) {
+ return FlashClassification::Denied;
+ }
+ mResult = CheckIfClassifyNeeded(aPrincipal);
+ if (FlashClassification::Unclassified != mResult) {
+ return mResult;
+ }
+
+ nsCString classificationTables = GetClassificationTables(aIsThirdParty);
+ nsresult rv = mUriClassifier->ClassifyLocalWithTables(mClassificationURI,
+ classificationTables,
+ mMatchedTables);
+ if (NS_FAILED(rv)) {
+ if (rv == NS_ERROR_MALFORMED_URI) {
+ // This means that the URI had no hostname (ex: file://doc.html). In this
+ // case, we allow the default (Unknown plugin) behavior.
+ mResult = FlashClassification::Unknown;
+ } else {
+ mResult = FlashClassification::Denied;
+ }
+ return mResult;
+ }
+ }
+
+ // Resolve the result based on mMatchedTables and aIsThirdParty.
+ mResult = Resolve(aIsThirdParty);
+ MOZ_ASSERT(FlashClassification::Unclassified != mResult);
+
+ // The subsequent call of Result() will return the resolved result
+ // and never reach here until Reset() is called.
+ return mResult;
+}
+
+/*virtual*/ nsresult
+PrincipalFlashClassifier::OnClassifyComplete(nsresult /*aErrorCode*/,
+ const nsACString& aLists, // Only this matters.
+ const nsACString& /*aProvider*/,
+ const nsACString& /*aPrefix*/)
+{
+ mAsyncClassified = true;
+
+ if (FlashClassification::Unclassified != mResult) {
+ // Result() has been called prior to this callback.
+ return NS_OK;
+ }
+
+ // TODO: Bug 1364804 - We should use a callback type which notifies
+ // the result as a string array rather than a formatted string.
+
+ // We only populate the matched list without resolving the classification
+ // result because we are not sure if the parent doc has been properly set.
+ // We also parse the comma-separated tables to array. (the code is copied
+ // from Classifier::SplitTables.)
+ nsACString::const_iterator begin, iter, end;
+ aLists.BeginReading(begin);
+ aLists.EndReading(end);
+ while (begin != end) {
+ iter = begin;
+ FindCharInReadable(',', iter, end);
+ nsDependentCSubstring table = Substring(begin,iter);
+ if (!table.IsEmpty()) {
+ mMatchedTables.AppendElement(Substring(begin, iter));
+ }
+ begin = iter;
+ if (begin != end) {
+ begin++;
+ }
+ }
+
+ return NS_OK;
+}
+
+// We resolve the classification result based on aIsThirdParty
+// and the matched tables we got ealier on (via either sync or async API).
+FlashClassification
+PrincipalFlashClassifier::Resolve(bool aIsThirdParty)
+{
+ MOZ_ASSERT(FlashClassification::Unclassified == mResult,
+ "We already have resolved classification result.");
+
+ if (mMatchedTables.IsEmpty()) {
+ return FlashClassification::Unknown;
+ }
+
+ auto& prefs = GetPrefStore();
+ if (ArrayContainsTable(mMatchedTables, prefs.mDenyTables) &&
+ !ArrayContainsTable(mMatchedTables, prefs.mDenyExceptionsTables)) {
+ return FlashClassification::Denied;
+ } else if (ArrayContainsTable(mMatchedTables, prefs.mAllowTables) &&
+ !ArrayContainsTable(mMatchedTables, prefs.mAllowExceptionsTables)) {
+ return FlashClassification::Allowed;
+ }
+
+ if (aIsThirdParty && ArrayContainsTable(mMatchedTables, prefs.mSubDocDenyTables) &&
+ !ArrayContainsTable(mMatchedTables, prefs.mSubDocDenyExceptionsTables)) {
+ return FlashClassification::Denied;
+ }
+
+ return FlashClassification::Unknown;
+}
+
+void
+PrincipalFlashClassifier::AsyncClassify(nsIPrincipal* aPrincipal)
+{
+ MOZ_ASSERT(FlashClassification::Unclassified == mResult,
+ "The old classification result should be reset first.");
+ Reset();
+ mResult = AsyncClassifyInternal(aPrincipal);
+}
+
+FlashClassification
+PrincipalFlashClassifier::CheckIfClassifyNeeded(nsIPrincipal* aPrincipal)
{
nsresult rv;
-
- bool httpOnly = Preferences::GetBool("plugins.http_https_only", true);
- bool flashBlock = Preferences::GetBool("plugins.flashBlock.enabled", false);
+ auto& prefs = GetPrefStore();
// If neither pref is on, skip the null-principal and principal URI checks.
- if (!httpOnly && !flashBlock) {
+ if (prefs.mPluginsHttpOnly && !prefs.mFlashBlockEnabled) {
return FlashClassification::Unknown;
}
- nsCOMPtr<nsIPrincipal> principal = GetPrincipal();
+ nsCOMPtr<nsIPrincipal> principal = aPrincipal;
if (principal->GetIsNullPrincipal()) {
return FlashClassification::Denied;
}
nsCOMPtr<nsIURI> classificationURI;
rv = principal->GetURI(getter_AddRefs(classificationURI));
if (NS_FAILED(rv) || !classificationURI) {
return FlashClassification::Denied;
}
- if (httpOnly) {
+ if (prefs.mPluginsHttpOnly) {
// Only allow plugins for documents from an HTTP/HTTPS origin. This should
// allow dependent data: URIs to load plugins, but not:
// * chrome documents
// * "bare" data: loads
// * FTP/gopher/file
nsAutoCString scheme;
rv = classificationURI->GetScheme(scheme);
if (NS_WARN_IF(NS_FAILED(rv)) ||
!(scheme.EqualsLiteral("http") || scheme.EqualsLiteral("https"))) {
return FlashClassification::Denied;
}
}
// If flash blocking is disabled, it is equivalent to all sites being
// on neither list.
- if (!flashBlock) {
+ if (!prefs.mFlashBlockEnabled) {
return FlashClassification::Unknown;
}
- nsAutoCString allowTables, allowExceptionsTables,
- denyTables, denyExceptionsTables,
- subDocDenyTables, subDocDenyExceptionsTables,
- tables;
- Preferences::GetCString("urlclassifier.flashAllowTable", &allowTables);
- MaybeAddTableToTableList(allowTables, tables);
- 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);
- }
-
+ return FlashClassification::Unclassified;
+}
+
+// Using nsIURIClassifier.asyncClassifyLocalWithTables to do classification
+// against the flash related tables based on the given principal.
+FlashClassification
+PrincipalFlashClassifier::AsyncClassifyInternal(nsIPrincipal* aPrincipal)
+{
+ auto result = CheckIfClassifyNeeded(aPrincipal);
+ if (FlashClassification::Unclassified != result) {
+ return result;
+ }
+
+ // We haven't been able to decide if it's a third party document
+ // since determining if a document is third-party may depend on its
+ // parent document. At the time we call AsyncClassifyInternal
+ // (i.e. StartDocumentLoad) the parent document may not have been
+ // set. As a result, we wait until Resolve() to be called to
+ // take "is third party" into account. At this point, we just assume
+ // it's third-party to include every list.
+ nsCString tables = GetClassificationTables(true);
if (tables.IsEmpty()) {
return FlashClassification::Unknown;
}
- nsCOMPtr<nsIURIClassifier> uriClassifier =
- do_GetService(NS_URICLASSIFIERSERVICE_CONTRACTID, &rv);
- if (NS_FAILED(rv)) {
+ if (!EnsureUriClassifier()) {
return FlashClassification::Denied;
}
- nsTArray<nsCString> results;
- rv = uriClassifier->ClassifyLocalWithTables(classificationURI,
- tables,
- results);
+ nsresult rv = aPrincipal->GetURI(getter_AddRefs(mClassificationURI));
+ if (NS_FAILED(rv) || !mClassificationURI) {
+ return FlashClassification::Denied;
+ }
+
+ rv = mUriClassifier->AsyncClassifyLocalWithTables(mClassificationURI,
+ tables,
+ this);
if (NS_FAILED(rv)) {
if (rv == NS_ERROR_MALFORMED_URI) {
// This means that the URI had no hostname (ex: file://doc.html). In this
// case, we allow the default (Unknown plugin) behavior.
return FlashClassification::Unknown;
} else {
return FlashClassification::Denied;
}
}
- if (results.IsEmpty()) {
- return FlashClassification::Unknown;
- }
-
- if (ArrayContainsTable(results, denyTables) &&
- !ArrayContainsTable(results, denyExceptionsTables)) {
- return FlashClassification::Denied;
- } else if (ArrayContainsTable(results, allowTables) &&
- !ArrayContainsTable(results, allowExceptionsTables)) {
- return FlashClassification::Allowed;
- }
-
- if (isThirdPartyDoc && ArrayContainsTable(results, subDocDenyTables) &&
- !ArrayContainsTable(results, subDocDenyExceptionsTables)) {
- return FlashClassification::Denied;
- }
-
- return FlashClassification::Unknown;
+ return FlashClassification::Unclassified;
}
FlashClassification
nsDocument::ComputeFlashClassification()
{
nsCOMPtr<nsIDocShellTreeItem> current = this->GetDocShell();
if (!current) {
return FlashClassification::Denied;
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -66,16 +66,17 @@
#include "mozilla/Attributes.h"
#include "nsIDOMXPathEvaluator.h"
#include "jsfriendapi.h"
#include "ImportManager.h"
#include "mozilla/LinkedList.h"
#include "CustomElementRegistry.h"
#include "mozilla/dom/Performance.h"
#include "mozilla/Maybe.h"
+#include "nsIURIClassifier.h"
#define XML_DECLARATION_BITS_DECLARATION_EXISTS (1 << 0)
#define XML_DECLARATION_BITS_ENCODING_EXISTS (1 << 1)
#define XML_DECLARATION_BITS_STANDALONE_EXISTS (1 << 2)
#define XML_DECLARATION_BITS_STANDALONE_YES (1 << 3)
class nsDOMStyleSheetSetList;
@@ -550,16 +551,19 @@ protected:
nsILoadGroup* aLoadGroup,
nsIDocument* aDisplayDocument);
nsClassHashtable<nsURIHashKey, ExternalResource> mMap;
nsRefPtrHashtable<nsURIHashKey, PendingLoad> mPendingLoads;
bool mHaveShutDown;
};
+// For classifying a flash document based on its principal.
+class PrincipalFlashClassifier;
+
// Base class for our document implementations.
class nsDocument : public nsIDocument,
public nsIDOMDocument,
public nsIDOMDocumentXBL,
public nsSupportsWeakReference,
public nsIScriptObjectPrincipal,
public nsIRadioGroupContainer,
public nsIApplicationCacheContainer,
@@ -1450,16 +1454,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;
+ RefPtr<PrincipalFlashClassifier> mPrincipalFlashClassifier;
mozilla::dom::FlashClassification mFlashClassification;
// Do not use this value directly. Call the |IsThirdParty()| method, which
// caches its result here.
mozilla::Maybe<bool> mIsThirdParty;
private:
void UpdatePossiblyStaleDocumentState();
static bool CustomElementConstructor(JSContext* aCx, unsigned aArgc, JS::Value* aVp);
--- a/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp
+++ b/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp
@@ -1645,22 +1645,16 @@ nsUrlClassifierDBService::Init()
}
sGethashNoise = Preferences::GetUint(GETHASH_NOISE_PREF,
GETHASH_NOISE_DEFAULT);
ReadTablesFromPrefs();
nsresult rv;
{
- // Force PSM loading on main thread
- nsCOMPtr<nsICryptoHash> dummy = do_CreateInstance(NS_CRYPTO_HASH_CONTRACTID, &rv);
- NS_ENSURE_SUCCESS(rv, rv);
- }
-
- {
// Force nsIUrlClassifierUtils loading on main thread.
nsCOMPtr<nsIUrlClassifierUtils> dummy =
do_GetService(NS_URLCLASSIFIERUTILS_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
}
// Directory providers must also be accessed on the main thread.
nsCOMPtr<nsIFile> cacheDir;
@@ -1816,16 +1810,28 @@ nsUrlClassifierDBService::ClassifyLocal(
NS_IMETHODIMP
nsUrlClassifierDBService::AsyncClassifyLocalWithTables(nsIURI *aURI,
const nsACString& aTables,
nsIURIClassifierCallback* aCallback)
{
MOZ_ASSERT(NS_IsMainThread(), "AsyncClassifyLocalWithTables must be called "
"on main thread");
+ // We do this check no matter what process we are in to return
+ // error as early as possible.
+ nsCOMPtr<nsIURI> uri = NS_GetInnermostURI(aURI);
+ NS_ENSURE_TRUE(uri, NS_ERROR_FAILURE);
+
+ nsAutoCString key;
+ // Canonicalize the url
+ nsCOMPtr<nsIUrlClassifierUtils> utilsService =
+ do_GetService(NS_URLCLASSIFIERUTILS_CONTRACTID);
+ nsresult rv = utilsService->GetKeyForURI(uri, key);
+ NS_ENSURE_SUCCESS(rv, rv);
+
if (XRE_IsContentProcess()) {
using namespace mozilla::dom;
using namespace mozilla::ipc;
ContentChild* content = ContentChild::GetSingleton();
MOZ_ASSERT(content);
auto actor = new URLClassifierLocalChild();
@@ -1848,26 +1854,16 @@ nsUrlClassifierDBService::AsyncClassifyL
if (gShuttingDownThread) {
return NS_ERROR_ABORT;
}
using namespace mozilla::Telemetry;
auto startTime = TimeStamp::Now(); // For telemetry.
- nsCOMPtr<nsIURI> uri = NS_GetInnermostURI(aURI);
- NS_ENSURE_TRUE(uri, NS_ERROR_FAILURE);
-
- nsAutoCString key;
- // Canonicalize the url
- nsCOMPtr<nsIUrlClassifierUtils> utilsService =
- do_GetService(NS_URLCLASSIFIERUTILS_CONTRACTID);
- nsresult rv = utilsService->GetKeyForURI(uri, key);
- NS_ENSURE_SUCCESS(rv, rv);
-
auto worker = mWorker;
nsCString tables(aTables);
// Since aCallback will be passed around threads...
nsMainThreadPtrHandle<nsIURIClassifierCallback> callback(
new nsMainThreadPtrHolder<nsIURIClassifierCallback>(aCallback));
nsCOMPtr<nsIRunnable> r =