gecko-dev/dom/base/nsContentPolicy.cpp
Andreas Farre 25ca8d7890 Bug 1620594 - Part 7: Remove TabGroup and SystemGroup. r=nika,bas
TabGroup never really made any difference in which thread something go
dispatched to. This was the intended use, but development of TabGroups
with abstract main threads never made it that far. The good thing is
that thish makes it safe to also remove to the SystemGroup and instead
switch all SystemGroup dispatches to dispatches to main thread.

Timers for setTimeout and workers were the sole users of wrapped and
throttled event targets, that those throttled queues have been moved
to the BrowsingContextGroup and are now accessed explicitly.

The SchedulerEventTarget has been removed, since there are no longer a
separate event target for every TaskCategory. Instead a
LabellingEventTarget has been added to DocGroup to handle the case
where an event is dispatched do DocGroup or when an AbstractThread is
created using a DocGroup. This means that we'll actually label more
events correctly with the DocGroup that they belong to.

DocGroups have also been moved to BrowsingContextGroup.

Depends on D67636

Differential Revision: https://phabricator.services.mozilla.com/D65936

--HG--
extra : moz-landing-system : lando
2020-04-07 15:17:47 +00:00

188 lines
7.0 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
// vim: ft=cpp tw=80 sw=2 et ts=8
/* 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/. */
/*
* Implementation of the "@mozilla.org/layout/content-policy;1" contract.
*/
#include "mozilla/Logging.h"
#include "nsISupports.h"
#include "nsXPCOM.h"
#include "nsContentPolicyUtils.h"
#include "mozilla/dom/nsCSPService.h"
#include "nsContentPolicy.h"
#include "nsIURI.h"
#include "nsIBrowserChild.h"
#include "nsIContent.h"
#include "nsIImageLoadingContent.h"
#include "nsCOMArray.h"
#include "nsContentUtils.h"
#include "mozilla/dom/nsMixedContentBlocker.h"
#include "nsIContentSecurityPolicy.h"
#include "mozilla/TaskCategory.h"
class nsIDOMWindow;
using mozilla::LogLevel;
NS_IMPL_ISUPPORTS(nsContentPolicy, nsIContentPolicy)
static mozilla::LazyLogModule gConPolLog("nsContentPolicy");
nsresult NS_NewContentPolicy(nsIContentPolicy** aResult) {
*aResult = new nsContentPolicy;
NS_ADDREF(*aResult);
return NS_OK;
}
nsContentPolicy::nsContentPolicy() : mPolicies(NS_CONTENTPOLICY_CATEGORY) {}
nsContentPolicy::~nsContentPolicy() = default;
#ifdef DEBUG
# define WARN_IF_URI_UNINITIALIZED(uri, name) \
PR_BEGIN_MACRO \
if ((uri)) { \
nsAutoCString spec; \
(uri)->GetAsciiSpec(spec); \
if (spec.IsEmpty()) { \
NS_WARNING(name " is uninitialized, fix caller"); \
} \
} \
PR_END_MACRO
#else // ! defined(DEBUG)
# define WARN_IF_URI_UNINITIALIZED(uri, name)
#endif // defined(DEBUG)
inline nsresult nsContentPolicy::CheckPolicy(CPMethod policyMethod,
nsIURI* contentLocation,
nsILoadInfo* loadInfo,
const nsACString& mimeType,
int16_t* decision) {
nsContentPolicyType contentType = loadInfo->InternalContentPolicyType();
nsCOMPtr<nsISupports> requestingContext = loadInfo->GetLoadingContext();
// sanity-check passed-through parameters
MOZ_ASSERT(decision, "Null out pointer");
WARN_IF_URI_UNINITIALIZED(contentLocation, "Request URI");
#ifdef DEBUG
{
nsCOMPtr<nsINode> node(do_QueryInterface(requestingContext));
nsCOMPtr<nsIDOMWindow> window(do_QueryInterface(requestingContext));
nsCOMPtr<nsIBrowserChild> browserChild(
do_QueryInterface(requestingContext));
NS_ASSERTION(!requestingContext || node || window || browserChild,
"Context should be a DOM node, DOM window or a browserChild!");
}
#endif
nsCOMPtr<mozilla::dom::Document> doc;
nsCOMPtr<nsIContent> node = do_QueryInterface(requestingContext);
if (node) {
doc = node->OwnerDoc();
}
if (!doc) {
doc = do_QueryInterface(requestingContext);
}
nsContentPolicyType externalType =
nsContentUtils::InternalContentPolicyTypeToExternal(contentType);
/*
* Enumerate mPolicies and ask each of them, taking the logical AND of
* their permissions.
*/
nsresult rv;
const nsCOMArray<nsIContentPolicy>& entries = mPolicies.GetCachedEntries();
nsCOMPtr<nsPIDOMWindowOuter> window;
if (nsCOMPtr<nsINode> node = do_QueryInterface(requestingContext)) {
window = node->OwnerDoc()->GetWindow();
} else {
window = do_QueryInterface(requestingContext);
}
if (doc) {
nsCOMPtr<nsIContentSecurityPolicy> csp = doc->GetCsp();
if (csp && window) {
csp->EnsureEventTarget(
window->EventTargetFor(mozilla::TaskCategory::Other));
}
}
int32_t count = entries.Count();
for (int32_t i = 0; i < count; i++) {
/* check the appropriate policy */
rv = (entries[i]->*policyMethod)(contentLocation, loadInfo, mimeType,
decision);
if (NS_SUCCEEDED(rv) && NS_CP_REJECTED(*decision)) {
// If we are blocking an image, we have to let the
// ImageLoadingContent know that we blocked the load.
if (externalType == nsIContentPolicy::TYPE_IMAGE ||
externalType == nsIContentPolicy::TYPE_IMAGESET) {
nsCOMPtr<nsIImageLoadingContent> img =
do_QueryInterface(requestingContext);
if (img) {
img->SetBlockedRequest(*decision);
}
}
/* policy says no, no point continuing to check */
return NS_OK;
}
}
// everyone returned failure, or no policies: sanitize result
*decision = nsIContentPolicy::ACCEPT;
return NS_OK;
}
// uses the parameters from ShouldXYZ to produce and log a message
// logType must be a literal string constant
#define LOG_CHECK(logType) \
PR_BEGIN_MACRO \
/* skip all this nonsense if the call failed or logging is disabled */ \
if (NS_SUCCEEDED(rv) && MOZ_LOG_TEST(gConPolLog, LogLevel::Debug)) { \
const char* resultName; \
if (decision) { \
resultName = NS_CP_ResponseName(*decision); \
} else { \
resultName = "(null ptr)"; \
} \
MOZ_LOG( \
gConPolLog, LogLevel::Debug, \
("Content Policy: " logType ": <%s> result=%s", \
contentLocation ? contentLocation->GetSpecOrDefault().get() : "None", \
resultName)); \
} \
PR_END_MACRO
NS_IMETHODIMP
nsContentPolicy::ShouldLoad(nsIURI* contentLocation, nsILoadInfo* loadInfo,
const nsACString& mimeType, int16_t* decision) {
// ShouldProcess does not need a content location, but we do
MOZ_ASSERT(contentLocation, "Must provide request location");
nsresult rv = CheckPolicy(&nsIContentPolicy::ShouldLoad, contentLocation,
loadInfo, mimeType, decision);
LOG_CHECK("ShouldLoad");
return rv;
}
NS_IMETHODIMP
nsContentPolicy::ShouldProcess(nsIURI* contentLocation, nsILoadInfo* loadInfo,
const nsACString& mimeType, int16_t* decision) {
nsresult rv = CheckPolicy(&nsIContentPolicy::ShouldProcess, contentLocation,
loadInfo, mimeType, decision);
LOG_CHECK("ShouldProcess");
return rv;
}